SROP
仅供个人学习参考
原理
signal 机制是类 unix 系统中进程之间相互传递信息的一种方法。一般,我们也称其为软中断信号,或者软中断。比如说,进程之间可以通过系统调用 kill 来发送软中断信号。一般来说,信号机制常见的步骤如下图所示:
1.内核向某个进程发送 signal 机制,该进程会被暂时挂起,进入内核态。
2.内核会为该进程保存相应的上下文,主要是将所有寄存器压入栈中,以及压入 signal 信息,以及指向 sigreturn 的系统调用地址。此时栈的结构如下图所示,我们称 ucontext 以及 siginfo 这一段为 Signal Frame。需要注意的是,这一部分是在用户进程的地址空间的。之后会跳转到注册过的 signal handler 中处理相应的 signal。因此,当 signal handler 执行完之后,就会执行 sigreturn 代码。
3.signal handler 返回后,内核为执行 sigreturn 系统调用,为该进程恢复之前保存的上下文,其中包括将所有压入的寄存器,重新 pop 回对应的寄存器,最后恢复进程的执行。其中,32 位的 sigreturn 的调用号为 **119(0x77)**,64 位的系统调用号为 15(0xf)
发现,Signal Frame可控制寄存器的值;Signal Frame 被保存在用户的地址空间中,所以用户是可以读写的。且内核与信号处理程序无关 (kernel agnostic about signal handlers),它并不会去记录这个 signal 对应的 Signal Frame,所以当执行 sigreturn 系统调用时,此时的 Signal Frame 并不一定是之前内核为用户进程保存的 Signal Frame。(内核不做检查)
64位下Signal Frame如图:
总结一下利用方式及所需条件:
1.存在栈溢出且溢出后可供写入的内存足够大
2.需要知道signal frame, sigreturn , binsh , syscall 的地址
3.栈溢出后利用rop链完成攻击
构造system call chains方式如下图所示
1.控制栈指针。
2.把原来 rip 指向的syscall gadget 换成syscall; ret gadget。
例题
360 春秋杯 smallest-pwn https://raw.githubusercontent.com/GNchen1/Pages/main/Img/smallest
查看保护
ida查看伪代码,发现没什么东西
ida查看汇编
可以看出这是一个对read函数的系统调用,相当于read(0,rsp,0x400),没有别的函数了,写入数据过大,有栈溢出机会,考虑srop
经过gdb调试,发现程序会ret到我们输入的地址上
exp如下:
1 | from pwn import * |