Skip to content

Instantly share code, notes, and snippets.

@JJTech0130
Created May 9, 2026 06:17
Show Gist options
  • Select an option

  • Save JJTech0130/e238798e66fe70abc16f1c6dc6c28ab3 to your computer and use it in GitHub Desktop.

Select an option

Save JJTech0130/e238798e66fe70abc16f1c6dc6c28ab3 to your computer and use it in GitHub Desktop.
SSL keylogging for libssl.35.dylib for MobileDevice.framework
// This script implements SSL keylogging for libssl.35.dylib, which is an old version of LibreSSL.
// Primarily intended to be used when debugging MobileDevice.framework, which uses it for some reason.
var mod = Process.getModuleByName("libssl.35.dylib");
var gen_master = mod.findExportByName("tls1_generate_master_secret");
var keylogPath = '/tmp/keylog.txt';
var keylog = new File(keylogPath, "a");
var toHex = function(arr) {
return Array.from(new Uint8Array(arr))
.map(b => b.toString(16).padStart(2, '0')).join('');
};
Interceptor.attach(gen_master, {
onEnter(args) {
this.ssl = args[0];
this.master_key_buf = args[1];
},
onLeave(r) {
try {
var master_key_len = r.toInt32();
if (master_key_len <= 0) return;
var master_key = this.master_key_buf.readByteArray(master_key_len);
/*
From LibreSSL 2.2.9:
struct ssl_st {
int version; // 0x00 4 bytes
int type; // 0x04 4 bytes
const SSL_METHOD *method; // 0x08 8 bytes
BIO *rbio; // 0x10 8 bytes
BIO *wbio; // 0x18 8 bytes
BIO *bbio; // 0x20 8 bytes
int rwstate; // 0x28 4 bytes
int in_handshake; // 0x2c 4 bytes
int (*handshake_func)(SSL *); // 0x30 8 bytes
int server; // 0x38 4 bytes
int new_session; // 0x3c 4 bytes
int quiet_shutdown; // 0x40 4 bytes
int shutdown; // 0x44 4 bytes
int state; // 0x48 4 bytes
int rstate; // 0x4c 4 bytes
BUF_MEM *init_buf; // 0x50 8 bytes
void *init_msg; // 0x58 8 bytes
int init_num; // 0x60 4 bytes
int init_off; // 0x64 4 bytes
unsigned char *packet; // 0x68 8 bytes
unsigned int packet_length; // 0x70 4 bytes
// 4 bytes padding
struct ssl3_state_st *s3; // 0x78 8 bytes <---
};
typedef struct ssl3_state_st {
long flags; // 0x00 8 bytes
int delay_buf_pop_ret; // 0x08 4 bytes
unsigned char read_sequence[8]; // 0x0c 8 bytes
int read_mac_secret_size; // 0x14 4 bytes
unsigned char read_mac_secret[64]; // 0x18 64 bytes
unsigned char write_sequence[8]; // 0x58 8 bytes
int write_mac_secret_size; // 0x60 4 bytes
unsigned char write_mac_secret[64]; // 0x64 64 bytes
unsigned char server_random[32]; // 0xa4 32 bytes
unsigned char client_random[32]; // 0xc4 32 bytes <---
};
*/
var s3 = this.ssl.add(0x78).readPointer();
var client_random = s3.add(0xC4).readByteArray(32);
var line = "CLIENT_RANDOM " + toHex(client_random) + " " + toHex(master_key) + "\n";
keylog.write(line);
keylog.flush();
console.log(line.trim());
} catch(e) {
console.log("Error: " + e);
}
}
});
console.log("TLS keylog active, writing to: " + keylogPath);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment