栈迁移–ROP
本次实验我们使用lab4的可执行文件。
在开始之前我们需要明确一些问题以及需要注意的地方,以下我会讲到,这也是在实验过程中我碰到的一些情况和解题关键:
-
为什么使用栈迁移?
由上图可知,程序开辟的堆栈大小是0x50字节,而read函数输入可以输入0x60字节,明显存在栈溢出的可能,不过可输入的字节数不是足够多,空间较小,不足以使我们填入足够的ROP链,所以我们需要栈迁移。 -
使用栈迁移的关键是什么?
使用栈迁移的关键在于leave
指令,其相当于move rbp rsp , pop rbp
两条指令,在每个函数运行完时最后一条指令通常为pop rbp
,接着我们将ret
指向的地址覆盖为leave
,便可以根据我们的想法,控制$rbp的内容,从而控制程序流向。 -
send
与sendline
的区别
在最开始我写的脚本中,所有的发送均用的sendline
指令,由于sendline
指令会在发送时自动添加 “/n”,即会在你的输入时多一个字节,这也导致了开始我每次填充时总会多一个"0a"的干扰,但是这也不是说sendline
没有用,只用send
便可以,有的输入函数是需要"/n"作为输入结束符的,所以发送时具体用哪种指令得视情况而定。
接下来我们讲讲getshell的实际过程:
1.终端输入 checkcsc lab4
,查看栈保护.
已知,开启了栈保护,存在地址随机化,所以我们的第一步应该是填充堆栈,找到当前$rbp中的值,计算得到此时该值与read函数输入地址的差,即求得地址偏移量,因为地址存在随机化时,偏移量是保持不变的。