[英]Testing Shellcode From C - Bus Error 10
下面,我寫了打印'Hello,World!'的x64程序集。 來自Mac OS X 10.8上的系統調用。 它獨立執行時匯編並運行完美。
; 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!'
我遇到的問題是當我嘗試從ac程序運行此代碼作為shell代碼時。 我使用otool獲取以下機器操作碼。
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";
以下是我用來執行此操作的程序。 但我一直收到一個總線錯誤: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;
}
當我逐步使用gdb時,我將執行傳遞給shellcode時得到KERN_PROTECTION_FAILURE。
更新的問題:
以上是由Carl Norum解決的,這是由於記憶保護。 我有一個不同的問題,但與上面類似。 我沒有將shell代碼放在同一個文件中,而是想從.txt文件中讀取shell代碼並執行它。 下面我嘗試將一段內存標記為PROT_EXEC,並將.txt文件的內容讀入其中並執行。 但是它不起作用,我得到了同樣的錯誤,KERN_PROTECTION_FAILURE,我嘗試使用mprotect和mmap將一段內存標記為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;
}
這是我正在讀的text.txt文件,它是同一個hello world代碼:
\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。
您的程序嘗試從標記為“ execute disable ”的內存頁面執行shellcode,這是數據部分中內存的默認值。 這就是你看到KERN_PROTECTION_FAILURE
的原因。 您需要將shellcode放在文本部分:
__attribute__((section("__TEXT,__text")))
char code[] = ...
這樣做之后,你的程序運行正常:
$ clang -Wall -Wextra -pedantic -O2 example.c -o example
$ ./example
Hello, World!
編者注:你的函數指針調用不需要類型轉換。 只是ret();
會沒事的。 你需要至少擺脫(int)
部分進行編譯而不發出警告。
編輯:
這是一個無需你做部分覆蓋體操的程序:
#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;
}
示例運行:
$ clang -O2 -Wall -Wextra example.c -o example
$ ./example
Hello, World!
$ gcc -O2 -Wall -Wextra example.c -o example
$ ./example
Hello, World!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.