將一些C語言代碼彙編後得到的機器碼可以作爲shellcode注入到一個新的進程中去,如果執行這個新的代碼那麼就可以運行注入得到的機器指令。
比如下一段代碼:
#include <stdlib.h>
char shellcode[] = "\xeb\x19\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04"\
"\xb2\x0e\x59\xb3\x01\xcd\x80\x31\xc0\xb0\x01"\
"\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff"\
"\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c"\
"\x64\x21\x0a";
int main(int argc, char **argv) {
int (*ret)();
ret = (int(*)())shellcode;
(int)(*ret)();
exit(0);
}
如果直接編譯運行的話,結果可能就是段錯誤,比如:
$ gcc 1.c -o sc
$ ./sc
Segmentation fault (core dumped)
這是因爲shellcode是以全局字符數組變量的形式存儲在進程堆棧中的數據段中,數據段是沒有可執行權限的,所以一旦PC寄存器進入到這裏面,那麼程序就會報錯。
解決方法有兩個,一個是在gcc編譯的時候加入-z execstack參數,比如
$ gcc 1.c -o sc -z execstack
$ ./sc
Hello, World!
也可以安裝execstack這個軟件,然後在用命令將要運行的程序用execstack
-s ./prog。那麼該程序就解除可執行棧的保護了。
$ sudo apt-get install execstack
$ execstack -s ./sc
$ ./sc
$ Hello, World!
這樣就可以運行了。