Implementing certificate pinning can be done by two methods. The first one is to pin the fingerprint of public key and the other one is to pin the certificate file.
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">example.com
</domain>
<pin-set>
<pin digest="SHA-256">mM294xslEgmvDODAxWWH2DeH4/bNgPBpgZvd7SfciuA=
</pin>
<pin digest="SHA-256">RQeZkB42znUfsDIIFWIRiYEcKl7nHwNFwWCrnMMJbVc=
</pin>
<pin digest="SHA-256">r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=
</pin>
</pin-set>
</domain-config>
</network-security-config>
You should patch this part like this:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="@raw/server" />
</trust-anchors>
</base-config>
</network-security-config>
You can do patch like upper example but it’s not recommended. Because usually the certificate will be check with other method. Therefore the better approach is to replace your certificate with original one.
To achieve this goal simply export burp certificate in der format and then replace with this file and then patch the network security config part.😃
Note: use apktool & zipalign and apksigner. Don't use tools like apklab.
This is old approach which developer store the certificate on keystore file. The developer should open the keystore with a password. You should first find the password.
private X509TrustManager trustManagerForCertificates(InputStream in) throws GeneralSecurityException {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
if (certificates.isEmpty()) {
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
}
char[] password = "password".toCharArray();
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
for (Certificate certificate : certificates) {
int index2 = index + 1;
String certificateAlias = Integer.toString(index);
keyStore.setCertificateEntry(certificateAlias, certificate);
index = index2;
}
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
return (X509TrustManager) trustManagers[0];
}
private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, password);
return keyStore;
} catch (IOException e) {
throw new AssertionError(e);
}
}
In this situation you can replace the keystore file.
Add a Certificate To Existing keystore
objection is a runtime mobile exploration toolkit, powered by Frida, built to help you assess the security posture of your mobile applications, without needing a jailbreak.
Frida is a dynamic code instrumentation toolkit that lets you inject your script into black-box processes (No source code needed). It is free and works on Windows, macOS, GNU/Linux, iOS, Android, and QNX. It is used for dynamic analysis of Android applications. It allows you to intercept and modify data passed between the application and the operating system. You can use it to bypass SSL pinning, tamper with HTTP requests/responses among other things.
To install it: