CSAPP Attack Lab
Attack Lab 的内容通过缓冲区溢出漏洞进行代码注入或者 ROP 攻击。
Level 1
调用touch1
即可。
观察getbuf
函数:
1 | 4017a8: 48 83 ec 28 sub $0x28,%rsp |
发现分配了0x28
的缓冲区,缓冲区之后就是原本存放返回值的位置,我们只需要覆盖这个返回值即可。
看一下touch1
的地址为4017c0
,用小端法写入,因此答案为:
1 | 00 00 00 00 00 00 00 00 |
Level 2
调用touch2
函数,并且需要将 cookie 作为一个数字参数传入函数。
进行代码注入,注入的代码的内容是:将touch2
的地址0x4017ec
入栈,之后ret
的时候就跳转到此;再将 cookie 的值赋给%rdi
即可,写成汇编:
1 | pushq $0x4017ec |
调用以下命令:
1 | gcc -c code2.s |
得到如下结果:
1 | 0: 68 ec 17 40 00 pushq $0x4017ec |
再去调试一下程序,断点设在0x4017bd
,也就是getbuf
函数的ret
处,看一下%rsp
的值:
1 | (gdb) print /x $rsp |
给上述代码分配 16 字节的位置,因此这段代码的起始地址为0x5561dc90
。
最后汇总起来得到答案为:
1 | 00 00 00 00 00 00 00 00 |
Level 3
调用touch3
函数,并且需要将 cookie 的 ASCII 码作为一个字符串参数传入函数。即 cookie 的内容必须提前写在栈里,传入的时候将其地址作为参数。
因为在hexmatch
的过程中会分配超过 110 字节的栈空间,如果 cookie 保存在小于%rsp
的地址,就会被覆盖掉,因此有两种解决方案:
- 把
%rsp
减掉一点,腾出至少 9 字节的空间放 cookie,但是这种方法容易产生段错误,不太清楚原因。 - 直接放在大于
%rsp
的位置。
第二种方法比较直接,因此还是和上一部分差不多,先把touch3
地址0x4018fa
入栈,然后把%rsp+8
的地址取出来放到%rdi
中即可。
直接放反汇编的结果:
1 | 0: 68 fa 18 40 00 pushq $0x4018fa |
cookie 的 ASCII 表示形式可以看man ascii
对照表来计算,注意字符串末尾要有一个 0。
答案为:
1 | 00 00 00 00 00 00 00 00 |
Level 4
利用 ROP 的方法调用touch2
。
根据提示,可以通过popq
的 gadget 从栈中取出一个值到寄存器中,因此栈中的内容为指令地址和数据的混合。在 farm 中找到的popq
只有58
,也就是popq %rax
,比如这个地方:
1 | 00000000004019a7 <addval_219>: |
地址为4019ab
,之后把 cookie 的值写到这个地址后面,程序在getbuf
中先跳转到4019ab
,之后%rsp
指向 cookie 的地址,执行popq
之后%rsp
指向下一个 gadget。
下一个 gadget 应当把%rax
的值赋给%rdi
,找到:
1 | 00000000004019c3 <setval_426>: |
地址为4019c5
,指令为movq %rax,%rdi
。
最后再跳转到touch2
的地址,因此答案如下:
1 | 00 00 00 00 00 00 00 00 |
Level 5
利用 ROP 的方法调用touch3
。
首先是要把%rsp
的值存到%rdi
中,但是因为mov
指令不像pop
指令会更新%rsp
的地址,如果在mov
指令的地址后面跟着 cookie 字符串,下一次ret
就会到一个奇怪的位置。
同样还有hexmatch
会覆盖栈的问题,因此需要把 cookie 字符串存到最后面,之后通过给%rsp
的指针加一个偏移量来给出 cookie 字符串的地址。这个把我卡了好久,最后找到了:
1 | 00000000004019d6 <add_xy>: |
这个就可以做加法了,那么现在就是怎么把%rsp
的值转到%rdi
,栈中pop
出来的偏移量从%rax
转到%rsi
,找到了下面这些:
401a06
,movq %rsp,%rax
:
1 | 0000000000401a03 <addval_190>: |
4019c5
,movq %rax,%rdi
:
1 | 00000000004019c3 <setval_426>: |
4019ab
,popq %rax
上个阶段用过。
4019dd
,movl %eax,%edx
:
1 | 00000000004019db <getval_481>: |
401a34
,movl %edx,%ecx
:
1 | 0000000000401a33 <getval_159>: |
401a27
,movl %ecx,%esi
:
1 | 0000000000401a25 <addval_187>: |
做加法之后再将结果从%rax
转到%rdi
,还是用4019c5
。
然后写touch3
的地址,最后跟上 cookie 字符串,然后根据这些指令算一下字符串的位置相对于第一个movq %rsp,%rax
的偏移量,放到popq %rax
指令之后即可。答案为:
1 | 00 00 00 00 00 00 00 00 |
总结
做完之后回看一下感觉难度也没有那么大,因为对过程的调用和返回机制的理解深刻很多,其中最后一个阶段难度跨度比较大,writeup 中还写了一大段强调“你已经拿了 95 分了,很高了,如果不是时间多闲得慌就不用往下做了”,挺有意思。
CSAPP Attack Lab