信号与栈-SROP 原理分析
warning
免责声明
本文所述 PWN 均属 CTF(Capture The Flag)参赛行为或赛前训练行为.笔者所 PWN 的对象均为 CTF 比赛或练习中平台方提供的靶机.
本文意在分享网络安全与 CTF 相关技术与技巧,共同提升实力.
请本文读者谨记相关法律法规与政策.读者需为自身行为承担相应的法律后果.笔者(Y7n05h)不为读者的行为承担责任.
Signal 原理
相信各位师傅对 Signal
都有一些了解.Signal
作为一种 *nix 的异步通知方式,在 *nix 的系统编程方面十分常见.
本文将分析信号处理函数调用过程中的简单流程,并尝试部分 SROP 利用.
笔者使用如下程序分析 signal
机制.
1 |
|
通过编译运行本程序,并使用终端向程序发送 SIGUSR1
信号,触发信号处理函数 func
.
在这个简单的实验中,能看到:
1 | main:0x7ffdd6510440 |
当信号发送时,内核将进程的 ucontext
和 siginfo
压入 用户态 的进程栈顶部,并切换至 用户态 执行 Signal Handler
,当 用户态 的 Signal Handler
返回时,执行 syscall sigreturn
,内核恢复先前保存的 ucontext
和 siginfo
,并恢复被信号中断函数的执行.
从上图中能十分清晰的看出,ucontext
和 siginfo
都保存在用户态,而且 signal_stack
并无 Canary
的保护.
下图是 x86_64 环境下,Signal Frame 的详细信息
SROP 利用
SROP 即 Sigreturn Oriented Programming.
前文已经说明了 Signal
机制所存在的安全隐患,下面来聊聊 signal_stack
的利用方式
- 如果
signal_stack
有缓冲区溢出错误,则能够从signal_stack
通过溢出修改ucontext
和siginfo
的内容,实现对寄存器的控制. - 我们还可以伪造
ucontext
和siginfo
并利用sigreturn
将伪造的数据的数据应用至寄存器中,实现对所有寄存器的控制.
目前 pwntools 已经集成了 SROP 的利用工具,能极大的方便 payload 的构造.
例题
题目:360chunqiu2017_smallest
1 | from pwn import * |
本题目是经典的 SROP 例题,本题中很巧妙的一点是利用 syscall read
写入 1 bytes 同时达成设置 rax
与 修改返回地址两个目的.
此时利用 rax == 1
调用 write
泄漏出一处可写的内存地址,在其上构造栈迁移.
Q:为什么需要这样做呢?
A:因为在后面的调用中需要 execve(sh_addr,NULL,NULL)
,只有将栈转移到已知的位置,才能确定写入的 /bin/sh\x00
字符串的地址.
其后,再次利用 syscall write
读取输入将 ‘/bin/sh\x00’ 写入,并利用偏移量计算出其地址,在最后面再次构造 signal_stack
,调用 execve
成功 getshell.
参考资料
1:Bosman E, Bos H. Framing signals-a return to portable shellcode[C]//2014 IEEE Symposium on Security and Privacy. IEEE, 2014: 243-258.
2. SROP.[G/OL].ctf-wiki.https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/advanced-rop/srop/#system-call-chains. ↩
3. 杨超.CTF竞赛权威指南.Pwn篇[M].北京:电子工业出版社. ↩