Reverse Engineering — Deep CTF 2020

kosong
8 min readApr 6, 2020

Last weekend there was CTF event organized by Deep Tech and i played as Bat Squad team . Thank you to the organizer for providing great CTF and thank you to sponsors for giving interesting award .

Here is my solution for Reverse Engineering Challenge.

Nested Rev

Using ghidra for open the binary file and go to the main function

There are lots of if statement which if we order the variables it will produce flag, but i’m too lazy to do it. So here i am using angr to automate solving that binary.

Finding address of main function

Finding instruction for load string “Voila!!! You Got It” from memory using gdb.

After that write a program for find the correct value automatically using angr.

import angr
import monkeyhex
import sys
base=0x400000
main=base+0x0000000000001155
project = angr.Project('binary/Cr4ckm3')
initial_state=project.factory.entry_state(addr=main)
simulation=project.factory.simgr(initial_state)
load_good_address=base+0x0000000000001295
simulation.explore(find=load_good_address)
if simulation.found:
solution_state = simulation.found[0]
print(solution_state.posix.dumps(sys.stdin.fileno()))
else:
raise Exception('Could not find the solution')

and here is the result.

Flag : d33p{y0u_r3v3rs3d_1t_w3ll}

SkipMe

Open the binary using ghidra and go to the main function

In this challenge we need to change the value of our computer name,os,cpuid to the correct value like in strcmp argument and in the end if our values are correct the program will run finish function. So like the title of challenge “SkipMe” , we can skip all those checks and directly call finish function.

Flag : d33p{f51579e9ca38ba87d71539a9992887ff}

0xKEY

Open the binary using ghidra and go to the main function

I think this challenge is broke, because we can easily knowing the flag by using ltrace command (because there is strcmp function which compare string and we can find out the argument of strcmp using ltrace command).

If there is no strcmp function we can examine the address of secret like this for find out the flag.

main function
break after generateMyFlag and then run the program
examine the value of secret as string and got the flag

Flag : d33p{jnhFClg2sv3uaBBxs}

Down

Open the binary using ghidra

Nothing helpful, so here i decide to run the file and here is the result.

After clicking ok the program will close, but here we know some string stored on that executable , so the next step is try to examine defined string on that executable.

Using the address for that string we can find the reference to that address which may be the address of main function.

Lets move to assembly tab instead of pseudocode tab to be more obvious.

from the instruction we know that the program after calling message box will call FUN_004012c0() which is calling GetTickCount function and the next instrucion is INT (interrupt) 3 which is intended for calling the debug exception handler and this instruction make the program break. There area many int 3 instruction after calling FUN_004012c0() and then something like garbage after the last int 3 instruction.

Here i try to convert it to assembly instruction and here is the result

There are some jump instruction and the last jump instruction lead to the flag.

So here my solution is changing the assembly instruction int3 to nop so the program can continue to the next instruction and lead to the message box with flag on it.

before patched
after patched

And then run the file to get the flag

Flag : d33p{ww.canabalt.com}

Wacha Wachin

At the beginning i thought the challenge was about reversing the encrypted pdf file , but it didn’t,it was even worse :) . Here is the contents of the pdf file.

That is assembly on arm architecture, here I analyze these instructions manually .

Some arm assembly instruction cheat sheet

ADD     R2, R2, R1    // R2=R2+R1
MOV R3, R2,LSL#6 // R3=R2<<6
SUB R3, R3, R2 // R3=R3-R2
EOR R3, R3, R2 // R3=R3^R2
AND R3, R3, #0xFF // R3=R3&0XFF
ORR R3, R0, R3 // R3=R0|R3

Here i will say set of instruction per box as section, so start from the first section

First Section

check_flag:
STMFD SP!, {R11,LR}
ADD R11, SP, #4
SUB SP, SP, #0x18
STR R0, [R11,#var_18] // R11,#var_18 is the flag
LDR R3, =aAqlbn; "AQLbN"
STR R3, [R11,#var_C] // Store "AQLbN" to R11,#var_C
LDR R3, =asc_1D250; "-="
STR R3, [R11,#var_10] // Store "-=" to R11,#var_10
LDR R3, [R11,#var_18]
LDRB R3, [R3] // Load first byte from flag / flag[0]
MOV R1, R3
MOV R2, R1 // R2 = first byte from flag
MOV R2, R2,LSL#1
ADD R2, R2, R1
MOV R3, R2,LSL#6
SUB R3, R3, R2
MOV R3, R3,LSL#1
ADD R3, R3, R1
MOV R3, R3,LSL#1
MOV R2, R3
LDR R3, [R11,#var_18]
ADD R3, R3, #9
LDRB R3, [R3] // R3 = flag[9]
ADD R3, R2, R3
LDR R2, =0x1225C
CMP R3, R2 // compare R3 with 0x1255c
BNE loc_83F0 // if same jump to second section , if
not same jump to fail section

Second Section

LDR     R3, [R11,#var_18]
ADD R3, R3, #1
LDRB R2, [R3] // R2 = flag[1]
LDR R3, [R11,#var_18]
ADD R3, R3, #8
LDRB R3, [R3] // R3 = flag[8]
EOR R3, R3, R2
AND R3, R3, #0xFF
MOV R3, R3,LSL#1
CMP R3, #0xE // compare R3 with 0xE
BNE loc_83EC // if same jump to third section , if
not same jump to fail section

Third Section

LDR     R3, [R11,#var_18]
ADD R3, R3, #8
LDRB R3, [R3] // R3 = flag[8]
LDR R2, =0x4EC4EC4F
UMULL R1, R3, R2, R3 // Multiply R2 and R3,store the most
significat 32 digit on R3
MOV R3, R3,LSR#2
AND R3, R3, #0xFF
MOV R2, R3
LDR R3, [R11,#var_18]
LDRB R3, [R3] // R3 = flag[0]
ADD R3, R2, R3
CMP R3, #0x66 ; 'f' // compare R3 with 'f'
BNE loc_83E8 // if same jump to fourth section , if
not same jump to fail section

Fourth section

LDR     R3, [R11,#var_18]
ADD R3, R3, #1
LDRB R3, [R3] // R3 = flag[1]
MOV R0, R3
LDR R3, [R11,#var_18]
ADD R3, R3, #9
LDRB R3, [R3] // R3 = flag[9]
MOV R1, R3
MOV R3, R1
MOV R3, R3,LSL#1
ADD R3, R3, R1
MOV R2, R3,LSL#3
SUB R2, R2, R3
MOV R2, R2,LSL#1
ADD R3, R2, R1
ORR R3, R0, R3
LDR R2, =0x833
CMP R3, R2 // compare R3 and R2
BNE loc_83E4 // if same jump to fifth section , if
not same jump to fail section

Fifth section

LDR     R3, [R11,#var_18]
ADD R3, R3, #7
LDRB R3, [R3] // R3 = flag[7]
CMP R3, #0x69 ; 'i' // compare R3 with 'i'
BNE loc_83E0 // if same jump to loop section , if
not same jump to fail section

Loop Section

MOV     R3, #0                   // set initiate value for looping, R3=0
STR R3, [R11,#var_8] // save R3=0 to R11,#var_8
B loc_83D0 // jump to next instruction
LDR R3, [R11,#var_8] // Load value from R11,#var_8 and save
to R3
CMP R3, #4 // compare r3 with 4
BLE loc_8368 // if r3<=4 jump to next instruction,if
not jump to win
LDR R3, [R11,#var_8]
ADD R3, R3, #2 // R3=R3+2
MOV R2, R3 // R2=R3
LDR R3, [R11,#var_18]
ADD R3, R3, R2
LDRB R2, [R3] // R3=flag[R2] , R2 will be 2,3,4,5,6
LDR R3, [R11,#var_8]
CMP R3, #0
AND R3, R3, #1 // check odd or even ,if odd result = 1
even result = 0
RSBLT R3, R3, #0 // if r3<0 set r3=0-r3 ( absolute )
MOV R1, R3
LDR R3, [R11,#var_10]
ADD R3, R3, R1
LDRB R3, [R3] // R3=var_10[R1] , R1 will be 0,1,0,1,0
EOR R3, R3, R2
AND R2, R3, #0xFF
LDR R3, [R11,#var_8]
LDR R1, [R11,#var_C]
ADD R3, R1, R3
LDRB R3, [R3] // R3=var_C[R3] , R3 will be 0,1,2,3,4
CMP R2, R3 // compare R2 with R3
BEQ loc_83C4 // if same jump to next instruction,
if not same jump to fail section
LDR R3, [R11,#var_8]
ADD R3, R3, #1
STR R3, [R11,#var_8] // var_8=var_8+1

The next step is writing script for bruteforcing the value per section.

On the first section i got exact value for flag[0] and flag[9].

On the second section i got many possibilities for flag[1] and flag[8] , so we keep the value and go to third section.

On third section i failed to find value for flag[8] ( i think because i fail to implement umull instruction ) so i decided to go to fourth section.

On fourth section i got exact value for flag[1] and on the second section we know that flag[1] and flag[8] in pairs , so from fourth section i got value for flag[1] and flag[8]. Fifth section is the clearest section,flag[7]=’i’ .

The last is loop section , on loop section we will get values for flag[2] until flag[6]. Here is my script i used to get the flag using bruteforce method.

or you can see the full script include my comment while debugging below

Flag : d33p{b3lla_ci40}

Thank you for reading my write up !

--

--

kosong

CTF Player | Currently learning about Reverse Engineering and Cryptography