Windows平台shellcode開發入門(一)

2021-07-10 05:28:17 字數 3889 閱讀 9509

本文簡要介紹shellcode開發技術及其特點。理解這些概念可以有助於我們編寫自己的shellcode。更進一步講,你可以修改現有的漏洞利用**來執行自己所需要的定製功能。

一、介紹

比方說你手頭上有乙個ie或flash playerd現成的漏洞利用**,但它只能夠開啟計算器calc.exe。但是這實際上並沒有什麼卵用,不是嗎?你真正想要的是可以執行一些遠端命令或實現其他有用的功能。

在這種情況下,你可能想要利用已有的標準shellcode,比如來自shell storm資料庫或由metasploit的msfvenom工具生成。不過,你必須先理解編寫shellcode的基本原則,才可以在自己的漏洞利用**中有效地使用它們。對於不熟悉這個術語的同學們,可以參考一下維基百科:

在計算機安全中,shellcode是一小段**,可以用於軟體漏洞利用的載荷。被稱為「shellcode」是因為它通常啟動乙個命令終端,攻擊者可以通過這個終端控制受害的計算機,但是所有執行類似任務的**片段都可以稱作shellcode。......shellcode通常是以機器碼形式編寫的。
shellcode是一段可用於漏洞利用載荷的機器碼。「機器碼」又是什麼?讓我們以下面的c**為例:

#include

intmain

()

這段c**會編譯成如下彙編**:

_main proc

push ebp

mov ebp, esp

push offset helloworld ; "hello, world!\n"

call _printf

add esp, 4

xor eax, eax

pop ebp

ret 0

_main endp

此處,我們需要注意下main程式以及對printf函式的呼叫。正如偵錯程式中突出顯示的,這些**已經編譯成機器碼:

所以,「55 8b ec 68 00 b0 33 01 … 」便是上述c**的機器碼。

二、shellcode如何應用到漏洞利用

舉乙個簡單漏洞利用的示例,乙個基於棧的緩衝區溢位漏洞。

void

exploit

(char *data)

1)向應用程式傳送長度超過20位元組的字串,其中包含shellcode。

2)由於寫入資料越過靜態分配緩衝區的邊界,棧結構遭到破壞。同時,shellcode也會被放置在棧上。

3)字串通過自定義的記憶體位址重寫棧上某塊重要資料(如儲存的eip或函式指標)

4)程式會從棧上跳轉到你的shellcode,開始執行其中的機器碼指令。

三、shellcode特點但是shellcode不能是任意的機器碼。在編寫自己的shellcode時,我們必須需要注意shellcode的一些限制:

1)不能使用字串的直接偏移。

2)不能確定函式的位址(如printf)

3)必須避免一些特定字元(如null位元組)

關於上述的每個問題,讓我們進行乙個簡短的討論。

1.字串的直接偏移即使你在c/c++**中定義乙個全域性變數,乙個取值為「hello world」的字串,或直接把該字串作為引數傳遞給某個函式。但是,編譯器會把字串放置在乙個特定的section中(如.rdata或.data)。

由於需要與位置無關的**,我們想把字串作為**的一部分,因此必須把字串儲存在棧上,正如你將在本文後續內容中所看到的。

2.函式位址

在c/c++中,呼叫某個函式非常簡單。我們利用「#include<>」指定某個標頭檔案,然後通過名稱來呼叫某個函式。編譯器和鏈結器會在背後幫你解決這個問題:解析函式的位址(例如,來自user32.dll的messagebox函式),然後我們就可以輕而易舉地通過名稱呼叫函式。

在shellcode中,我們卻不能以逸待勞了。因為我們無法確定包含所需函式的dll檔案是否已經載入到記憶體。受aslr(位址空間布局隨機化)機制的影響,系統不會每次都把dll檔案載入到相同位址上。而且,dll檔案可能隨著windows每次新發布的更新而發生變化,所以我們不能依賴dll檔案中某個特定的偏移。

我們需要把dll檔案載入到記憶體,然後直接通過shellcode查詢所需要的函式。幸運的是,windows api為我們提供了兩個函式:loadlibrary和getprocaddress。我們可以使用這兩個函式來查詢函式的位址。

3.避免空位元組

空位元組(null)的取值為:0×00。在c/c++**中,空位元組被認為是字串的結束符。正因如此,shellcode存在空位元組可能會擾亂目標應用程式的功能,而我們的shellcode也可能無法正確地複製到記憶體中。

雖然不是強制的,但類似利用strcpy()函式觸發緩衝區溢位的漏洞是非常常見的情況。該函式會逐字節拷貝字串,直至遇到空位元組。因此,如果shellcode包含空位元組,strcpy函式便會在空位元組處終止拷貝操作,引發棧上的shellcode不完整。正如你所料,shellcode當然也不會正常的執行。

上圖中的兩條指令從功能上來說是等價的,但你可以清楚地看到第一條指令包含空位元組,而第二條指令卻包含空位元組。雖然空位元組在編譯後的**中非常常見,但是我們可以很容易地避免。

還有,在一些特殊情況下,shellcode必須避免出現類似\r或\n的字元,甚至只能使用字母數字。

四、linux平台與windows平台的shellcode對比

相對於windows平台,編寫針對linux平台的shellcode可能更為簡單。這是因為在linux平台上,我們可以輕鬆地通過0×80中斷執行類似write、execve或send的系統呼叫。

例如,在linux平台上執行「hello world」shellcode只需要以下幾個步驟:

1)指定系統呼叫syscall序號(如「write」)。

2)指定系統呼叫syscall的引數(如,stdout,「hellow, world」,字串長度)

3)呼叫0x80中斷來執行系統呼叫syscall。

這將會發起呼叫:write(stdout, 「hello, world」, length).

1)獲取kernel32

.dll 基位址;

2)定位 getprocaddress函式的位址;

3)使用getprocaddress確定 loadlibrary函式的位址;

4)然後使用 loadlibrary載入dll檔案(例如user32

.dll);

5)使用 getprocaddress查詢某個函式的位址(例如messagebox);

6)指定函式引數;

7)呼叫函式。

五、結論本文是windows平台shellcode編寫入門系列的第1部分。本文介紹了什麼是shellcode,shellcode存在哪些限制,以及windows和linux平台的shellcode之間的區別。第2部分會包括簡單介紹組合語言、pe()檔案格式、peb(程序環境塊)。接下來,你會了解這些內容如何幫助你編寫自定義的shellcode。

Windows平台JxCore打包

2.解壓並配置環境變數 3.檢視環境變數配置是否成功 jx version 4.打包命令 jx package test.js test 如圖所示 test.jxp這是乙個中介軟體檔案,包含了需要編譯的完整專案資訊。test.jx 這是乙個完整包資訊的二進位制檔案,可執行在客戶端上 5.繼續在當前目...

Windows平台Adreno SDK編譯與執行

adreno sdk是高通提供的opengl開發sdk包,我們可以從裡面學習到很多opengl知識,也能夠加深對高通adreno gpu特性的了解。編譯前準備 1 進入adrenosdk development tutorials opengles目錄,我們嘗試編譯裡面的01 createwindo...

Windows平台JxCore打包

2.解壓並配置環境變數 3.檢視環境變數配置是否成功 jx version 4.打包命令 jx package test.js test 如圖所示 test.jxp這是乙個中介軟體檔案,包含了需要編譯的完整專案資訊。test.jx 這是乙個完整包資訊的二進位制檔案,可執行在客戶端上 5.繼續在當前目...