文档详情

《深入理解计算机系》缓冲区漏洞.pdf

发布:2018-05-16约3.54万字共19页下载文档
文本预览下载声明
《深入理解计算机系统》3.38 题解——缓冲区溢出攻击实例 1. 问题描述 在这个问题中,你要着手对你自己的程序进行缓冲区溢出攻击。前面我们说过,我们不能原谅用这种或其他形式的攻击来 获得对系统的未被授权的访问,但是通过这个联系,你会学到许多关于机器级编程的知识。 从CS:APP 的网站上下载文件bufbomb.c,编译它创建一个可执行文件。在bufbomb.c 中,你会发现下面的函数。 1 int getbuf() 2 { 3 char buf[12]; 4 getxs(buf); 5 return 1; 6 } 7 8 void test() 9 { 10 int val; 11 printf(Type Hex string:); 12 val = getbuf(); 13 printf(getbuf returned 0x%x\n, val); 14 } 函数getxs (也在bufbomb.c 中)类似于库函数gets,除了它是以十六进制数字对的编码方式读入字符的以外。比如 说,要给它一个字符串0123,用户应该输入字符串“30 31 32 33”。这个函数会忽略空格字符。回忆一下,十进制数 字x 的ASCII 表示为0x3x。 这个程序的典型执行是这样的: Unix./bufbomb Type Hex string: 30 31 32 33 getbuf returned 0x1 看看getbuf 函数的代码,看上去似乎很明显,无论何时被调用,它都会返回值1。看上去就好像调用getxs 没有产生 效果一样。你的任务是,只简单地对提示符输入一个适当的十六进制字符串,就使getbuf 对test 返回-559038737 (0xdeadbeef)。 下面这些建议可能会帮助你解决这个问题: o 用objdump 创建bufbomb 的一个反汇编版本。仔细研究,确定getbuf 的栈帧是如何组织的,以及溢出 的缓冲区会如何改变保存的程序状态。 o 在gdb 下运行你的程序。在getbuf 中设置一个断点,并运行到该断点。确定像%ebp 的值这样的参数, 以及已保存的当缓冲区溢出时会被覆盖的所有状态的值。 o 手工确定指令序列的字节编码是很枯燥的,而且容易出错。可以用工具来完成这个工作,写一个汇编代码 文件,包含想要放入栈中的指令和数据。用gcc 汇编这个文件,再用objdump 反汇编它,就可以获得要在提示符 处输入的字节序列了。当objdump 试图反汇编你文件中的数据时,它会产生一些看上去非常奇怪的指令,但是十 六进制字节序列应该是正确的。 要记住,你的攻击是非常依赖于机器和编译器的。当运行在不同的机器上或使用不同版本gcc 时,可能需要改变你的字符 串。 笔者注: o 题目摘自《深入理解计算机系统》(中文版)第200 页。 o bufbomb.c 文件下载地址 /public/ics/code/asm/bufbomb.c 2. 目标分析与题解 看源程序可以发现,好像无论输入什么数据,其返回结果都是1,打印出来的都是0x1,似乎无从下手。另外,我们攻击 的目标只是让其返回0xdeadbeef,不干别的。 实验环境:Winxp + cygwin + gcc(3.4.4) 2.1 修改源程序? 这是题目不允许的。题目的要求是输入一些数据,使其输出为0xdeadbeef。输入什么样的数字串?这就是本题要求解 的。 2.2 如何得到这个数字串? 如果了解程序的编译、链接、执行的过程即可知道,此题不是无解。 由《过程调用与栈帧》一文可知,过程调用时要将参数和返回地址压入栈中,然后进入被调过程执行,待从被调过程返回 时,弹出返回地址,将该地址存入%eip 寄存器,并转到该地址开始执行。入栈和出栈均是对%esp 指向的内存操作,其基 地址为%ebp。 假设,如果我们输入的是机器码,存放于该缓冲区中,注意到程序中的缓冲区只有12 字节,利用缓冲区溢出,将本应存 放test 调用getbuf 的返回地址的内存单元修改为存放可执行的机器码的地址,而这个地址就是我们的缓冲区地址,那 么在调用完getbuf 后会返回到缓冲区地址处执行我们输入的机器码,在机器码中让程序输出oxdeadbeef,并正确返回 继续执行。这样会不会达到目标? 这句话有些拗口,总结来讲,就是将存放test
显示全部
相似文档