Alles CTF 2020 Writeups
[Rev] Flag Service Revolution
Given a boot.dol file, a Nintendo GameCube file. Opened it with the dolphin-emu. Then searched how we can disassemble the .dol files and found this https://mkwii.com/showthread.php?tid=1193 used ghidraThis is a stripped and statically linked binary, it's hard to trace the functions.
Searched for strings appearing on app -> `Cross References` - `main function FUN_8003d4c4`.
The decompiled code of ghidra is too messy with the stripped func names, var names.
Anyway gone through the code and renamed `variables` and the `functions` based on arguments, codeflow, values etc.. by tracing to make it convinient.
Finally modified decompiled code :
By looking the game window, assumed that `No flag yet ...` is the status message.
Looked for it in code, checked if that status message changes anywhere and found line 179
flag_status = (undefined4 *)&local_a0;
From the declaration part, found that `local_a0 is a
char array upto local_7c`.From the code found that these values are get initiated based on some conditions, and finally that message goes to status message.
That constructed message is most likely a flag. Boom :)
It just modifying that array using the strings used previously in code
Written a python script based on those modifications. Got the flag :)
Flag : ALLES{Wii_love_to_enter_great_flags}
Solution - 2
But i want to complete this game in it's way :). skip;(next-chall, menu)In previous part in the urge of getting flag i have left those conditions.
The conditions are checking the key strokes, 🤔.
if (counter == 8) {
if ((key_code & 0x800) == 0) goto LAB_8003d8ec;
local_93 = s_great_0-4._2_1_;
counter = 9;
local_98 = s_service_revolution_16-4._0_1_;
}
else {
if (counter == 7) {
if ((key_code & 0x400) == 0) goto LAB_8003d8ec;
counter = 8;
local_85 = (char)s_great_0-4;
local_82 = s_flag_0-4._0_1_ + ' ';
local_92 = s_service_revolution_8-4._0_1_;
local_8d = s_service_revolution_16-4._2_1_;
}
Biseds the key_code check, the counter is increment, which makes leads it to
next check.Game wants us to click 10 keys (based on counter checks 0-9), in a sequence.
Key-code sequence : `0x8, 0x4, 0x200, 0x100, 0x200, 0x100, 0x400, 0x400, 0x800, 0x800`
Need to find the keys for those codes, Luckily it gives the key press status on game.
By tracing the status message variable, found a function for updating that message.
Used that function to extracted key-code, status message pairs.
0x8 = A = ML // Mouse Left Click
0x4 = B =MR // Mouse Right Click
0x800 = UP (up arrow key)
0x400 = DOWN (down arrow key)
0x200 = RIGHT (right arrow key)
0x100 = LEFT (left arrow key)
0x1000 = PLUS
0x10 = MINUS
Surprisigly, on Mouse clicks the game is displaying A, B. So ML(Mouse Left) = A ; MR(Mouse Right) = B.Finally: Key-Sequence = `ML, MR, RIGHT, LEFT, RIGHT, LEFT, DOWN, DOWN, UP, UP`.
Here we go :)
[Rev] prehistoric_mario
Given a prehistoric-mario.apk file, a Game simmilar to mario. given a map (100 x 100), with 11 question tiles, which changes there color on hit. (green-> red-> blue-> yellow-> green -> ..)Decompiled the Apk and gone through the source code. (MyPlatformer.java)
checkFlag function drabbed the attention,
private void checkFlag() {
MessageDigest messageDigest;
int intValue;
byte[] bArr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
TiledMapTileLayer tiledMapTileLayer = (TiledMapTileLayer) this.map.getLayers().get("questionmarks");
int i = 0;
int i2 = 0;
while (i < 100) {
int i3 = i2;
for (int i4 = 0; i4 < 100; i4++) {
TiledMapTileLayer.Cell cell = tiledMapTileLayer.getCell(i, i4);
if (!(cell == null || !cell.getTile().getProperties().containsKey("questionmarkType") || (intValue = ((Integer) cell.getTile().getProperties().get("questionmarkType")).intValue()) == 1337)) {
bArr[i3] = (byte) intValue;
i3++;
}
}
i++;
i2 = i3;
}
try {
messageDigest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
messageDigest = null;
}
messageDigest.update(bArr);
messageDigest.update("P4ssw0rdS4lt".getBytes());
if (toHex(messageDigest.digest()).equals("024800ace2ec394e6af68baa46e81dfbea93f0f6730610560c66ee9748d91420")) {
try {
// Use that messageDigest to decrypt the flag map
It's grabbing `questionmarkType` property values of 11 tiles(based on length of bArr), might be from those 11 questionMark tiles.Constructing a string with those values and checking its sha256 with some hash.
Note : the code is skipping tile with 1337 value, there might be 12th questionMark Tile some where in map.
Now we have to check for where 'questionmarkType' values are modified and where this checkFlag is called.
Surprisingly both are at same place.
TiledMapTileLayer tiledMapTileLayer = (TiledMapTileLayer) this.map.getLayers().get("questionmarks");
TiledMapTileLayer.Cell cell2 = tiledMapTileLayer.getCell((int) next.x, (int) next.y);
if (cell2.getTile().getProperties().containsKey("questionmarkType")) {
int intValue = ((Integer) cell2.getTile().getProperties().get("questionmarkType")).intValue();
if (intValue == 1337) {
new Array();
checkFlag();
} else {
if (intValue == 0) {
intValue = 21;
} else if (intValue == 21) {
intValue = 97;
} else if (intValue == 97) {
intValue = 37;
} else if (intValue == 37) {
intValue = 0;
}
try {
new TiledMapTileLayer.Cell();
cell2.setTile(this.map.getTileSets().getTile(this.questionMarkTileMapping.get(Integer.valueOf(intValue)).intValue()));
tiledMapTileLayer.setCell((int) next.x, (int) next.y, cell2);
} catch (Exception unused) {
}
}
z = true;
}
This is the code for hitting questionMark tiles event.Things to notice:
- we need to find the tile with 1337 value, and hit it to call check Flag
- The questionmarkType value is changing on hit (4 values), same like color.
Extracted the apk, to get (map.tmx) in assets. Used pytmx and loaded (map.tmx).
And found there is 12 tile(with 1337 value as expected) on [15, 90] grid. which is below the map. it's impossible to reach there.
2. questionmarkType values
Each color denotes each value.
0 = GREEN
21 = RED
97 = BLUE
37 = YELLOW
We need to set the colors of 11 question Mark tiles in a correct manner, then call checkFlag.11 tiles, 4 colors ; Total possibilites = 4**11 = 4194304. Nothing for a brite force :)
Python code for getting Key (colors): Color-Key : RED, GREEN, BLUE, YELLOW, RED, YELLOW, YELLOW, BLUE, BLUE, YELLOW, RED
Note: We need to set those colors from left -> right manner.
Now the only challenge with which we left is calling checkFlag
There might be many ways like patching apk, patching map, dynamic debugging.
I choose calling the function[checkFlag] using objection tool
The script i used :
Expliotation:
1. Solved the color of questionMark tiles as Color-Key (above), by hand.
2. Then injected that script using objection, then dumping the map_flag.tmx file
Now we need the see the dumped flag map.
I have unpacked it , and changed the map.tmx with this map_flag.tmx and packed it using apktool.
Then installed, opened. Everything is same as before (walls, questionMarkstiles, structure) :(
Again came to pytmx, loaded map_flag.tmx. to check if ther are any hidden layers etc.
Found that there are many(100+) questionMark tiles than normal, something is fishy
Extracted there cordinates, and drawn them with python for rough figure
Those 11 tiles on the upper half are similar to normal map.
Means those extra questionMarks are for drawing the flag , flag is below the map. It's time to jump 👀.
Boom :) Flag : ALLES{1TS_A_DINO}
Awesome writeup!
ReplyDelete