Skip to content

Instantly share code, notes, and snippets.

@vadimszzz
Created May 17, 2022 06:42
Show Gist options
  • Save vadimszzz/741c539588bbce5b1fa6eeb2e4dc0220 to your computer and use it in GitHub Desktop.
Save vadimszzz/741c539588bbce5b1fa6eeb2e4dc0220 to your computer and use it in GitHub Desktop.
/**
* Sleep
*/
async function sleep(seconds = 0) {
await new Promise(r => setTimeout(r, seconds * 1000))
}
/**
* Logging function, reads null terminated string from address in line.
*/
function keyLogger(ssl, line) {
const keylog = new NativePointer(line).readCString()
console.log(keylog)
}
const keyLogCallback = new NativeCallback(keyLogger, 'void', ['pointer', 'pointer'])
/**
* Start logging libboringssl.dylib TLS keys. Should be called before resuming the binary.
*/
function startSystemTLSKeyLogger() {
const moduleName = "libboringssl.dylib"
// iOS version
const deviceSystemVersion = ObjC.classes.UIDevice.currentDevice().systemVersion()
const deviceSystemVersionMajor = deviceSystemVersion.floatValue() ^ 0
// Offset of keylog_callback pointer in SSL struct
// Derived from dissassembly of ssl_log_secret in ssl_lib.c (libboringssl.dylib) on iOS
const CALLBACK_OFFSET = {
12: 0x2A8,
13: 0x2C0,
14: 0x2B8,
}[deviceSystemVersionMajor]
if (!CALLBACK_OFFSET) {
throw new Error(`iOS ${deviceSystemVersion} isn't supported yet.`)
}
// Intercept
const SSL_CTX_set_info_callback = Module.findExportByName(moduleName, "SSL_CTX_set_info_callback");
Interceptor.attach(SSL_CTX_set_info_callback, {
onEnter: function (args) {
const ssl = new NativePointer(args[0])
const callback = new NativePointer(ssl).add(CALLBACK_OFFSET)
callback.writePointer(keyLogCallback)
}
})
send(`Module ${moduleName} SSL logging started.`)
}
/**
* Start logging TLS keys. Should be called before resuming the binary.
*/
function startTLSKeyLogger(moduleName) {
if (moduleName === "libboringssl.dylib") {
return startSystemTLSKeyLogger()
}
const SSL_CTX_new = Module.findExportByName(moduleName, "SSL_CTX_new")
const SSL_CTX_set_keylog_callback = Module.findExportByName(moduleName, "SSL_CTX_set_keylog_callback")
if (!SSL_CTX_set_keylog_callback) {
return
}
Interceptor.attach(SSL_CTX_new, {
onLeave: function(retval) {
const ssl = new NativePointer(retval)
if (!ssl.isNull()) {
const SSL_CTX_set_keylog_callbackFn = new NativeFunction(SSL_CTX_set_keylog_callback, 'void', ['pointer', 'pointer'])
SSL_CTX_set_keylog_callbackFn(ssl, keyLogCallback)
}
}
})
send(`Module ${moduleName} SSL logging started.`)
}
(async function() {
// Wait for environment (uncomment for iOS)
// while (true) {
// try {
// Module.ensureInitialized("libboringssl.dylib")
// break
// } catch {
// await sleep(0)
// }
// }
send("Loaded!")
// startTLSKeyLogger("libboringssl.dylib")
const modules = Process.enumerateModules()
for (const module of modules) {
if (module.name === "libboringssl.dylib") {
continue
}
startTLSKeyLogger(module.name)
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment