[DevCTF-2022] Android WebSkills

Pranjal Aggarwal
DevCTF-2022
Published in
5 min readMay 18, 2022

Problem Statement

Problem Statement: Sometimes you have to know JavaScript to do Java.Apk Link: https://anonfiles.com/hdxaEdhfy9/gti_apk

Solution

This was one of the most difficult problems in the android category and remained unsolved! To solve this problem, we need to understand how JavaScript Interfaces work in Android. You can read more about it here. In brief it allows Java functions to be called from JavaScript code in Android WebView. So lets first get started by decompiling the apk.

Decompiling APK

  1. Use the ApkLab extension for VSCode to decompile the apk. Head over to the AndroidManifest.xml file.
  2. We see 2 activities: MainActivity and BasicActivity with exported set to true. We also see a receiver and provider. For now lets just focus on the activities and analyze their source codes one by one.
  3. MainActivity just has a text view displaying some text fetched from SharedPreferences.
  4. BasicActivty has some interesting code. There is a WebView, to which JavascriptInterface has been added: webView.addJavascriptInterface(new C1332b(this), "Android"); . What this means is object of Class C1332b (name may be different) would be available by the name Android in JavaScript.
  5. Now lets go to definition of this C1332b class. There is a showToast function exposed to javascript. It calls a library function checkPassword2 and displays the output using a toast. Now our next task should be to analyze this checkPassword2 function. To decompile the so file, I will use ‘ghidra’ here.

Making Sense of Library Function

After decompiling the .so file, head over to checkPassword2 function. It looks too complicated😬. Nonetheless few things are clear, using the stringcmpfunction, the three function arguments(param3, param4, param5) are being compared to some fixed constant strings. These are: yuiop , zxcvb , cvbnm . If any of the stringcmp fails tryAgain will be returned! So lets try passing these arguments to the checkPassword2 function call from the showToast function. So now lets use our web skills!

Code Snippet of checkPassword2 function

Web Skills

Now lets again look at the code of BasicActivity.java . It expects a data item(‘ur1’) with the intent, and if not found it uses the 9211.html file from the assets directory. Now ideally one should have called this activity from some other app(remember the exported tag in Manifest?). However to simplify things, lets update the AndroidManifest.xml to make it the launcher activity. The new AndroidManifest.xml should look something like this:

New AndroidManifest.xml

Now lets add a javascript function in 9211.html file. Simply add this line in the body of html:

<input type=”button” value=”Call ShowToastFunction” onclick=’Android.showToast(“Return Value will be logged ”,”yuiop”,”zxcvb”,”cvbnm”)’ />

Next step is to recompile the apk, with the new assets and AndroidManifest file. On running this recompiled apk, on clicking the Show button, we should see the return value being logged.

Recompiling Apk

We can recompile the apk using the apktool itself. You can use this command:

java -jar] apktool.jar b -f -o gti_recomp.apk gti/

This should ideally recompile the apk, however we see a strange error:

A quick google search finds us the fix of the error. All we have to do is replace @android with @*android in res/values-31/colors.xml file, and we are done! Now the apk should be compiled correctly. However the apk is still not ready to be installed on the phone. We need to sign the apk first. For this we will use the uber-signer software. After downloading, simply run:

java -jar uber-apk-signer-$version.jar -a gti_recomp.apk

This generates an apk gti_recomp-aligned-debugSigned.apk . This can be installed on your android apk. Next we will run the app, press the show button, and check the logs using adb logcat . Run grep command to filter words with Key in the logs. We observe the following line:

2359 3710 D Key : 161364F84F6734C2A62E6258D12A4

Well, still not the flag😢. But we atleast have some strange looking string code. What to do with this?

Screen Visible on opening Recompiled APK

Finding the Flag

Receiver Class

Remember the Receiver in manifest file? Well it was there with some purpose. Lets go to the Receiver.java file to check what its exactly doing. A BroadcastReceiver has been registered, which calls the m60a function(Name may differ) with some random string, along with a string passed in the intent. The return value of function is then stored in the sharedPreference, visible on opening the MainActivity. Jumping to the definition of m60a, we see that it first decodes one of the two input strings, and then uses it as key in AES Algorithm. Perhaps passing the second string as the code we discovered in the last section would work? To test this, there are two options, either to manually run this code snippet, and check the output, or to fire-up the broadcast receiver and pass 161364F84F6734C2A62E6258D12A4 as value in ‘Output’ key. And then re-run the MainActivity.java. In either case, we will get the correct output which is the flag:

ctf{w3bvi3w@3x3ported-in1ent@r3ciever}

Cheers🥂

Bonus Method

If you don’t want to go through the hassle of using the JavaScriptInterface, Receivers etc, there is another way to solve this problem! But this requires modifying the smali code, which in simple terms can be considered as the assembly code corresponding to the Java code. This during the process of recompiling, java code is ignored, and .smali files are actually recompiled.

Now in order to solve the problem using this method, we first will have to analyze the .so file as in previous sections. Once we have those three strings, we can directly patch the MainActivity.smali file, to display the flag on screen. How to patch, requires some understanding of dalvik- bytecodes and tinkering with the code. Here I have provided the final patched file as it is:

So, in short to test this, simply decompile the apk from scratch update the MainActivity.smali file with the above code, recompile the apk and install. On opening the apk, you should directly see the flag!

--

--

Pranjal Aggarwal
DevCTF-2022

CS Senior@IITD. I learn, do and write about natural language processing, computer vision and cybersecurity.