Skip to content

Instantly share code, notes, and snippets.

@andydavies
Created March 28, 2018 17:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save andydavies/451c038c2f45cf3397cd17d9273b500e to your computer and use it in GitHub Desktop.
Save andydavies/451c038c2f45cf3397cd17d9273b500e to your computer and use it in GitHub Desktop.
Dumps TLS keys from jailbroken iOS 10.x device - requires Frida, doesn't support session resumption
#!/usr/bin/python
#/usr/local/bin/python
import frida
import sys
def on_message(message, data):
try:
if message:
f = open("tlskeys.log", 'a')
print("{0}".format(message["payload" ]))
f.write(message["payload"] + "\n" )
except Exception as e:
print(message)
print(e)
# tls_handshake_internal_prf signature from
# https://opensource.apple.com/source/coreTLS/coreTLS-83.20.8/lib/tls1Callouts.c.auto.html
#
# tls_handshake_t ctx,
# const void *vsecret,
# size_t secretLen,
# const void *label, // optional, NULL implies that seed contains
# // the label
# size_t labelLen,
# const void *seed,
# size_t seedLen,
# void *vout, // mallocd by caller, length >= outLen
# size_t outLen
hook = """
var hexChar = ["0", "1", "2", "3", "4", "5", "6", "7","8", "9", "A", "B", "C", "D", "E", "F"];
function byteToHex(byte) {
return hexChar[(byte >> 4) & 0x0f] + hexChar[byte & 0x0f];
}
var tls_handshake_internal_prf = Module.findExportByName("libsystem_coretls.dylib", "tls_handshake_internal_prf");
Interceptor.attach(tls_handshake_internal_prf, {onEnter: function (args) {
var secretLength = parseInt(args[2], 16);
var seedLength = parseInt(args[6], 16);
if(secretLength == 48 && (seedLength == 64 || seedLength == 77)) {
var secretAddr = new NativePointer(args[1])
var secretBytes = new Uint8Array(Memory.readByteArray(secretAddr, secretLength));
var secret = "";
for(var i = 0; i < secretLength; i++) {
secret += byteToHex(secretBytes[i]);
}
var seedLength = parseInt(args[6], 16);
var seedAddr = new NativePointer(args[5]);
var seedBytes = new Uint8Array(Memory.readByteArray(seedAddr, seedLength));
var clientRandom = "";
var serverRandom = "";
if(seedLength == 64) {
for(i = 0; i < 32; i++) {
clientRandom += byteToHex(seedBytes[i]);
}
for( ; i < 64; i++) {
serverRandom += byteToHex(seedBytes[i]);
}
}
else if(seedLength == 77) { // key expansion
var offset = 13;
for(i = offset; i < 32 + offset; i++) {
serverRandom += byteToHex(seedBytes[i]);
}
for( ; i < 64 + offset; i++) {
clientRandom += byteToHex(seedBytes[i]);
}
}
if(clientRandom !== "") {
send("CLIENT_RANDOM "+ clientRandom + " " + secret);
}
}
}
});
"""
if __name__ == '__main__':
try:
print("[*] Attaching ..." )
print("[*] Hooking... \n " )
if sys.argv[1] == "-n":
session = frida.get_usb_device().spawn(["re.frida.Gadget" ])
else:
session = frida.get_usb_device().spawn([sys.argv[1]])
session1 = frida.get_usb_device().attach(session)
frida.get_usb_device().resume(session)
script = session1.create_script(hook)
script.on('message' , on_message)
script.load()
sys.stdin.read()
except KeyboardInterrupt:
sys.exit(0)
except IndexError:
print("""
Error: No process specified. Usage: dumper.py [BundleIdentifier]
E.g. dumper.py com.apple.mobilesafari
If device is jailbroken please use -n option
""")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment