mirror of
https://github.com/httptoolkit/frida-interception-and-unpinning.git
synced 2026-10-05 07:22:19 +02:00
Add a script to directly inject one always-trusted cert into Conscrypt
This is a notably different approach to the past certificate unpinning setup. Through this new mechanism, we trust just one additional certificate (instead of disabling cert verification entirely) and handle just the standard Android certificate trust (we'll integrate unpinning into this later). This uses a hardcoded cert for now just for testing, but that will of course be configurable in future.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
const CERT_PEM = `-----BEGIN CERTIFICATE-----
|
||||
MIIDTzCCAjegAwIBAgIRClDpdJeylUmDvNyq5qq+plcwDQYJKoZIhvcNAQELBQAw
|
||||
QTEYMBYGA1UEAxMPSFRUUCBUb29sa2l0IENBMQswCQYDVQQGEwJYWDEYMBYGA1UE
|
||||
ChMPSFRUUCBUb29sa2l0IENBMB4XDTIyMTIyNTE5MDQ1MFoXDTIzMTIyNjE5MDQ1
|
||||
MFowQTEYMBYGA1UEAxMPSFRUUCBUb29sa2l0IENBMQswCQYDVQQGEwJYWDEYMBYG
|
||||
A1UEChMPSFRUUCBUb29sa2l0IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAz4pwm0pLDvf8qVmAiOi2cvu8xDgboetoLWBoONOY2wvoEFRylLUGaieP
|
||||
UG5Yuofcj798uYPEqPLoF2ugnw8J/lhYhkMqTEbuqoyZT7DooBiqtSbm4b++T/Zt
|
||||
F6YnpkYeWIkv88UJaRvLG8OHytVbiC71JQ/DFCEjzNzATCKT7UFqyF4ZsT3cnGJe
|
||||
3x1iiSzWxJsnDkNZmiQ+IDYSM/dx7RJYwrXO5oWbAHC7otdC66O9eB1uBYq9I8gU
|
||||
4FcVKHbWAH1BYbsoF/pQJLz2mAXD7E92/Vvho7FgTKYOUq0b58LF9UHt+gDRUGUC
|
||||
L4HtuMeb/Ckiwyoej50jqI//ER1XswIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/
|
||||
MA4GA1UdDwEB/wQEAwIBxjAdBgNVHQ4EFgQUfsk69D2mzcAFjDX0GV53o3gySMMw
|
||||
DQYJKoZIhvcNAQELBQADggEBAH08sPexRXFxzuIVWD1aUoarYq8FwNBP+xusgZcg
|
||||
DmRKr0FpEyUjBxgVIsmd44WSX/TWdXokdd7aLPVnjwQbq2mhYtXAn4aIRn3QBNaj
|
||||
TvFQovVy+LCSRwZjvlpr/KJnXlVMrqLIxP++I6FqLO5G5zJ+qDF39C7RUkkMpvmU
|
||||
tiS70/zpt2LSfLUNtnS287P9s4wXEwbrkOOY6oNgKDz7jtNua0ZiPq2uGdqrkyZ2
|
||||
VPgirbNnuoC1uZmuy0Mvih4+8xrvJWHb9QO7JOH3cXA+ZiZ945V+viMEnV0YkQB6
|
||||
FL11l3fE9xzkPv357Z3e7QULnC8vDRgFAossuh8WBhNjjmo=
|
||||
-----END CERTIFICATE-----`;
|
||||
|
||||
Java.perform(() => {
|
||||
// First, we build a JVM representation of our certificate:
|
||||
const String = Java.use("java.lang.String");
|
||||
const ByteArrayInputStream = Java.use('java.io.ByteArrayInputStream');
|
||||
const CertFactory = Java.use('java.security.cert.CertificateFactory');
|
||||
|
||||
const certFactory = CertFactory.getInstance("X.509");
|
||||
const certBytes = String.$new(CERT_PEM).getBytes();
|
||||
const cert = certFactory.generateCertificate(ByteArrayInputStream.$new(certBytes));
|
||||
|
||||
// Then we hook TrustedCertificateIndex. This is used for caching known trusted certs within Conscrypt -
|
||||
// by prepopulating all instances, we ensure that all TrustManagerImpls (and potentially other
|
||||
// things) automatically trust our certificate specifically (without disabling validation entirely).
|
||||
// This should apply to Android v7+ - previous versions used SSLContext & X509TrustManager.
|
||||
const TrustedCertificateIndex = Java.use('com.android.org.conscrypt.TrustedCertificateIndex');
|
||||
TrustedCertificateIndex.$init.overloads.forEach((overload) => {
|
||||
overload.implementation = function () {
|
||||
this.$init(...arguments);
|
||||
// Index our cert as already trusted, right from the start:
|
||||
this.index(cert);
|
||||
}
|
||||
});
|
||||
|
||||
TrustedCertificateIndex.reset.overloads.forEach((overload) => {
|
||||
overload.implementation = function () {
|
||||
const result = this.reset(...arguments);
|
||||
// Index our cert in here again, since the reset removes it:
|
||||
this.index(cert);
|
||||
return result;
|
||||
};
|
||||
});
|
||||
|
||||
// This effectively adds us to the system certs, and also defeats quite a bit of basic certificate
|
||||
// pinning too! It auto-trusts us in any implementation that uses TrustManagerImpl (Conscrypt) as
|
||||
// the underlying cert checking component.
|
||||
|
||||
console.log('Inject system certificate trust');
|
||||
});
|
||||
Reference in New Issue
Block a user