shroudedcode / apk-mitm

🤖 A CLI application that automatically prepares Android APK files for HTTPS inspection
https://npm.im/apk-mitm
MIT License
3.6k stars 337 forks source link

App crashes during login #68

Closed jj0e closed 2 years ago

jj0e commented 2 years ago

I'm working on reverse engineering an app right now. I need to login in order to gain access to the app. I have patched the app with apk-mitm, however when I go to login, the app crashes on login. When I inspect requests, the login is successful, but something else is preventing the UI from proceeding. After some deep digging, I was able to find the exact cause. Here is the exception that is being thrown from the app:

"exception": {
    "name": "java.lang.SecurityException",
    "cause": "uid 10326 cannot peek the authtokens associated with accounts of type: com.my.app.name"
  }

The issue is happening on class android.accounts.IAccountManager$Stub$Proxy and method peekAuthToken. More information about this class/method can be found here

What I don't understand, is how apk-mitm is causing this. I'm able to view requests and login perfectly fine using Frida, so I know for a fact that the issue is somehow related to apk-mitm.

Logically, it seems this issue is unrelated, but it only occurs with apk-mitm patch. Is there any insight that can be provided in order to fix this issue? I would love to use apk-mitm for my solution as Frida has some limitations.

EDIT: when I uninstall the app patched with apk-mitm, and reinstall regular version, my login is already persisted. This makes me question, is apk-mitm changing the app identifier or something?

shroudedcode commented 2 years ago

I would assume that you've used Frida in combination with a rooted phone (instead of frida-gadget), so the difference between your previous workflow and apk-mitm is that now you're now using a modified APK which can sometimes cause issues that are entirely unrelated to the changes that were made. This is due to the way that Apktool (which apk-mitm uses under the hood) decodes and re-encodes APK files.

To see if your issue is specifically caused by apk-mitm's changes or has simply been "corrupted" in some way during the de-/encoding process, you can try passing the --skip-patches flag. This won't apply any patches, so HTTPS proxying will not work, but it should allow you to test whether the app generally works.

jj0e commented 2 years ago

I would assume that you've used Frida in combination with a rooted phone (instead of frida-gadget), so the difference between your previous workflow and apk-mitm is that now you're now using a modified APK which can sometimes cause issues that are entirely unrelated to the changes that were made. This is due to the way that Apktool (which apk-mitm uses under the hood) decodes and re-encodes APK files.

To see if your issue is specifically caused by apk-mitm's changes or has simply been "corrupted" in some way during the de-/encoding process, you can try passing the --skip-patches flag. This won't apply any patches, so HTTPS proxying will not work, but it should allow you to test whether the app generally works.

I apologize for forgetting to specify my previous workflow in more detail. It actually was with frida-gadget on a non-rooted, real phone. Specifically, I'm using objection to patch the APK. The limitation that I don't like is that I need to have a Frida server running in order to get requests. So, there is really no difference in terms of the modified APK process.

I went ahead and tried passing the --skip-patches flag and the login issue persists. What do you suggest?

shroudedcode commented 2 years ago

Mmh, very interesting. The way objection and apk-mitm patch APKs is quite similar, so I'm surprised by the different results. Maybe objection uses a different version of Apktool or passes different flags...

Here's something you could try to figure this out:

If this works, you'd see what's different between the two APKs. Without knowing that (and especially without having access to the APK myself) I can't really help.

jj0e commented 2 years ago

I went ahead and gave this a try, I agree it would be good to see differences.

Here is the APK download, I've been trying to prevent putting the name just for sake of trying to prevent searches.

However, based on my analysis, it seems the only smali file that is different is TheWallActivity.smali

APK-MITM

151c151
<     .locals 2
---
>     .locals 3

OBJECTION

161a162,165
>     const-string v0, "frida-gadget"
> 
>     invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
> 

and it seems that its just frida-gadget. And TheWallActivity seems like it contains the code that handles whether user is logged in or not. I'm still confused on how this difference would cause the issue.

shroudedcode commented 2 years ago

One thing I could think of is that apk-mitm passes the --use-aapt2 flag to Apktool by default when re-encoding the app (which objection might not do). What you could try is to run apk-mitm without the --skip-patches flag and then re-encode the decode directory (you can find it in the temporary directory printed at the top) again without passing the --use-aapt2 flag to Apktool. Let me know if that changes anything.

jj0e commented 2 years ago

The issue still persists. I believe I have used both aapt and aapt2 with objection so I'm not surprised at this outcome.

jj0e commented 2 years ago

I've found the solution. Turns out it was completely unrelated to apk-mitm, which makes sense in the end. The issue was that AccountManager, is somehow tied to the signing cert. I had another app on my device that used the same AccountManager but had the objection signing cert. So when I tried to access this AccountManager with the apk-mitm signing cert, issues were raised. All I had to do was delete the other app.

shroudedcode commented 2 years ago

Huh, interesting... glad you found a solution!

Just out of curiosity: In what way can multiple apps "use the same AccountManager"? How are individual AccountManager's identified?

jj0e commented 2 years ago

I'm no expert, but from what I can see, each app that uses android.accounts.AccountManager require the need to specify an id similar to the app identifier com.xxx.xxx. Which is stored in authenticator.xml. It could even be the actual app identifier, which I would guess is what most apps are doing. When the device newly adds this id to that account store (or wherever it stores these things), it associates it with the signing certificate of the app that added it to the account store.

So, I guess to answer your question, each one has an explicit id that is specified in authenticator.xml

In my unique edge case, I had two apps installed on my device both from the same company, Nike. Since the same authentication API is used on both apps, they created a single account store for both apps. The signing cert of the app seems to act like a key to access the account store, so if the signing cert does not match the signing cert that was used to create the account store, it will return the error that I got: "Cannot peek the auth tokens..." because its essentially getting access denied. The solution is to have both apps patched with apk-mitm, objection, or only have one of the two installed.

shroudedcode commented 2 years ago

@jj0e Thanks for the detailed explanation, that clears things up for me!