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

SSL error when trying to bypass Youtube pinning #78

Open ta1c0 opened 6 months ago

ta1c0 commented 6 months ago

Hey, first I just wanted to mention that I really appreciate your hard work, thank you.

I'm using Burp as my proxy and mostly able to sniff most of the application I tried so far. When trying to sniff Youtube's app, the app starts but nothing loads, as if it has no internet connection. When looking on the logs (I'm on debug mode), I can see no errors or even an attempt to bypass the pinning (log attached at the end) I examined Logcat, and saw that the only indication I got is: [0314/163027.859572:ERROR:ssl_client_socket_impl.cc(975)] handshake failed; returned -1, SSL error code 1, net_error -202

BTW, if I try to sniff using HTTP Toolkit there are no error and I can see the traffic. Thank you

Log from frida

     ____
    / _  |   Frida 16.2.1 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to Android Emulator 5554 (id=emulator-5554)
Spawning `com.google.android.youtube`...                                

*** Starting scripts ***
Spawned `com.google.android.youtube`. Resuming main thread!             
[Android Emulator 5554::com.google.android.youtube ]->
    === 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 *
[ ] 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 ==
*** Scripts completed ***

 => android.security.net.config.NetworkSecurityConfig $init(*) (0)
 => android.security.net.config.NetworkSecurityConfig $init(*) (0)
 => android.security.net.config.NetworkSecurityConfig $init(*) (0)
 => android.security.net.config.NetworkSecurityConfig $init(*) (0)
 => javax.net.ssl.SSLContext init(KeyManager;[], TrustManager;[], SecureRandom)
pimterry commented 6 months ago

Which command are you running? It looks like you're not using the traffic capture or proxy override scripts. It might be worth trying that, instead of using the manual proxy setup that you'd normally have to do with Burp, since that may capture far more traffic.

Beyond that, I'm not sure what could cause this specifically. In general if some combination of the scripts here doesn't work immediately, you'll need to do some reverse engineering, and there's a guide for that here: https://httptoolkit.com/blog/android-reverse-engineering/

ta1c0 commented 6 months ago

Im using ‘frida -U -l config-burp.js -l android-certificate-unpinning.js -f com.google.android.youtube’ It works for most apps, but not for youtube I will also take a look at the guide you provided, thanks.

3052 commented 1 month ago

I dont think YouTube uses pinning, but it does use QUIC. but turns out if you block outbound UDP port 443 then YouTube uses HTTP/2 instead - so I am able to capture the Android client now

pimterry commented 1 month ago

@3052 thanks, that'd good info. Do you want to open a PR to the native-connect-hook here to block UDP 443? It should be possible to do this within the existing code there I think, and that way these scripts would handle that automatically.

3052 commented 1 month ago

eh I am extremely busy - as a recent YouTube change has killed a bunch of YouTube downloaders, and I currently have the only implementation of the new endpoint - but hopefully my comment above is helpful