-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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