80 lines
4.1 KiB
Markdown
80 lines
4.1 KiB
Markdown
|
## Difficulty
|
||
|
Difficult
|
||
|
## Category
|
||
|
Reverse Engineering
|
||
|
## How To Solve
|
||
|
You can again use any utility you like to analyze the APK; in this writeup we use [JADX](https://github.com/skylot/jadx). Decompile the APK using `jadx oats3.apk`.
|
||
|
|
||
|
Open the the `MainActivity.java` file in the obtained folder, and take a look at the following lines. This is where the toppings are defined.
|
||
|
```java
|
||
|
public void onCreate(Bundle savedInstanceState) {
|
||
|
...
|
||
|
String oats3 = getIntent().getStringExtra("oats3");
|
||
|
final Ref.ObjectRef oatsToppings = new Ref.ObjectRef();
|
||
|
oatsToppings.element = new String[]{"Peanut butter", "Strawberry", "Sugar", "Honey", "Peach", "Blueberry", "Pear"};
|
||
|
if (Intrinsics.areEqual(oats3, "oats3")) {
|
||
|
oatsToppings.element = gmFunc.ensure((String[]) oatsToppings.element, gmFunc.function((String[]) oatsToppings.element, oats3, ((Object[]) oatsToppings.element).length, Random.INSTANCE.nextInt()));
|
||
|
} else {
|
||
|
oatsToppings.element = gmFunc.ensureNot((String[]) oatsToppings.element, gmFunc.nofunction((String[]) oatsToppings.element, "oats3", Random.INSTANCE.nextInt()));
|
||
|
}
|
||
|
...
|
||
|
}
|
||
|
```
|
||
|
You might want to try to find out what the `ensure`, `ensureNot`, `function` and `nofunction`, methods are doing. However, we intentionally obfuscated their functionality, so this might not be the easiest path towards the flag.
|
||
|
|
||
|
You may notice that an extra string is retrieved from the [intent](https://developer.android.com/reference/android/content/Intent). That string is then compared to the string `oats3", determining the rest of the program. By default, intents have no 'extra' values. Hence, we need to make sure that the MainActivity is started with an extra value. In this case, both the key and the value need to be "oats3".
|
||
|
|
||
|
When you take a look at the `AndroidManifest.xml`file, you can see the following lines containing intent filters that guide deep links into `MainActivity` using the scheme `app_scheme://flags.all`.
|
||
|
```xml
|
||
|
<activity android:exported="true" android:label="@string/app_name" android:name="com.example.oats.MainActivity" ...>
|
||
|
...
|
||
|
<intent-filter>
|
||
|
<data android:host="flags.all" android:scheme="app_scheme"/>
|
||
|
<action android:name="android.intent.action.VIEW"/>
|
||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||
|
<category android:name="android.intent.category.BROWSABLE"/>
|
||
|
</intent-filter>
|
||
|
</activity>
|
||
|
```
|
||
|
|
||
|
You can also see from this file that the app's package name is `com.example.oats`.
|
||
|
|
||
|
This information suffices to write our own small app that launches the Oats app and starts the `MainActivity` with an extra string payload. Here is an example of a function you might need in this app:
|
||
|
```java
|
||
|
private fun launchOtherAppActivity() {
|
||
|
val packageName = "com.example.oats" // Replace with the target app's package name
|
||
|
val scheme = "app_scheme"
|
||
|
val host = "flags.all"
|
||
|
|
||
|
val intent = Intent(Intent.ACTION_VIEW)
|
||
|
val uri = Uri.parse("$scheme://$host")
|
||
|
intent.data = uri
|
||
|
|
||
|
// Set the oats3 payload
|
||
|
intent.putExtra("oats3", "oats3")
|
||
|
|
||
|
// Set the flag to launch the activity in a new task
|
||
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||
|
|
||
|
// Check if the app is installed before launching
|
||
|
val packageManager = packageManager
|
||
|
val isAppInstalled = packageManager.getLaunchIntentForPackage(packageName) != null
|
||
|
|
||
|
if (isAppInstalled) {
|
||
|
startActivity(intent)
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
Also don't forget to add the following lines to your `AndroidManifest.xml`. You won't be able to launch the other application without this:
|
||
|
```xml
|
||
|
<queries>
|
||
|
<package android:name="com.example.oats" />
|
||
|
</queries>
|
||
|
```
|
||
|
This write-up also contains a full [write-up apk](oats3_writeup.apk) that can be used to perform flag extraction.
|
||
|
|
||
|
When you run the exploit app, you are immediately redirected to the Oats app. However, you can now see another topping added at the bottom of the list: `SUdDVEZ7TzR0c193MXRoX00xbGt9`. Enter this value into [CyberChef](https://gchq.github.io/CyberChef/#input=U1VkRFZFWjdUelIwYzE5M01YUm9YMDB4Ykd0OQ) and you can obtain the flag.
|
||
|
![](screenshot1.png)
|
||
|
|
||
|
## Flag
|
||
|
`IGCTF{O4ts_w1th_M1lk}`
|