Sunday, September 22, 2013

CSAW CTF 2013 :: Web: Herpderper (300 points)

Tools Used:
Notepad++
Android Emulator & Android SDK
Burpsuite
apktool
keytool, jarsigner (JDK)

Ok, this is going to be a long article. Grab a cup of coffee and relax. In fact, grab one cup of coffee for me too =D

For this challenge, we were provided with an apk (Herpderper.apk)

As this is in the web category, I'm guessing we have to observe the web traffic from the application. In order to view the web traffic from the application, we would have to perform MITM on the Android Emulator.

I used Burp Suite. Fire it up and set the proxy settings.

Next we will launch the Android Emulator with the proxy settings enabled and pointing to BurpSuite. Create an emulated android device with the AVD Manager that comes with the Android SDK install. I created one that is running Android 4.0. To launch the emulator with proxy enabled, type the following command in the cmdline. (PS: the emulator binary is in the AndroidSDK/tools folder)

emulator -avd urEmulatorName -http-proxy proxyaddress:proxyport

Install the apk with the following command

adb install herpderper.apk

After installation, start the app and you should see a login screen.

Type in any email and password and try to login. If everything works correctly, burpsuite would be able to intercept the login request. However, burpsuite's intercept proxy does not see any requests. At the same time, the application displays a "Unknown Error" message in the UI. This is strange =/. Let's fire up "adb logcat", try to login again and see if there is any exception thrown

There is a debug message saying "Untrusted certificate chain". The application seems to be checking the SSL certificate presented by Burpsuite against something. We would have to reverse the apk and try to see how the application is checking the SSL certificate. We can use dex2jar and jd-gui to try and decompile and see the reconstructed java code. But I prefer looking at it in smali, to do this we need apktool. Run the following cmd to decompile the apk to smali

apktool d herpderper.apk herp
The decompiled files will be saved into the folder herp. Navigate to the /herp/smali/ops/black/herpderper folder (This is where all the source files are)

Open up all the smali files in Notepad++
Do a "Find All in All Opened Documents" with the string "Untrusted certificate chain"

The string is found in the class TrustModifier$AlwaysTrustManager. If we inspect the constructor of this class, we can see that it intializes a sequence of values that looks like SSL Cert values

We could create a self-signed cert with the same values and configure Burpsuite to serve that cert. But there is a easier way, we could patch the apk and make the application skip the ssl check completely. The ssl checks occur in the method checkServerTrusted. I added a line of code so that the method straight away returns without running the rest of the code. This effectively bypassed the SSL checks performed by the application

Now recompile the smali code back into an apk and install the patched apk to the emulator.
Run the following commands (You will be prompted for a password, just use the same password for both prompts)

- adb uninstall ops.black.herpderper
- apktool b herp patched.apk
- keytool -genkey -v -keystore my.keystore -alias anyalias -keyalg RSA -validity 10000
- jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore my.keystore patched.apk anyalias
- adb install patched.apk

Now, when we run the application and try to login with an email and password. The request is now properly intercepted by Burpsuite. However, when we forwarded the request, the received response was "integrity check failed". Let's see what is actually in the request

A post request is made to "https://webchal.isis.poly.edu/csaw.php" with 3 parameters
- 1 Base64-encoded username email (identity)
- 1 Base64-encoded password (secret)
- 1 long chunk of hex string (integrityid)

If we look back at the smali codes and try to find this integrityid parameter. It is in the AuthRequest class.

Upon further inspection of the code in this class, we found out that integrityid is actually the signature of the apk in a hex encoded format. Remember that we had to resign the patched apk in order to install it? (the jarsign command) This means that the server is actually checking that the application has not been tampered with. The next challenge is how do we get the signature of the original apk?

I found this article on androidcracking blog that described how to get the signature from a apk file. I copied the java code, compiled it into a jar file and ran the jar file against the original herpderper.apk. The output is the signature of the original herpderper.apk

Now go back to the Android emulator and try to login any email/password again. When Burpsuite intercepts the request, change the integrityid parameter to the signature that was just produced by the jar file and forward the request.

Now, the server responds with a "login failed" message. This means we have successfully bypassed its integrity check. The next part was where I was stuck for the longest time. I tried SQL injection and all kinds of stuffs but I will cut to the chase.

If we look at the "login failed" response from the server, there is actually a role parameter being returned. The solution is just to add a "role" parameter to the request. The value doesn't even matter. Once you submit that request, the server will respond with a "success" message together with the flag

(This screenshot is from a script that I wrote to make my life easier =D)

I apologise for the missing screenshots of the server responses. This is because I am writing this article after the CTF is over and CSAW has already shut down the server for this challenge. I'll remember to save screenshots as I play the next time =/

This was really an enjoyable challenge. I hope you enjoyed it as well as I did. Until next time.

Cheers,
thegrayone

1 comment: