Java.perform(function () {
console.log('start...')
const libcrypto = Process.findModuleByName("libGMJNISSL.so");
const PKCS12_parse = Module.findExportByName("libGMJNISSL.so", "PKCS12_parse");
const BIO_s_mem = Module.findExportByName("libGMJNISSL.so", "BIO_s_mem");
const BIO_new = Module.findExportByName("libGMJNISSL.so", "BIO_new");
const BIO_free = Module.findExportByName("libGMJNISSL.so", "BIO_free");
const PEM_write_bio_PrivateKey = Module.findExportByName("libGMJNISSL.so", "PEM_write_bio_PrivateKey");
const PEM_write_bio_X509 = Module.findExportByName("libGMJNISSL.so", "PEM_write_bio_X509");
const BIO_ctrl_pending = Module.findExportByName("libGMJNISSL.so", "BIO_ctrl_pending");
const BIO_read = Module.findExportByName("libGMJNISSL.so", "BIO_read");
const sk_X509_num = Module.findExportByName("libGMJNISSL.so", "OPENSSL_sk_num");
const sk_X509_value = Module.findExportByName("libGMJNISSL.so", "OPENSSL_sk_value");
const sk_X509_free = Module.findExportByName("libGMJNISSL.so", "OPENSSL_sk_free");
const bio_s_mem = new NativeFunction(BIO_s_mem, "pointer", []);
const bio_new = new NativeFunction(BIO_new, "pointer", ["pointer"]);
const bio_free = new NativeFunction(BIO_free, "int", ["pointer"]);
const pem_write_pkey = new NativeFunction(
PEM_write_bio_PrivateKey,
"int",
["pointer", "pointer", "pointer", "pointer", "int", "pointer", "pointer"]
);
const pem_write_x509 = new NativeFunction(
PEM_write_bio_X509,
"int",
["pointer", "pointer"]
);
const bio_ctrl_pending = new NativeFunction(
BIO_ctrl_pending,
"int",
["pointer"]
);
const bio_read = new NativeFunction(
BIO_read,
"int",
["pointer", "pointer", "int"]
);
const stack_num = new NativeFunction(
sk_X509_num,
"int",
["pointer"]
);
const stack_value = new NativeFunction(
sk_X509_value,
"pointer",
["pointer", "int"]
);
const stack_free = new NativeFunction(
sk_X509_free,
"void",
["pointer"]
);
function exportX509ToPEM(certPtr) {
const mem_bio_method = bio_s_mem();
const bio = bio_new(mem_bio_method);
pem_write_x509(bio, certPtr);
const certSize = bio_ctrl_pending(bio);
const certBuffer = Memory.alloc(certSize + 1);
bio_read(bio, certBuffer, certSize);
const pemCert = certBuffer.readCString();
bio_free(bio);
return pemCert;
}
Interceptor.attach(Module.findExportByName("libGMJNISSL.so", "ssl_verify_cert_chain"), {
onEnter: function (args) {
console.log('ssl_verify_cert_chain...')
this.sk = args[1];
},
onLeave: function (retval) {
var caPtr = ptr(this.sk)
if (!caPtr.isNull()) {
const caStackPtr = caPtr
const numCAs = stack_num(caStackPtr);
console.log(`找到 ${numCAs} 个CA证书`);
let caChainPEMs = [];
for (let i = 0; i < numCAs; i++) {
const caCertPtr = stack_value(caStackPtr, i);
const pemCA = exportX509ToPEM(caCertPtr);
caChainPEMs.push(pemCA);
}
caChainPEMs.forEach((pem, index) => {
console.log(pem);
});
}
}
});
console.log("[+] ssl_verify_cert_chain hook 已安装");
});