Write-up for the Pentestit.ru lab Reverse flag.
The lab is available under https://lab.pentestit.ru/ address. This series deals with 12th installment of the challenge. It is a CTF laboratory with total of 16 flags to find. In the following series each post will deal with one token. I’ll be be publishing them along with solving these challenges.
Disclaimer: I’m not a reverse engineering expert and such analysis is rather out of my usual scope of interest. There are probably better places to learn it than this post. Also I hope my analysis isn’t too laughable for any actual specialists. Anyway, any feedback is welcome, as usual :)
Getting access to repository allowed us to download a bin file. It looks like an executable:
# file bin
bin: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=119ea32cf92d114f4c938989562717e2451414d9, not stripped
Let’s fire up IDA pro to analyze the file. Main function looks simple enough:
Main function first prints out “PASSWORD: “ text using printf function:
Then it reads up to 32 characters from stdin using scanf:
Then, it calls function check_pw, sending input string as an argument. Depending on the result of the function (stored in eax register) it prints out “Access granted” or “Access denied”.
Now let’s analyze the check_pw function:
I have taken the liberty to rename key variables to show their purpose in the function. As we can see the method is basically a loop. The i variable is a counter and is used to iterate through the password string. First the i variable is compared with 31. If it’s less or equal it jumps to beginning of loop body. That ensures that that entire loop will execute exactly 32 times, checking all 32 character from password:
If the loop has executed 32 times, it is ended and 1 is stored as result of the function in eax register before returning (which will result in displaying “Access granted” in the main function):
If the counter didn’t reach desired value, the loop body is fired. It first reads i-th character from the password and stores it in the edx register:
Now comes the most complicated part. From what I understood, the program uses every eight value from ws array and uses it to calculate position of another character of actual password obfuscated among random characters in the is array. Finally it is stored in the eax register:
Here comes the most interesting bit for us. Now the eax and edx registers are compared:
If the characters match, counter is incremented and execution is redirected back to the beginning of the loop:
Otherwise, the loop is terminated and zero is returned from the function, which will result in “ACCESS DENIED” display:
How can we use that knowledge? We can set a breakpoint on characters compare instruction (cmp dl, al) and run the program giving it any password as input. When it hits the breakpoint, value of the eax register will be a code for i-th character of the actual password. Then we need to set edx register to match eax so the loop continues to execute. If we repeat that process 32 times we will know entire password! The password is obviously a REVERSE flag. As usual I won’t include entire flag, but here’s an example for first character:
As we can see, the first character in the password is 0x62 (which is lowercase b). In the rdx register there’s 0x41, as I’ve send only uppercase A’s as input. Now, all we need to do is set rdx value to 0x61 and continue the program. It’ll give up another letter from the password.
That’s it! We’ve got a reverse flag! We used IDA pro software to analyse a binary program logic. We identified where actual comparison of password characters takes place. Then we used dynamic analysis to break the program on the comparison and read password characters from the register.