免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 39801 | 回复: 85
打印 上一主题 下一主题

【好玩】缓冲区溢出攻击实验 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-11-03 17:52 |只看该作者 |倒序浏览
这是出自《深入理解计算机系统》的一道题目:


  1. /* Bomb program that is solved using a buffer overflow attack */

  2. #include <stdio.h>;
  3. #include <stdlib.h>;
  4. #include <ctype.h>;

  5. /* Like gets, except that characters are typed as pairs of hex digits.
  6.    Nondigit characters are ignored.  Stops when encounters newline */
  7. char *getxs(char *dest)
  8. {
  9.   int c;
  10.   int even = 1; /* Have read even number of digits */
  11.   int otherd = 0; /* Other hex digit of pair */
  12.   char *sp = dest;
  13.   while ((c = getchar()) != EOF && c != '\n') {
  14.     if (isxdigit(c)) {
  15.       int val;
  16.       if ('0' <= c && c <= '9')
  17.         val = c - '0';
  18.       else if ('A' <= c && c <= 'F')
  19.         val = c - 'A' + 10;
  20.       else
  21.         val = c - 'a' + 10;
  22.       if (even) {
  23.         otherd = val;
  24.         even = 0;
  25.       } else {
  26.         *sp++ = otherd * 16 + val;
  27.         even = 1;
  28.       }
  29.     }
  30.   }
  31.   *sp++ = '\0';
  32.   return dest;
  33. }

  34. /* $begin getbuf-c */
  35. int getbuf()
  36. {
  37.     char buf[12];
  38.     getxs(buf);
  39.     return 1;
  40. }

  41. void test()
  42. {
  43.   int val;
  44.   printf("Type Hex string:");
  45.   val = getbuf();
  46.   printf("getbuf returned 0x%x\n", val);
  47. }
  48. /* $end getbuf-c */

  49. int main()
  50. {

  51.   int buf[16];
  52.   /* This little hack is an attempt to get the stack to be in a
  53.      stable position
  54.   */
  55.   int offset = (((int) buf) & 0xFFF);
  56.   int *space = (int *) alloca(offset);
  57.   *space = 0; /* So that don't get complaint of unused variable */
  58.   test();
  59.   return 0;
  60. }
复制代码


题目的要求是,在getbuf函数中也许“显然”地会返回1,通过输入一个数据使这个函数返回0xdeadbeef,就是在test函数中地printf中打印地是0xdeadbeef.

我大概有了思路,做着玩玩,晚上回来再说。

论坛徽章:
0
2 [报告]
发表于 2004-11-03 21:47 |只看该作者

【好玩】缓冲区溢出攻击实验

要是能来篇
堆的溢出或shellcode的编写就更好了
期望中......

论坛徽章:
0
3 [报告]
发表于 2004-11-03 22:40 |只看该作者

【好玩】缓冲区溢出攻击实验

思路已经想到了,还没有时间实践,分析如下:
当函数test在调用getbuf的时候,栈的分布情况大致如下:

  1. |                                    |     <- test的栈帧  (地址在高位)
  2. |为局部变量分配空间(val)      |
  3. |   其他的一些空间        |
  4. |   返回地址                     |
  5. |                                    |     <-getbuf的栈帧 (地址在低位)
  6. |为局部变量分配空间(buf变量) |
  7. |   其他的一些空间        |
  8. |   返回地址              |
  9. |                                    |
复制代码

而getbuf中的局部变量buf数组就是紧靠着getbuf栈帧的数据空间,当这个空间溢出的时候,数据就会跑到test函数的栈帧中。
看下面的test函数的汇编代码:

  1. 00000115 <_test>;:
  2. 115:        55                           push   %ebp
  3. 116:        89 e5                        mov    %esp,%ebp
  4. 118:        83 ec 18                     sub    $0x18,%esp
  5. 11b:        c7 04 24 ee 00 00 00         movl   $0xee,(%esp)
  6. 122:        e8 00 00 00 00               call   127 <_test+0x12>;
  7. 127:        e8 aa ff ff ff               call   d6 <_getbuf>;
  8. 12c:        89 45 fc                     mov    %eax,0xfffffffc(%ebp)
  9. 12f:        8b 45 fc                     mov    0xfffffffc(%ebp),%eax
  10. 132:        89 44 24 04                  mov    %eax,0x4(%esp)
  11. 136:        c7 04 24 ff 00 00 00         movl   $0xff,(%esp)
  12. 13d:        e8 00 00 00 00               call   142 <_test+0x2d>;
  13. 142:        c9                           leave  
  14. 143:        c3                           ret   
复制代码

注意到12c那一行,是把调用getbuf函数的返回值传到局部变量0xfffffffc(%ebp)中,就是val,接下来的一行就是把这个局部变量传到eax寄存器再由寄存器传到test栈帧的后面然后再调用printf函数。

我的修改思路如下,反汇编出从getbuf函数的栈帧中buf数组那部分直到test中val变量之间的代码,其他的部分不改变,改变的只有以下两个部分:
1)修改test函数的返回地址,使这个地址指向12f那一行,就是说把
mov    %eax,0xfffffffc(%ebp)这一行跳过,直接把变量val的值传到printf中
2)找到val在栈帧所在的位置,把这个位置的代码改为我们所要的,也就是0xdeadbeef.

思路大致如上面所说,明天有时间实践看看。

不知道说清楚没有,大家给点意见。

论坛徽章:
0
4 [报告]
发表于 2004-11-03 23:09 |只看该作者

【好玩】缓冲区溢出攻击实验

简而言之,修改后的test函数是这样的:

  1. void test()
  2. {
  3.   int val = 0xdeadbeef;                  //把val变量改为我们需要的值
  4.   printf("Type Hex string:");
  5.   //val = getbuf();                          //单独调用getbuf函数,不把返回值放在val中
  6.   getbuf();
  7.   printf("getbuf returned 0x%x\n", val);
  8. }

复制代码

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
5 [报告]
发表于 2004-11-04 08:42 |只看该作者

【好玩】缓冲区溢出攻击实验

在《黑客就这么几招》中有很详细的缓冲区溢出漏洞的原理和shellcode的编写。

^_^,当初在书店看到这书,本来打算翻开嘲笑一翻,因为这个名字太张扬了。不过,看了却发现,有很多废话(教授工具和讲述历史)以外,还是有些内容的。尤其将缓冲区溢出漏洞和格式化字符串漏洞的原理讲述的尤为详细。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
6 [报告]
发表于 2004-11-04 09:19 |只看该作者

【好玩】缓冲区溢出攻击实验

converse,你的思路错了。题目的意思,不是想让你覆盖val的值,这样做没有什么意义。而是想让你通过getbuf函数返回一个地址。这才是有用的。

我们能控制它返回一个值,我们就能进一步让这个值覆盖getbuf函数返回时要执行的指令。如果我们在我们控制的这个返回值的地址上,放上一个shellcode。那么就能让程序“脱轨”,而进入我们设定的“轨道”。

论坛徽章:
0
7 [报告]
发表于 2004-11-04 09:28 |只看该作者

【好玩】缓冲区溢出攻击实验

是的,现在这样看应该有很多办法实现,因为既然找到了覆盖返回时执行指令的办法就可以为所欲为了,我晚上再做做看吧。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
8 [报告]
发表于 2004-11-04 11:13 |只看该作者

【好玩】缓冲区溢出攻击实验

converse兄,你的思路还是正确的,偶刚才说错了,^_^,莫怪。

呵呵,刚才深入搞了一下,这个还真不简单。这个题要求我们溢出,让程序“脱轨”一段后,还要回到原来的“轨道”上去,继续打印出val的值。不能是像平常的溢出攻击一样,让它“脱轨”,走我们设定的“轨道”就好了。所以想了一下,要做的事情有4步:

1、计算出getbuf函数下一条指令(给val赋值)的下一条指令的地址:A。
2、计算出getbuf函数返回的栈帧的地址:B。B中原来存放的是getbuf函数下一条指令(给val赋值)的地址:C。
3、通过输入精心设计的输入串,将A(内容)写入B(地址),即用A,覆盖C,使函数返回的时候跳过给val赋值的部分。使火车“脱轨”,绕过一个“站点”后,继续回到原来的铁路上。
4、精心设计的输入串,同时也要用0x覆盖val变量,就像converse说的。

关键就在于计算A和B。A要计算出绝对的数值,B起码要计算出相对的数值。A的计算,单从程序上看,实在想不出什么办法。莫非要去分析gcc将每条指令都翻译成了什么,占多少字节?B的计算,相对比较容易,可以从在栈上分配的空间计算出来,可是,汇编了C程序分析了一下。gcc总是在分配空间的时候很“大方”,总是多让出一些字节(防止溢出攻击?),而且,郁闷的是,让出的这些空间,大小不是固定的。有的函数是8个字节,有的函数是12个字节,真是找不到规律。难道要去读gcc的源码?

搞了一上午,不能搞了。今天任务要完不成了。得去工作了。唉,晚上回来在说吧。

论坛徽章:
0
9 [报告]
发表于 2004-11-06 00:52 |只看该作者

【好玩】缓冲区溢出攻击实验

bf.JPG (116.85 KB, 下载次数: 154)

运行在 VMWare 上的 gentoo linux, 通过 xshell 访问。

运行在 VMWare 上的  gentoo linux, 通过 xshell 访问。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
10 [报告]
发表于 2004-11-06 09:44 |只看该作者

【好玩】缓冲区溢出攻击实验

哈哈哈,好啊,好啊。来,来,讲讲原理。讲讲怎么做的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP