Pragyan had some fun challenges! There will be more writeups coming up soon for the CTF.
This binary Challenge wasn't very difficult, but the nostalgia of it was nice!
Here is the description:
Chris is trying out to be a police officer and the applications have just been sent into the police academy. He is really eager to find out about his competition. Help it him back the system and view the other applicant’s applications. The service is running at 128.199.224.175:13000
We're given a x86-64 binary with NX & Canary enabled named police_academy.
Looking in Binary Ninja, we can immediately find out a few details which will help later when running through dynamic analysis.
First, there's a simple hard-coded password check on the binary:
After this it asks for a case number using scanf, uses a jump table to load a specific data filename onto the stack ($rbp-0x30) and then prints that file using print_record:
For the strings in Binary Ninja above, one useful feature is to hit the 'r' key to convert to character constants. The same was done for the jump to the flag setup:
The flag case exits which isn't very useful for us, so time to look elsewhere.
We can see all other cases converge onto this one block:
Note it's loading the filename string at rbp-0x30, 16 bytes after the password on the stack.
It's also interesting the existence check happens after the print.
Maybe we can overflow using password to add the path of flag.txt to the string referenced on the stack.
Looking back at the initial case comparison, there's a jump above instruction which will hit 0x400cb8 if the value is above 7:
Seems like we have a good amount of information to start dynamic analysis, let's run this binary!
Breaking at the ja destination, we'll inspect the stack value for filename to see if we can overflow into it. Remember the password is stored at rbp-0x40 and the filename is stored at rbp-0x30, that's a difference of 0x10 or 16 bytes. With that, let's try the overflow in GDB:
pwndbg> b *0x400cb8 Breakpoint 1 at 0x400cb8 pwndbg> r Enter password to authentic yourself : kaiokenx20______AAAA Enter case number: 1) Application_1 2) Application_2 3) Application_3 4) Application_4 5) Application_5 6) Application_6 7) Flag Enter choice :- 9 pwndbg> x/s $rbp-0x40 0x7fffffffdf00: "kaiokenx20_____"... pwndbg> x/s $rbp-0x30 0x7fffffffdf10: "AAAA"
Looks like it worked!
Repeating the same with flag.txt doesn't seem to work for some reason, let's look back at the disassembly....
In print_record, there's a compare for the filename size to be equal to 0x24 bytes:
This next part brings the nostolgia back, with path modification to work with this buffer size. We need to make this path 0x24 bytes while preserving validity of loading flag.txt. To do this we may add a bunch of slash characters when referencing it locally, ex.:
.///////////////////////////flag.txt
Combining this with our password, we get the following:
kaiokenx20______.///////////////////////////flag.txt
Running the binary with this password and a large > 7 (or underflowed negative) value for case number we drop the flag:
Enter password to authentic yourself : Enter case number: 1) Application_1 2) Application_2 3) Application_3 4) Application_4 5) Application_5 6) Application_6 7) Flag Enter choice :- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX The flag is :- pctf{bUff3r-0v3Rfl0wS`4r3.alw4ys-4_cl4SsiC}