攻击过程
0.关闭随机地址空间的保护功能
1.编写攻击代码:
code 的值为课件上的值,这个值不一定能够使缓冲区溢出后调用到bug函数,因为我们不知道bug函数的代码会被放在哪个地址上。
2.在关闭gcc的栈保护功能下编译代码:
3.用gdb进行调试,查看main函数的汇编代码,找到调用copy后的下一指令的位置为0x0804849b
4.查看bug函数的汇编代码,找到函数开头的地址为:0x08048472
5.在调用strcpy语句处打上断点,运行程序到该语句前,查看此时esp的地址为:0xbffff0a0.
6.从栈顶开始查看栈信息,并找到函数结束后返回的地址所在的位置:
7.运行strcpy语句后,再查看栈信息,发现buf的起始地址是0xbffff0b7,与要覆盖的地址相差22个bytes:
(注意,由于漏了截图,此图是我后来改变了code值后成功攻击的图,不影响本步的分析)
到此,准备工作完成,我们得到了bug函数代码的地址。接下来就是对如何使用缓冲区溢出调用bug函数进行设计了。
8.由于buf的起始地址与要覆盖的地方相差22bytes,而要覆盖的地址占用了4个bytes,所以只要修改code的第23到26byte为bug代码的地址:0x08048472,即可达到缓冲区溢出调用bug的目的。所以code的值改为如下:
9.编译改动后的代码,运行程序,成功调用bug函数:
10.用gdb调试,断点到strcpy前,查看栈信息:
执行strcpy语句后,再查看栈信息,发现copy函数结束后返回的地址被覆盖为: 0x08048472
攻击过程中栈帧的变化
调用copy函数前,栈顶在0xbffff0d0:
进入到copy函数,在执行strcpy之前,栈顶在0xbffff0a0:
对比两个栈帧信息,在压入函数结束后的返回地址前,压入了0x0804a01c,查看这个地址的内容(下图),发现,它是实参code的地址:
因此,我们得到栈帧信息如下:
0x0804a01c(实参code的地址) |
0x0804849b(函数结束后返回的地址) |
0xbffff0e8(pre ebp) |
为bug分配的空间 |
….. ….. ….. |
esp栈顶 |
执行完strcpy后,查看栈信息,栈顶仍在0xbffff0a0:
此时,栈帧图如下:
0x0804a000(实参code的地址被改了一个byte) |
0x08048472(bug函数的地址) |
0x41414141 |
为bug分配的空间(41414141...) |
….. ….. ….. |
esp栈顶 |