srop

signal机制

signal机制是类unix系统中进程之间相互传递信息的一种方法。一般,我们也称之为软中断信号,或者软中断。比如说进程之间可以通过系统调用kill来发送软中断信号。一般分为三大步

1.内核会向某个进程发送signal机制,改进程会被暂时挂起,进入内核态

2.内核会为该进程保存相应的上下文,跳转到之前注册好的signal handler中处理signal

3.signal返回

4.内核为进程恢复之前保留的上下文,恢复进程的执行

内核会为进程保存相应的上下文,主要是将所有寄存器压入栈中以及压入signal信息 以及指向sigreturn的系统调用地址。此时栈的结构如下图所示,我们称ucontext以及siginfo这一段为Signal Frame。需要注意的是,这一部分是在用户进程的地址空间的。之后会跳转到注册过的signal handler中处理相应的signal。因此,当signal handler执行完之后,就会执行sigreturn代码

1
2
3
4
5
6
7
#unix signals
+++++++++++++
| stack |
| uncontext |
| siginfo |
| sigreturn | <---- sp
+++++++++++++

获取shell

首先,我们假设攻击者可以控制用户进程的栈,那么它就可以伪造一个Signal Frame , 如下图所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
0x00    rt_sigreturn        uc_flags
0x11 &uc uc_stack.ss_sp
0x20 uc_stack.ss_flags uc_stack.ss_size
0x30 r8 r9
0x40 r10 r11
0x50 r12 r13
0x60 r14 r15
0x70 rdi = &"/bin/sh" rsi
0x80 rbp rbx
0x90 rdx rax = 59(execve)
0xA0 rcx rsp
0xB0 rip = &syscall eflags
0xC0 cs/gs/fs err
0xD0 trapno oldmask(unused)
0xE0 cr2(segfault addr) &fpstate
0xF0 _reserved sigmask

当系统执行完sigreturn系统调用之后,会执行一系列的pop指令以便于恢复相应寄存器的值,当执行到pop rip时,就会把程序执行流指向syscall,根据相应寄存器的值,此时。便会得到一个shell.

system call chains

需要指出的时,上面的例子中,我们只是单独的得到一个shell,有时候,我们可能会希望执行一系列的函数,我们只需要做两处修改即可

1.控制栈指针

2.把原来rip指向的syscall gadget换成syscall;ret gadget

这样每次syscall返回的时候,栈指针都会指向下一个Signal Frame,因此可以执行一些系列的sigreturn函数调用

后续

需要注意的是,我们在构造ROP攻击的时候,需要满足下面的条件

1.可以通过栈溢出来控制栈的内容

2.需要知道相应的地址

1
2
3
4
/bin/sh
Signal Frame
syscall
sigreturn

需要有足够大的空间来塞下整个sigl frame