0xd13a

A rookie in a world of pwns

HackIT CTF 2017 Writeup: rev200

rev200

Description: You haxor, come on you little sciddie… debug me, eh? You fucking little lamer… You fuckin’ come on, come debug me! I’ll get your ass, you jerk! Oh, you IDA monkey! Fuck all you and your tools! Come on, you scum haxor, you try to reverse me? Come on, you asshole!!

Webpage: rev200.zip

The attachment is a Windows DLL. Let’s open it in IDA and look for interesting artifacts.

efi_main function asks for a flag and then runs function algo on it:

1
2
3
4
5
6
7
8
...
.text:00000000709412AD                 lea     rcx, aEnterTheFlag ; "Enter the flag: "
.text:00000000709412B4                 call    Input
...
.text:00000000709412F5                 lea     rax, [rbp+var_A0]
.text:00000000709412FC                 mov     rcx, rax
.text:00000000709412FF                 call    algo
...

Function algo performs a bunch of permutations on flag’s characters and then compares it to correct constant (which is 40 32-bit integers long, one per each flag’s character):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
.text:00000000709411FF                 lea     rdx, correct
.text:0000000070941206                 mov     rcx, rax
.text:0000000070941209                 call    memcmp
.text:000000007094120E                 test    eax, eax
.text:0000000070941210                 jnz     short loc_70941220
.text:0000000070941212                 lea     rcx, Format     ; "\nCorrect\n"
.text:0000000070941219                 call    Print
.text:000000007094121E                 jmp     short loc_7094122C
.text:0000000070941220 ; ---------------------------------------------------------------------------
.text:0000000070941220
.text:0000000070941220 loc_70941220:                           ; CODE XREF: algo+19F
.text:0000000070941220                 lea     rcx, aWrong     ; "\nWrong\n"
.text:0000000070941227                 call    Print
...

Skipping the encoding algorithm details, here is the summary:

  • For each of the 20 characters in the first half the flag: XOR with 0xC, add 6, XOR with 0xD, add 7, XOR with 0xE, add 8
  • For each of the 20 characters in the second half the flag: XOR with 0xF, add 9, XOR with 0x10, add 10, XOR with 0x11, add 11

A small script will help automate the decoding:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
data = bytearray(open("rev200.efi","rb").read())

enc1 = lambda c : (((((c ^ 0xC) + 6) ^ 0xD) + 7) ^ 0xE) + 8
enc2 = lambda c : (((((c ^ 0xF) + 9) ^ 0x10) + 10) ^ 0x11) + 11

out = ""

for x in range(20):
	for z in range(0x7F):
		if (data[0x5400 + x*4] == enc1(z)):
			out += chr(z)
	
for x in range(20):
	for z in range(0x7F):
		if (data[0x5400 + 80 + x*4] == enc2(z)):
			out += chr(z)
	
print out

Running the script gets us the flag h4ck1t{ff77af3cf8d4e1e67c4300aeb5ba6344}:

1
2
$ python solve.py 
h4ck1t{ff77af3cf8d4e1e67c4300aeb5ba6344}