《Hardware/Software Interface》实验三 是内存攻击,通过注入多余的数据造成缓存溢出从而改变栈中的数据,进而改变进程的运行轨迹。这个实验能帮助我们加深理解函数间调用的过程以及栈空间的使用,是非常棒的一个实验。
实验环境:
Ubuntu 64位 操作系统
内存攻击
实验分为4个level ,每个level的处理过程差不多,难度整体是在上升。为了更好地理解整个实验,我们先看一下相关的内存栈知识。
stack frame
每个当前内存frame需要指出它在内存中的范围,范围的值由两个寄存器来保存,Linux64位系统中由rsp(stack pointer) 和 rbp(base pointer) 来保存。如下:
函数间的调用导致了frame的切换,当一个函数要调用另一个函数时,需要保存当前函数的返回地址等。例如:
int main()
{
printf("Type a string:");
echo();
return 0;
}
调用了 echo 的函数之后 ,栈如下:
调用echo函数前,首先保存返回到main函数的地址;进入到echo函数的frame中后,会首先保存之前的main函数frame的bp,之后保存一些相关的寄存器数据。
工具
实验还提供了多个工具方便我们的使用。
- objdump
- objdump命令是Linux下的反汇编目标文件或者可执行文件的命令. 实验中我们还会需要向缓冲区中注入汇编命令,但是汇编命令也是需要转换成二进制作为输入,那么objdump可以将我们生成的目标文件反汇编,显示出不同汇编语句对应的机器代码。
- sendstring
- 我们的输入串本身的含义可能是二进制码,但是作为输入会被计算机识别成ASCII字符然后转换,这样背离了我们的初衷,实验提供了sendstring程序来帮助我们把输入文件转成对应被计算机识别的二进制文件。
上述工具的使用说明在实验指导书中都提到了。
Level 0: Candle
每个任务开始都会调用test()方法,内部会调用getbuf(),getbuf()会继续调用函数Gets(),如下: