httptoolkit / frida-interception-and-unpinning

Frida scripts to directly MitM all HTTPS traffic from a target mobile application
https://httptoolkit.com/android/
GNU Affero General Public License v3.0
1.06k stars 198 forks source link

Error: access violation accessing 0x5d8 #93

Open fftry12 opened 4 months ago

fftry12 commented 4 months ago

Hi, I got this error when running the script

*** Starting scripts ***
== Redirecting all TCP connections to 192.168.1.100:8888 ==
[+] Patched 2 libssl.so verification methods
== Hooked native TLS lib libssl.so ==
Spawned `kr.co.kork7app`. Resuming main thread!
[SM-G988N::kr.co.kork7app ]-> == Proxy system configuration overridden to 192.168.1.100:8888 ==
Rewriting <class: java.net.ProxySelector>
Rewriting <class: sun.net.spi.DefaultProxySelector>
== Proxy configuration overridden to 192.168.1.100:8888 ==
[+] Injected cert into com.android.org.conscrypt.TrustedCertificateIndex
[ ] Skipped cert injection for org.conscrypt.TrustedCertificateIndex (not present)
[ ] Skipped cert injection for org.apache.harmony.xnet.provider.jsse.TrustedCertificateIndex (not present)
== System certificate trust injected ==

    === Disabling all recognized unpinning libraries ===
[+] javax.net.ssl.HttpsURLConnection setDefaultHostnameVerifier
[+] javax.net.ssl.HttpsURLConnection setSSLSocketFactory
[+] javax.net.ssl.HttpsURLConnection setHostnameVerifier
[+] javax.net.ssl.SSLContext init(KeyManager;[], TrustManager;[], SecureRandom)
[ ] com.android.org.conscrypt.CertPinManager isChainValid
[+] com.android.org.conscrypt.CertPinManager checkChainPinning
[+] android.security.net.config.NetworkSecurityConfig $init(*) (0)
[+] android.security.net.config.NetworkSecurityConfig $init(*) (1)
[+] com.android.okhttp.internal.tls.OkHostnameVerifier verify(String, SSLSession)
[+] com.android.okhttp.Address $init(String, int, Dns, SocketFactory, SSLSocketFactory, HostnameVerifier, CertificatePinner, Authenticator, Proxy, List, List, ProxySelector)
[ ] com.android.okhttp.Address $init(String, int, SocketFactory, SSLSocketFactory, HostnameVerifier, CertificatePinner, Authenticator, Proxy, List, List, ProxySelector)
[ ] okhttp3.CertificatePinner check(String, List)
[ ] okhttp3.CertificatePinner check(String, Certificate)
[ ] okhttp3.CertificatePinner check(String, Certificate;[])
[+] okhttp3.CertificatePinner a(String, List)
[ ] okhttp3.CertificatePinner check$okhttp
[ ] com.squareup.okhttp.CertificatePinner *
[ ] com.datatheorem.android.trustkit.pinning.PinningTrustManager *
[ ] appcelerator.https.PinningTrustManager *
[ ] nl.xservices.plugins.sslCertificateChecker *
[ ] com.worklight.wlclient.api.WLClient *
[ ] com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning *
[ ] com.worklight.androidgap.plugin.WLCertificatePinningPlugin *
[ ] com.commonsware.cwac.netsecurity.conscrypt.CertPinManager *
[ ] io.netty.handler.ssl.util.FingerprintTrustManagerFactory *
[ ] com.silkimen.cordovahttp.CordovaServerTrust *
[ ] com.appmattus.certificatetransparency.internal.verifier.CertificateTransparencyHostnameVerifier *
[ ] com.appmattus.certificatetransparency.internal.verifier.CertificateTransparencyInterceptor *
[ ] com.appmattus.certificatetransparency.internal.verifier.CertificateTransparencyTrustManager *
== Certificate unpinning completed ==
== Unpinning fallback auto-patcher installed ==
*** Scripts completed ***

Ignoring attempt to clear http.proxyHost system property
Ignoring attempt to clear https.proxyHost system property
Ignoring attempt to clear http.proxyPort system property
Ignoring attempt to clear https.proxyPort system property
Ignoring attempt to clear http.nonProxyHosts system property
Ignoring attempt to clear https.nonProxyHosts system property
Ignoring unix:stream connection
Manually intercepting connection to 188.114.97.2:443
Ignoring unix:stream connection
Ignoring unix:stream connection
Connected tcp fd 42 to {"ip":"192.168.1.100","port":8888} (-1)
 => android.security.net.config.NetworkSecurityConfig $init(*) (1)
 => android.security.net.config.NetworkSecurityConfig $init(*) (0)
 => com.android.okhttp.Address $init(String, int, Dns, SocketFactory, SSLSocketFactory, HostnameVerifier, CertificatePinner, Authenticator, Proxy, List, List, ProxySelector)
Ignoring unix:stream connection
Ignoring unix:stream connection
Ignoring unix:stream connection
Connected tcp6 fd 54 to null (-1)
 => com.android.okhttp.Address $init(String, int, Dns, SocketFactory, SSLSocketFactory, HostnameVerifier, CertificatePinner, Authenticator, Proxy, List, List, ProxySelector)
Ignoring unix:stream connection
Ignoring unix:stream connection
Connected tcp6 fd 127 to {"ip":"::ffff:192.168.1.100","port":8888} (-1)
Ignoring udp6 connection
Ignoring unix:stream connection
Ignoring unix:stream connection
Ignoring unix:stream connection
Ignoring unix:stream connection
Connected tcp fd 161 to null (-1)
 => javax.net.ssl.SSLContext init(KeyManager;[], TrustManager;[], SecureRandom)
 => javax.net.ssl.SSLContext init(KeyManager;[], TrustManager;[], SecureRandom)
 => com.android.okhttp.internal.tls.OkHostnameVerifier verify(String, SSLSession)
 => com.android.okhttp.internal.tls.OkHostnameVerifier verify(String, SSLSession)
Ignoring unix:stream connection
Ignoring unix:stream connection
Connected tcp6 fd 140 to {"ip":"::ffff:192.168.1.100","port":8888} (-1)
 => com.android.okhttp.Address $init(String, int, Dns, SocketFactory, SSLSocketFactory, HostnameVerifier, CertificatePinner, Authenticator, Proxy, List, List, ProxySelector)
Ignoring unix:stream connection
Ignoring unix:stream connection
Connected tcp6 fd 166 to {"ip":"::ffff:192.168.1.100","port":8888} (-1)
Error: access violation accessing 0x5d8
    at <anonymous> (C:\Users\13\Documents\frida-interception-and-unpinning-main\native-tls-hook.js:111)
 => com.android.okhttp.internal.tls.OkHostnameVerifier verify(String, SSLSession)
Ignoring unix:dgram connection
Process terminated

At first I had this error

[!] Matched class okhttp3.CertificatePinner but could not patch any methods

certificate

Adding this to "android-certificate-unpinning.js" fixed that issue

{
    methodName: 'a',
    overload: ['java.lang.String', 'java.util.List'],
    replacement: () => NO_OP
},
const realCallback = new NativeFunction(realCallbackAddr, 'int', ['pointer','pointer']);

const hookedCallback = new NativeCallback(function (ssl, out_alert) {
    let realResult = false;

    if (targetLib !== 'libboringssl.dylib') {
        // Cronet assumes its callback is always calls, and crashes if not. iOS's BoringSSL
        // meanwhile seems to use some negative checks in its callback, and rejects the
        // connection independently of the return value here if it's called with a bad cert.
        // End result: we *only sometimes* proactively call the callback.
        realResult = realCallback(ssl, out_alert)
    }

That's the line which makes it crash

realResult = realCallback(ssl, out_alert)

maybe int should be replaced by another type

const realCallback = new NativeFunction(realCallbackAddr, 'int', ['pointer','pointer']);

I've tested it on other apps with the same configuration, so far that's the only app i'm having trouble with, so the issue is unlikely to be from my end. Here's the command line i use to launch the script

frida -U -l ./config.js -l ./native-connect-hook.js -l ./native-tls-hook.js -l ./android/android-proxy-override.js -l ./android/android-system-certificate-injection.js -l ./android/android-certificate-unpinning.js -l ./android/android-certificate-unpinning-fallback.js -f kr.co.kork7app
pimterry commented 4 months ago

Hmm, this is very interesting! Thanks for the detailed error report.

Adding this to "android-certificate-unpinning.js" fixed that issue

This is a good fix given the obfuscation here, but it's probably not actually necessary. OkHTTP failures are caught by the 'fallback' script, even if they're obfuscated (by checking for thrown TLS errors matching built-in types, and pattern matching against the class structure). That's not happening here (it prints a large warning) so this shouldn't matter much.

Error: access violation accessing 0x5d8

This is definitely more concerning & interesting. Unfortunately I can't reproduce the exact error here though. With a quick test I see:

Very occasionally it fails with:

Cmdline: kr.co.kork7app
pid: 11603, tid: 11787, name: DefaultDispatch  >>> kr.co.kork7app <<<
uid: 10173
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000010
Cause: null pointer dereference
Abort message: 'FORTIFY: pthread_mutex_lock called on a destroyed mutex (0x7d4a2c7962c8)'
    rax 00001e460023d160  rbx 0000000000000000  rcx 0000000000000000  rdx 0000000000000000
    r8  00007d46ea192470  r9  0000000000000000  r10 0000000000000000  r11 0000000000000246
    r12 0000000000000000  r13 00007d46ea192470  r14 00001e460064a0a0  r15 0000000000000000
    rdi 00001e460023d160  rsi 00007d4715eced3b
    rbp 0000000000000000  rsp 00007d46ea190d20  rip 00007d47194084a5
backtrace:
      #00 pc 00000000037614a5  /product/app/TrichromeLibrary/TrichromeLibrary.apk!libmonochrome_64.so (BuildId: 2759a97e5f69d7525020ed6c6e09c6dd52905ae6)
      #01 pc 0000000003760f84  /product/app/TrichromeLibrary/TrichromeLibrary.apk!libmonochrome_64.so (BuildId: 2759a97e5f69d7525020ed6c6e09c6dd52905ae6)
      #02 pc 00000000036c3e24  /product/app/TrichromeLibrary/TrichromeLibrary.apk!libmonochrome_64.so (BuildId: 2759a97e5f69d7525020ed6c6e09c6dd52905ae6)
      #03 pc 0000000004139e51  /product/app/TrichromeLibrary/TrichromeLibrary.apk!libmonochrome_64.so (BuildId: 2759a97e5f69d7525020ed6c6e09c6dd52905ae6)
      #04 pc 000000000413a138  /product/app/TrichromeLibrary/TrichromeLibrary.apk!libmonochrome_64.so (BuildId: 2759a97e5f69d7525020ed6c6e09c6dd52905ae6)
      #05 pc 00000000036ba5d4  /product/app/TrichromeLibrary/TrichromeLibrary.apk!libmonochrome_64.so (BuildId: 2759a97e5f69d7525020ed6c6e09c6dd52905ae6)

That seems unrelated, and I've managed to reproduce this with and without the TLS hook script. It's hard to know exactly what triggers that. I have seen some anti-Frida blocks do things like this on purpose elsewhere I think so it could be related to that.

maybe int should be replaced by another type

const realCallback = new NativeFunction(realCallbackAddr, 'int', ['pointer','pointer']);

The types here come from BoringSSL (you can see here libssl.so is being patching - that should always be some BoringSSL version). I think that this is always the correct type because:

That said, that's for the latest version of BoringSSL. It might be possible that older versions are different, or really really old version use OpenSSL or something else instead maybe. What Android version are you using? Can you share the exact details of your device setup? That might provide some clues.