''' author: ceres-c usage: ./frida-extract-keystore.py Once the keystore(s) have been exported you have to convert them to PKCS12 using keytool '''
import frida, sys, time
app_name = 'com.example.httpstest' i = 0 ext = ''
defon_message(message, data): global i, ext if (message['type'] == 'send'and'event'in message['payload']): if (message['payload']['event'] == '+found'): i += 1 print("\n[+] Hooked keystore" + str(i) + "...")
jscode = """ setTimeout(function() { Java.perform(function () { var keyStoreLoadStream = Java.use('java.security.KeyStore')['load'].overload('java.io.InputStream', '[C'); /* following function hooks to a Keystore.load(InputStream stream, char[] password) */ keyStoreLoadStream.implementation = function(stream, charArray) { /* sometimes this happen, I have no idea why, tho... */ if (stream == null) { /* just to avoid interfering with app's flow */ this.load(stream, charArray); return; } /* just to notice the client we've hooked a KeyStore.load */ send({event: '+found'}); /* read the buffer stream to a variable */ var hexString = readStreamToHex (stream); /* send KeyStore type to client shell */ send({event: '+type', certType: this.getType()}); /* send KeyStore password to client shell */ send({event: '+pass', password: charArray}); /* send the string representation to client shell */ send({event: '+write', cert: hexString}); /* call the original implementation of 'load' */ this.load(stream, charArray); /* no need to return anything */ } }); },0); /* following function reads an InputStream and returns an ASCII char representation of it */ function readStreamToHex (stream) { var data = []; var byteRead = stream.read(); while (byteRead != -1) { data.push( ('0' + (byteRead & 0xFF).toString(16)).slice(-2) ); /* <---------------- binary to hex ---------------> */ byteRead = stream.read(); } stream.close(); return data.join(''); } """
print("[.] Attaching to device...") try: device = frida.get_remote_device() except: print("[-] Can't attach. Is the device connected?") sys.exit()
print("[.] Spawning the app...") try: pid = device.spawn(app_name) device.resume(pid) time.sleep(1) except: print("[-] Can't spawn the App. Is filename correct?") sys.exit()
print("[.] Attaching to process...") try: process = device.attach(pid) except: print("[-] Can't connect to App.") sys.exit()
print("[.] Launching js code...") print(" (run the app until needed, close it and then kill this script)") script = process.create_script(jscode) script.on('message', on_message) script.load() try: sys.stdin.read() except KeyboardInterrupt: print ("\nExiting now") exit(0)