attacklab-rtarget(未完成)
写在前面
和ctarget不同,rtarget程序引入了常见的栈保护机制,如栈随机化,使得程序运行的地址是不确定的。这样便无法通过注入代码(写指令)的方式攻击程序。
但是办法总比困难多。有些人想出了一个叫“断章取义”的办法来攻击程序。即在指令集中截取某一部分指令(掐头不去尾),这部分指令的意思可能会发生变化,然后我们就利用这部分现有的指令去攻击程序。
以官方文档给出的例子为例:
1 | 400f15: c7 07 d4 48 89 c7 movl $0xc78948d4,(%rdi) |
如果只截取48 89 c7
这段指令的话,那么我们就生成了一个全新的指令:movq %rax, %rdi
实验作者已经把这些可能有帮助的指令全都放到了rtarget的start_farm
和mid_farm
中间。
1 | 0000000000401994 <start_farm>: |
实验文档中也提供了一些指令的组合:
movq S, D
popq R
movl S, D
nop R, R
Leval1
要求和ctarget的第二阶段一模一样,要使得rdi=cookie。
题目提示我们可以用popq
指令来解决问题, 而且只需要两条指令就可以实现效果。
popq
会执行以下两条指令:
1 | movq (%rsp), %rax |
可惜无法找到popq %rdi
对应的机器码。但是我们能找到popq %rax
对应的58 + c3
(地址是4019ab)和movq %rax, %rdi
对应的48 89 c7 + c3
(地址是4019a2)。把这两段拼起来就能达到我们想要的效果了!
首先是这一段指令:
1 | ab 19 40 00 00 00 00 00 /* 覆盖返回地址 */ |
覆盖原先的返回地址,到达0x4019ab这个地方执行指令。但是在这个时候,rsp
指针指向的地址是返回地址加8的位置,因为getbuf
的ret指令会将rsp+8(别忘了写代码的地方也是一个函数getbuf
,函数返回时会调用ret指令)。这就让rsp成功指向我们存放cookie的地方。
当popq的时候,就会把cookie存放到rax里面。接着的指令是90
,跳过,接着是c3
也就是执行ret指令,返回写代码的地方。
然后:
1 | A2 19 40 00 00 00 00 00 |
跳到这个地方执行movq指令,把rax里面的东西存放到rdi里面。然后ret。
最后:
1 | EC 17 40 00 00 00 00 00 |
跳转到touch2函数所在地址。
总结
这中间rsp的位置到底指向哪里非常的绕,需要对popq, retq有一定的理解才能看懂。