Testing Shellcode From C - Bus Error 10
assembly, c, macos, shellcode
Solution
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!
Problem
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.