syncopation HTB business ctf
Table of Contents
Syncopation
This is a challenge from the HTB Business CTF in July 2021.
The user has to enter a “killswitch”, when this switch is correct, it is equivalent to the flag.
The challenge was solved using binary ninja in the normal graph disassembly view. At the end of the article there is also a high level IL view of the flag comparison function.
This is a very short first post for this blog and hopefully not too many details are left out.
After reading in the user input a comparison function at 0x400677 is called to compare the stored flag with the user input.
The cyan colored blocks have one real instruction and the rest is for moving forward inside the code. These instructions are colored orange in the screenshot. On the right hand side of the first screenshot the high level graph view of this function is visible. In that view most code is marked as cyan while part is marked as orange and only the orange parts are really relevant tot the challenge. These orange lines will be later extracted as separate code for easier readability.
This next screenshot shows the end of the cyan blocks and the comparison block (a lot of cyan single instruction block have been left out).
The jump construct
Add ida picture and describe it
Extracting only the orange lines results in the following code for the loop(some annotations included):
GET THE CURRENT CHAR IN USER INPUT
eax, dword ptr [rbp-0x34 {index}]
movsxd rdx, eax
mov rax, qword ptr [rbp-0x48 {userInput}]
add rax, rdx
movzx eax, byte ptr [rax]
mov byte ptr [rbp-0x36 {currentUserInputChar}], al
GET CURRENT CHAR IN FLAG BLOCK
mov edx, dword ptr [rbp-0x34 {index}]
mov eax, edx
shl eax, 0x2 // index = index * 4
add eax, edx // index = index + index = index * 4 + index = 5 * index
movzx eax, byte ptr [rax+0x400a00] // load address of stored flag block
mov byte ptr [rbp-0x35 {checkBlockChar}], al
COMPARE THE CHARS
movzx eax, byte ptr [rbp-0x36 {currentUserInputChar}]
cmp al, byte ptr [rbp-0x35 {checkBlockChar}]
jz 0x400807 // restart loop and increase index by one
What can be seen from the code above is, that it gets the character at the current index for the user input and for the flag. Those two characters are than compared, if they are identical the loop continues until all characters have been compared, otherwise the comparison ends.
As an addition here is a high level IL view from binary ninja:
This high level view also makes it clear that there is a loop of lenght 0x1d that compares the user_input[index] to the flag_block[5*index]. (The flag_block starts at 0x400a00)
The referenced flag block looks like the following hex:
Flag
Taking every 5th character out of this with a loop of 0x1d(29 decimal) results in the following string: HTB{4_r4th3r_0ffb34t_b1n4ry!}