Reverse Engineering
FCaaS (0 solve)
Staged ELF, Runtime Modification, Input Validation
FCaaS
Description
Like usual flag checker. Nothing new, but now running as a service
Solution
Given ELF bit file, then open it using IDA

From the main function we can see that the program receive user input using scanf and store it on v13.

v13 values are processed with xor operation and stored in dest variable. Function sub_14bb use dest variable as argument and when we dive on the function we can see that the function actually RC4 algorithm


Since we know the key we can reimplement it on our main programming language, in this case i reimplement it on python.

The last function called on main function is executing file located on memory, we can check the syscall on link below https://github.com/torvalds/linux/blob/master/arch/x86/entry/syscalls/syscall_64.tbl

So actually the RC4 algorithm used to decrypt the actual binary that validate the flag. Here is script i use to decrypt the binary

Running the new elf we can see that there is no output but we can confirm that it is valid elf
Now the question is how can the binary validate the flag? and where is our input stored?


When we decompile the new binary we can see that there are some values that looks like our input which is gemastik2023{AA...AA}. Take a look on assembly code we can see that 0x67 or g stored on address 0x12c9

On initial binary, we found the same value (0x12c9 or 4809)


and we can confirm that v8[45] value is 0, so line 330 with j = 45 produce dest[3809] = v9[0] ^ v13[0]. Line 331 do the same thing but with different value which is dest[16176] = v13[10]^v12[9]. Checking value on address 16176 or 0x3f30 on new binary we found that it also store constant (0x41)

Now we know how is our input stored in second binary. So the next step is understanding how the second binary validate our input.

So actually there are 3 functions that process our input, so take a look on each function.



From the constant stored on each function we can confirm that those 3 function generate md5 hash. After knowing all functions we can rewrite flow like below
We know all the variable values except the input. So basically we can bruteforce each byte by validating with md5 result stored in check variable (each input can be validated with 3 bytes hash). After getting valid input on index x1 we can recover another value on index x2 and so on. Here is final script to recover the flag by bruteforcing
Flag : gemastik{you_know_the_pattern_you_got_the_flag}
Last updated