Skip to main content

pull-me

Solved by: grb

This is what the challenge looks like, there's an APK file attached with it, a change of scenery huh?

Challenge

Let's use jadx-gui to decompile this APK, shall we? Cuz we goin' for full static analysis.

jadx first time

This is what you will see when you load the APK for the first time in jadx-gui. As you can see, we have our target class which should contain the game core codes. Lets start the analysis by searching for anything about the flag in the class.

search result

Woah, so much result eh? And a bunch of interesting stuff too! Let's start with the com.requiiem.compitgacha.network.ApiServiceKt.encryptedFlagData data.

public final class ApiServiceKt {
public static final int FLAG_PRICE = Integer.MAX_VALUE;
private static final byte[] encryptedFlagData = {-83, 47, -102, -29, -90, -80, 109, -6, -38, -52, 92, -118, -73, -50, 34, -49, -39, -120, 23, -83, 87, 22, 0, 53, -70, 64, 39, -107, -79, 17, 20, 31, 64, 72, -24, 39, -74, 25, 118, -10, -15, -74, 83, -14, -126, -104, 94, -89, Base64.padSymbol, 85, -105, 63, 96, -79, -59, -22, 84, 79, -56, 113, 110, -14, 101, -120, -115, -85, -20, -116, -95, 83, 63, 20, -84, -68, 98, 53, -31, -58, 106, -40, -124, 99, -119, 102, -69, 105, -25, -102, -31, -91, 58, -25, 95, -21, -84, 20, 97, -5, -95, 17, -75, -80, -20, -64, -17, 0, -109, -72, 101, -43, -77, -61, 51, 23, 110, -112, 84, -38, -10, 70, 14, 14, 35, 126, -23, -47, 12, 120, -31, -92, -64, 40, 77, 12, 41, -91, 93, 67, 111, 89, -34, -82, 112, 93, 111, 21, -86, -35, 125, 108, -120, -91, 21, -76, 0, 32, -10, -94, -19, -29, 47, -7, 10, -100, 12, 123, 56, 62, -117, -92, -10, -88, 88, -27, 96, 20, 70, 104, -89, 86, 5, 39, ByteCompanionObject.MIN_VALUE, 65, -17, 31, -64, -19, -93, 93, -52, 119, 108, -107, -34, -87, -96, -123, 1, -69, -119, 55, 41, 6, -123, 46, -45, 96, 90, 103, -10, 16, -61, 37, -120, -12, -12, 59, -65, 56};
}

It looks like the flag is some sort of buyable object inside the app. Lets find any cross-reference with this data.

found buyFlag

Bingo! Sounds interesting, lets check it out.

buyFlag

So, this function is the decryptor of the encrypted flag data we found before. We can see that the key consists of the app signature SHA256 hash, the current currency of the player in the app (which should be consistent with the FLAG_PRICE we found before), and the list of 3 star names. Lets collect them all before decrypting the flag ourself. Lets start with the app signature SHA256 hash. We could get it right from the jadx.

APK signature

Next, the current currency of the player. If the flag is a buyable object, then the buyFlag function should only be executed if the currency of the player is enough to buy the flag, which is the 32bit positive integer max value (2147483647). And lastly, the list of 3 star names.

get3StarNames

getAllTemplatesOfRarity

loadCharactersFromXml

I think the 3 star names are stored in an XML. We can easily find it from the jadx or by searching the file manually.

XML

Concatenating all of them becomes KnightPaladinNinjaRobotWitchBardPirate. And at last, I asked an LLM to create me a decryptor code in python with all of those parameters as the key. You can check it here. And when we run it...

PWNED!

PO- PO- PO- PWNED!!!