srop介绍
当程序进行syscall系统调用是,程序会保存当前寄存器的状态,等到系统调用完成时,程序会恢复寄存器状态,而保存寄存器状态的这段内存叫做signal frame
系统调用完成后时通过执行sigreturn来恢复寄存器状态的
signal frame是可读可写,因此我们可以改变signal frame里的寄存器状态伪造sigframe进而主动执行sigreturn从而控制每个寄存器
signal frame的结构 (来自ctf-wiki)
使用前提
能够主动去系统调用sigreturn,控制rax的值使其对sigreturn系统调用(可以通过read的返回值控制rax)
知道binsh的地址,在栈上要泄露栈地址
有足够长的溢出空间能够写下signal frame
有syscall的地址能够跳转到此处
pwntools进行srop
pwntools中有伪造signal frame的工具
1 | sigframe = SigreturnFrame() |
利用SigreturnFrame()类来伪造signal frame 注意大小写
此处伪造的是 execve('/bin/sh,0,0')
没有赋值的寄存器值默认设置为0,注意设置好rip寄存器,使其执行完后直接跳转到syscall
一次srop只能调用一次syscall
若能想办法指向syscall ret 则可以控制rsp进行一系列的sigreturn调用
实例
来源:[CISCN 2019华南]PWN3 | NSSCTF
64位nx保护,main直接调用vuln
一读一写,因此可以在劫持返回地址的同时泄露栈地址
返回地址继续返回到vuln,第二次执行再写入binsh
程序中有个mov rax,0xf; ret因此可以直接在第二次执行vuln的时候返回地址劫持为此处就可以进行sigreturn的系统调用了
exp
1 | from pwn import* |