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
905 stars 178 forks source link

FATAL EXCEPTION: OkHttp Dispatcher #10

Open cyal1 opened 2 years ago

cyal1 commented 2 years ago

Process crashed: java.lang.NullPointerException: interceptor se0.e@1c6a394 returned null


FATAL EXCEPTION: OkHttp Dispatcher Process: cn.adidas.app, PID: 1455

pimterry commented 2 years ago

This probably means that the SSLPeerUnverifiedException auto-patcher isn't working right. Can you try commenting out this section and see if it works for you?

This code is designed to try and automatically hotfix unknown code that appears to be rejecting a certificate, by just replacing erroring methods with an empty method that returns null. In some cases this could easily cause null pointer issues though.

Commenting that out will confirm the cause here. Unfortunately, even if you remove that you'll probably still have an issue. This error normally means that there's an unrecognized method (in your case se0.e) which is validating certificates and rejecting them, so if you disable the autopatch fix then your certificate will just be rejected for real.

From se0.e class name in that error message, it looks like this is happening because the app's code is obfuscated, so no methods can be recognized at all. That's inconvenient, but it's solvable. To handle this, you'll need to reverse engineer the app, and modify the script to work against that specific obfuscated code. I've written a guide to reverse engineering here: https://httptoolkit.tech/blog/android-reverse-engineering/

cyal1 commented 2 years ago

This probably means that the SSLPeerUnverifiedException auto-patcher isn't working right. Can you try commenting out this section and see if it works for you?

This code is designed to try and automatically hotfix unknown code that appears to be rejecting a certificate, by just replacing erroring methods with an empty method that returns null. In some cases this could easily cause null pointer issues though.

Commenting that out will confirm the cause here. Unfortunately, even if you remove that you'll probably still have an issue. This error normally means that there's an unrecognized method (in your case se0.e) which is validating certificates and rejecting them, so if you disable the autopatch fix then your certificate will just be rejected for real.

From se0.e class name in that error message, it looks like this is happening because the app's code is obfuscated, so no methods can be recognized at all. That's inconvenient, but it's solvable. To handle this, you'll need to reverse engineer the app, and modify the script to work against that specific obfuscated code. I've written a guide to reverse engineering here: https://httptoolkit.tech/blog/android-reverse-engineering/

Thank you for your advice. I'll take a look

tcortega commented 1 year ago

This probably means that the SSLPeerUnverifiedException auto-patcher isn't working right. Can you try commenting out this section and see if it works for you?

This code is designed to try and automatically hotfix unknown code that appears to be rejecting a certificate, by just replacing erroring methods with an empty method that returns null. In some cases this could easily cause null pointer issues though.

Commenting that out will confirm the cause here. Unfortunately, even if you remove that you'll probably still have an issue. This error normally means that there's an unrecognized method (in your case se0.e) which is validating certificates and rejecting them, so if you disable the autopatch fix then your certificate will just be rejected for real.

From se0.e class name in that error message, it looks like this is happening because the app's code is obfuscated, so no methods can be recognized at all. That's inconvenient, but it's solvable. To handle this, you'll need to reverse engineer the app, and modify the script to work against that specific obfuscated code. I've written a guide to reverse engineering here: https://httptoolkit.tech/blog/android-reverse-engineering/

I wonder if there isn't an easier fix for this. Been having the same issue:

FATAL EXCEPTION: OkHttp Dispatcher
Process: random.app, PID: 8163

java.lang.IndexOutOfBoundsException: Empty list doesn't contain element at index 0.
        at xz2.g0.b(Collections.kt)
        at xz2.g0.get(Collections.kt)
        at na.d.b(SSLHandshakeInterceptor.kt:1)
        at na.d.intercept(SSLHandshakeInterceptor.kt:2)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at mq2.e.intercept(CertificateTransparencyInterceptor.kt:10)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:4)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:27)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:22)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:7)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at in2.g.intercept(GzipResponseInterceptor.kt:5)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at in2.i.b(MarketplaceCredentialInterceptor.kt:2)
        at in2.i.intercept(MarketplaceCredentialInterceptor.kt:2)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at in2.r.intercept(ProactiveRefreshTokenInterceptor.kt:13)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at h71.k.intercept(LocationInterceptor.kt:8)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at zm2.a.intercept(AbTestInterceptor.kt:8)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at vn2.e.intercept(TimeoutInterceptor.kt:19)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at an2.a.intercept(AppInfoInterceptor.kt:19)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at in2.a.intercept(AuthenticationInterceptor.kt:8)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:12)
        at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:16)
        at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:6)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)
tcortega commented 1 year ago

@pimterry By the way, read the tutorial you linked and thanks for the work, really good. But in your scenario, there was a simpler code and the error was intrinsic to the app itself. My error seems to be in relation to okhttp, what should I do?

pimterry commented 1 year ago

My error seems to be in relation to okhttp, what should I do?

The exact same concept as that article applies: you need to reverse engineer the code and find out where to apply a patch, and then use Frida to change the behaviour in the target code.

From your stack trace, I think in your case OkHttp is not obfuscated (because the full class name is listed there clearly), but the core app code contains custom certificate pinning logic for this app in na.d.intercept(SSLHandshakeInterceptor.kt:2), which does look like it has been obfuscated.

Some interaction between the two is causing a problem, but it's not clear from that trace why, or exactly where the issue is.

To solve this, you'll need to open up the app with JADX, as in the article, look at that na.d class and its intercept method and OkHttp's RealInterceptorChain.process() logic, work out what those are doing, and then work out how to change them to do what you want.

You can try disabling the SSLPeerUnverifiedException patch at the start of this Frida script, to see if that helps in your case. That's the one hook in the script that I know doesn't work 100% of the time and could cause problems (although AFAIK all cases where it breaks are places where SSL pinning is going to fail regardless). That's a best-efforts optimistic hook for edge cases, whereas the rest of the script is all designed to target specific APIs and should never fail.

You can try commenting out the OkHttp hooks too to test those though. If you find that there's one that is genuinely causing problems with a specific app, do let me know and I can investigate it further.