测试壳牌code从C - 总线错误10 [英] Testing Shellcode From C - Bus Error 10

查看:148
本文介绍了测试壳牌code从C - 总线错误10的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面,我写64集,打印你好,世界!从在Mac OS X 10.8系统调用。它装配当执行独立运行完美。

 ;装配和链接:
; NASM -f macho64 -o HelloWorld.o HelloWorld.s
; LD -arch x86_64的-o的HelloWorld HelloWorld.o全球启动.text段开始:    推RBP
    MOV RBP,RSP    JMP短字符串    异或偏下,偏下
    MOV迪,为0x01StringRet:
    RSI流行    XOR RDX,RDX
    MOV DL,0xE    MOV R8B,0X02
    SHL R8,24
    或R8,0×04
    MOV RAX,R8    系统调用;系统调用写(4)    异或EDI,EDI    MOV R8B,0X02
    SHL R8,24
    或R8,为0x01
    MOV RAX,R8    系统调用;系统调用出口(1)    MOV RSP,RBP
    流行RBP串:    调用StringRet
    DB你好,世界!

我遇到的问题是,当我尝试从C程序运行此code作为外壳code。我用otool得到以下机器操作codeS。

  otool -t HelloWorld.o字符code [] =\\ X55 \\ X48 \\ X89 \\ xe5 \\ X41 \\ XB0 \\ X02 \\ X49 \\ XC1 \\ xe0 \\ X18 \\ X49 \\ X83 \\ xc8 \\ X04 \\ x4c
              \\ X89 \\ XC0 \\ X48 \\ X31 \\ XFF \\ X66 \\ XBF \\ X01 \\ X00 \\ XEB \\ X1E \\ x5e \\ X48 \\ X31 \\ XD2 \\ XB2
              \\ x0e \\ X0F \\ X05 \\ X41 \\ XB0 \\ X02 \\ X49 \\ XC1 \\ xe0 \\ X18 \\ X49 \\ X83 \\ xc8 \\ X01 \\ x4c \\ X89
              \\ XC0 \\ X31 \\ XFF \\ X0F \\ X05 \\ X48 \\ X89 \\ XEC \\ X5D \\ xe8 \\ XDD \\ XFF \\ XFF \\ XFF \\ X48 \\ X65
              \\ x6c \\ x6c \\ x6f \\ X2C \\ X20 \\ X57 \\ x6f \\ X72 \\ x6c \\ 64 \\ X21

和下面是我用执行该C程序。不过,我不断收到一个总线错误:10

 ;编译:
; GCC -o HelloWorldTest HelloWorldTest.c字符code [] =\\ X55 \\ X48 \\ X89 \\ xe5 \\ X41 \\ XB0 \\ X02 \\ X49 \\ XC1 \\ xe0 \\ X18 \\ X49 \\ X83 \\ xc8 \\ X04 \\ x4c
              \\ X89 \\ XC0 \\ X48 \\ X31 \\ XFF \\ X66 \\ XBF \\ X01 \\ X00 \\ XEB \\ X1E \\ x5e \\ X48 \\ X31 \\ XD2 \\ XB2
              \\ x0e \\ X0F \\ X05 \\ X41 \\ XB0 \\ X02 \\ X49 \\ XC1 \\ xe0 \\ X18 \\ X49 \\ X83 \\ xc8 \\ X01 \\ x4c \\ X89
              \\ XC0 \\ X31 \\ XFF \\ X0F \\ X05 \\ X48 \\ X89 \\ XEC \\ X5D \\ xe8 \\ XDD \\ XFF \\ XFF \\ XFF \\ X48 \\ X65
              \\ x6c \\ x6c \\ x6f \\ X2C \\ X20 \\ X57 \\ x6f \\ X72 \\ x6c \\ 64 \\ X21诠释的main()
{
    INT(* RET)();    RET =(INT(*)())code;    (INT)(* RET)();    返回0;
}

当我使用gdb步我得到KERN_PROTECTION_FAILURE权当执行传递给shell code。

更新问题:

以上是由卡尔·Norum时解决,这是由于内存保护。我有不同的问题,但类似于以上。而不是在同一个文件壳code,我想读一个.txt文件外壳code和执行它。下面我试着打标内存PROT_EXEC一节并读取.txt文件的内容到它并执行。但它不会工作,我得到了同样的错误,KERN_PROTECTION_FAILURE,我尝试使用mprotect的MMAP和标记为PROT_EXEC内存部分。

 的#include<&stdio.h中GT;
#包括LT&; SYS / mman.h>
#包括LT&;&string.h中GT;
#包括LT&;&stdlib.h中GT;INT(* RET)();无符号字符* BUF;诠释的main()
{
    FILE *文件;
    文件= FOPEN(的text.txt,RB);    unsigned int类型LEN = FTELL(文件);    BUF =(字符*)malloc的(LEN);
    FREAD(BUF,1,LEN,文件);    FCLOSE(文件);    则mprotect(安培; BUF,LEN,PROT_EXEC);   //我也试过mmap的,但同样的错误。
   / *无效* PTR = MMAP(0,1024,PROT_EXEC,MAP_ANON | MAP_PRIVATE,-1,0);    如果(PTR == MAP_FAILED)
    {
        PERROR(MMAP);
        出口(-1);
    }    的memcpy(PTR,BUF,1024); * /    RET = BUF;    RET();    返回0;
}

这是文件──test.txt文件,我读,它同样的hello world code:

<$p$p><$c$c>\\x55\\x48\\x89\\xe5\\xeb\\x33\\x48\\x31\\xff\\x66\\xbf\\x01\\x00\\x5e\\x48\\x31\\xd2\\xb2\\x0e\\x41\\xb0\\x02\\x49\\xc1\\xe0\\x18\\x49\\x83\\xc8\\x04\\x4c\\x89\\xc0\\x0f\\x05\\x31\\xff\\x41\\xb0\\x02\\x49\\xc1\\xe0\\x18\\x49\\x83\\xc8\\x01\\x4c\\x89\\xc0\\x0f\\x05\\x48\\x89\\xec\\x5d\\xe8\\xc8\\xff\\xff\\xff\\x48\\x65\\x6c\\x6c\\x6f\\x2c\\x20\\x57\\x6f\\x72\\x6c\\x64\\x21\\x0a

由于我复制txt文件到内存PROC_EXEC的内容,我不明白为什么我得到KERN_PROTECTION_FAILURE。


解决方案

您程序试图从内存执行shell code分页标记的执行禁用的,这是用于在数据段存储器中的缺省值。这就是为什么你看到 KERN_PROTECTION_FAILURE 。你需要把外壳code在文中部分:

  __ __属性((节(__文本,文本__)))
字符code [] = ...

这样做之后,你的程序正常工作:

  $铛-Wall -pedantic -Wextra -O2 example.c -o例子
$ ./example
你好,世界!

编者按:你不需要在你的函数指针调用类型转换。刚 RET(); 将被罚款。你需要摆脱至少(INT)部分没有出现警告编译。

编辑:

下面是不需要你做的部分,覆盖体操工作的程序:

 的#include&LT; SYS / mman.h&GT;
#包括LT&;&inttypes.h GT;
#包括LT&;&unistd.h中GT;字符code [] =\\ X55 \\ X48 \\ X89 \\ xe5 \\ X41 \\ XB0 \\ X02 \\ X49 \\ XC1 \\ xe0 \\ X18 \\ X49 \\ X83 \\ xc8 \\ X04 \\ x4c
              \\ X89 \\ XC0 \\ X48 \\ X31 \\ XFF \\ X66 \\ XBF \\ X01 \\ X00 \\ XEB \\ X1E \\ x5e \\ X48 \\ X31 \\ XD2 \\ XB2
              \\ x0e \\ X0F \\ X05 \\ X41 \\ XB0 \\ X02 \\ X49 \\ XC1 \\ xe0 \\ X18 \\ X49 \\ X83 \\ xc8 \\ X01 \\ x4c \\ X89
              \\ XC0 \\ X31 \\ XFF \\ X0F \\ X05 \\ X48 \\ X89 \\ XEC \\ X5D \\ xe8 \\ XDD \\ XFF \\ XFF \\ XFF \\ X48 \\ X65
              \\ x6c \\ x6c \\ x6f \\ X2C \\ X20 \\ X57 \\ x6f \\ X72 \\ x6c \\ 64 \\ X21 \\ X0A诠释的main()
{
    INT(* RET)()=(INT(*)())code;
    void *的网页=(无效*)((uintptr_t形式)code和;〜(为getpagesize() - 1));    则mprotect(页,sizeof的code,PROT_EXEC);    RET();    返回0;
}

运行示例:

  $铛-O2 -Wall -Wextra example.c -o例子
$ ./example
你好,世界!
$ GCC -O2 -Wall -Wextra example.c -o例子
$ ./example
你好,世界!

Below, I written x64 assembly that prints 'Hello, World!' from a syscall on Mac OS X 10.8. It assembles and runs perfect when executed standalone.

; Assemble and link with:
; nasm -f macho64 -o HelloWorld.o HelloWorld.s
; ld -arch x86_64 -o HelloWorld HelloWorld.o

global start

section .text

start:

    push rbp
    mov rbp, rsp

    jmp short String

    xor rdi, rdi
    mov di, 0x01

StringRet:
    pop rsi

    xor rdx, rdx
    mov dl, 0xE

    mov r8b, 0x02
    shl r8, 24
    or r8, 0x04
    mov rax, r8

    syscall            ; System call for write(4)

    xor edi, edi

    mov r8b, 0x02
    shl r8, 24
    or r8, 0x01
    mov rax, r8

    syscall            ; System call for exit(1)

    mov rsp, rbp
    pop rbp

String:

    call StringRet
    db 'Hello, World!'

The problem I'm having is when I try to run this code as shell code from a c program. I used otool to get the following machine opcodes.

otool -t HelloWorld.o

char code[] = "\x55\x48\x89\xe5\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x04\x4c"
              "\x89\xc0\x48\x31\xff\x66\xbf\x01\x00\xeb\x1e\x5e\x48\x31\xd2\xb2"
              "\x0e\x0f\x05\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x01\x4c\x89"
              "\xc0\x31\xff\x0f\x05\x48\x89\xec\x5d\xe8\xdd\xff\xff\xff\x48\x65"
              "\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21";

And below is the c program I'm using to execute this. But I keep getting a Bus error: 10.

; Compile:
; gcc -o HelloWorldTest HelloWorldTest.c

char code[] = "\x55\x48\x89\xe5\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x04\x4c"
              "\x89\xc0\x48\x31\xff\x66\xbf\x01\x00\xeb\x1e\x5e\x48\x31\xd2\xb2"
              "\x0e\x0f\x05\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x01\x4c\x89"
              "\xc0\x31\xff\x0f\x05\x48\x89\xec\x5d\xe8\xdd\xff\xff\xff\x48\x65"
              "\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21";

int main()
{
    int (*ret)();

    ret = (int(*)())code;

    (int)(*ret)();

    return 0;
}

When I step through with gdb I get KERN_PROTECTION_FAILURE right when execution is passed to the shellcode.

Updated Question:

The above was solved by Carl Norum, it was due to memory protection. I have a different problem but is similar to above. Instead of having the shell code in the same file, I want to read the shell code from a .txt file and execute it. Below I tried marking a section of memory as PROT_EXEC and read the contents of the .txt file into it and execute. But it won't work, I'm getting the same error, KERN_PROTECTION_FAILURE, I tried using mprotect and mmap to mark a section of memory as PROT_EXEC.

#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>

int (*ret)();

unsigned char* buf;

int main()
{
    FILE* file;
    file = fopen("text.txt", "rb");

    unsigned int len = ftell(file);

    buf = (char*)malloc(len);
    fread(buf, 1, len, file);

    fclose(file);

    mprotect(&buf, len, PROT_EXEC);

   // I also tried mmap, but same error.
   /*void *ptr = mmap(0, 1024, PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);

    if (ptr == MAP_FAILED)
    {
        perror("mmap");
        exit(-1);
    }

    memcpy(ptr, buf, 1024);*/

    ret = buf;

    ret();

    return 0;
}

This is the text.txt file I'm reading in, its the same hello world code:

\x55\x48\x89\xe5\xeb\x33\x48\x31\xff\x66\xbf\x01\x00\x5e\x48\x31\xd2\xb2\x0e\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x04\x4c\x89\xc0\x0f\x05\x31\xff\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x01\x4c\x89\xc0\x0f\x05\x48\x89\xec\x5d\xe8\xc8\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0a

Since I'm copying the contents of the txt file into PROC_EXEC memory, I don't understand why I'm getting KERN_PROTECTION_FAILURE.

解决方案

Your program tries to execute the shellcode from a memory paged marked "execute disable", which is the default for memory in the data section. That's why you see the KERN_PROTECTION_FAILURE. You need to put the shellcode in the text section:

__attribute__((section("__TEXT,__text")))
char code[] = ...

After doing that, your program works fine:

$ clang -Wall -Wextra -pedantic -O2 example.c -o example
$ ./example
Hello, World!

Editorial note: You don't need the typecast on your function pointer invocation. Just ret(); will be fine. You'll need to get rid of at least the (int) part to compile without warnings.

Edit:

Here's a program that works without requiring you to do section-override gymnastics:

#include <sys/mman.h>
#include <inttypes.h>
#include <unistd.h>

char code[] = "\x55\x48\x89\xe5\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x04\x4c"
              "\x89\xc0\x48\x31\xff\x66\xbf\x01\x00\xeb\x1e\x5e\x48\x31\xd2\xb2"
              "\x0e\x0f\x05\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x01\x4c\x89"
              "\xc0\x31\xff\x0f\x05\x48\x89\xec\x5d\xe8\xdd\xff\xff\xff\x48\x65"
              "\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0a";

int main()
{
    int (*ret)() = (int (*)())code;
    void *page = (void *)((uintptr_t)code & ~(getpagesize() - 1));

    mprotect(page, sizeof code, PROT_EXEC);

    ret();

    return 0;
}

Example runs:

$ clang -O2 -Wall -Wextra example.c -o example
$ ./example
Hello, World!
$ gcc -O2 -Wall -Wextra example.c -o example
$ ./example
Hello, World!

这篇关于测试壳牌code从C - 总线错误10的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆