手把手教你在PE文件中植入無法檢測的後門(下)

傳送門


【技術分享】如何在PE文件中植入完全無法檢測的後門(上)

前言


在上篇中,我們已經成功創建了一個新的Section Header,並將我們的Shellcode放在其中,劫持了執行流到我們的Shellcode,運行後再返回到應用程序的正常功能。而在本文中,我們在此基礎上繼續討論如何來實現反病毒軟體軟體的低檢測率,真正做到標題所說的「完全無法檢測的後門」。

7. 如何通過用戶交互和Codecave來觸發Shellcode


在這一小節中,我們將結合兩種方法來實現低檢測率,並有效改善新增Section Header方法的諸多缺點。具體要討論的技術如下:

如何基於用戶和特定功能的交互,觸發我們的Shellcode。

如何查找和使用Codecave。

7.1 Codecave

Codecave(代碼洞)是指在程序運行時內存中的死塊(Dead block)或空塊(Empty block),可以用來注入我們自己的代碼。相比於創建一個新的Section,我們完全可以使用現有的Codecave注入我們的Shellcode。幾乎在任何PE中都能找到不同大小的Codecave。並且,Codecave的大小十分關鍵,我們希望能在找到一個比Shellcode大的Codecave,這樣我們就能順利注入Shellcode,而不必再將其分成多個小塊。

第一步,是要找到一個Codecave。Cave Miner是一個非常好用的Python腳本,可以方便地幫助我們找到Codecave,該腳本需要我們提供所需的大小,隨後就會自動查找並顯示大於該值的全部Codecave。

在這裡,我們發現有兩個Codecave大於700位元組,這兩處足夠讓我們注入Shellcode。我們需要記下虛擬地址(vaddress),虛擬地址就是其起始地址,隨後我們將通過跳轉到虛擬地址來實現執行流的劫持。

然而,如圖中所示,現在找到的這兩個Codecave都僅僅是可讀的。為了讓它能執行我們的Shellcode,就必須要讓它可讀、可寫以及可執行,這一點我們使用LordPE來實現。

7.2 通過用戶交互觸發Shellcode

進展到這裡,我們已經有了一個可以跳轉到的Codecave,接下來需要找到一種方法去通過用戶的交互將執行流重定向到我們的Shellcode上。與前面的方法不同,我們現在並不希望在程序一運行後就劫持執行流。我們希望的是,讓程序正常運行,並在用戶進行特定功能的交互操作時再執行Shellcode,例如在點擊某個選項卡的時候。

為了實現這一點,我們需要在應用程序中查找引用字元串。然後,我們可以通過修改一個特定的引用字元串的地址,來跳轉到Codecave。這就意味著,每當在內存中訪問一個特定的引用字元串的地址時,執行流都會被重定向到我們的Codecave。讓我們具體來研究一下如何去實現。

在Ollydbg中打開7zip程序,右鍵點擊,選擇「Search for」,選擇「All reference text strings」。

在引用字元串中,我們發現了一個有趣的字元串,一個域名:http://www.7-zip.org。當用戶點擊「About(關於)」——「Domain(網站)」時,該域的內存地址就會被訪問。

在這裡,我們可以在單個程序中設置多個用戶交互觸發器。舉例來說,我們使用上圖中的「網址」按鈕,該按鈕的正常功能是點擊後在瀏覽器中打開7zip的官網。而我們的目標則是,用戶在點擊該按鈕後,能觸發我們的Shellcode。

現在,我們必須要在域名字元串的地址添加一個斷點,藉此來修改其操作碼,讓用戶在點擊按鈕的時候能跳轉到我們的Codecave中。我們複製域名字元串的地址0044A8E5並添加一個斷點。然後,我們點擊7zip程序中的域名按鈕。隨後,執行就會在斷點處停止,如下圖所示:

現在,我們可以修改這個地址,讓它能跳轉到Codecave,這樣一來,當用戶點擊該按鈕時,執行流會跳轉到我們的Codecave,再然後會執行我們的Shellcode。

此外,我們還複製0044A8E5後面的指令,因為我們希望在執行完Shellcode後執行流能返回這裡,繼續運行其正常的功能。

在修改為JMP 00477857之後,我們將可執行文件另存為7zFMUhijacked.exe。請注意,地址00477857是Codecave1的起始地址。

我們在Ollydbg中載入7zFMUhijacked.exe,讓其正常執行,隨後點擊該域名按鈕,我們就被重定向到了一個空的Codecave中。

接下來,為了保持文章的簡潔,我們在這裡略過「添加Shellcode」和「修改Shellcode」這兩個步驟,因為這和之前6.2、6.3中所講解的方法一致。

7.3 生成Shell

在我們添加和修改Shellcode,並將執行流恢復到我們此前劫持的0044A8E5位置後,將其保存為7zFMUhijackedShelled.exe。該Shellcode使用的是Stageless Windows reverse TCP。我們設置一個netcat監聽器,運行7zFMUhijackedShelled.exe,並點擊網站按鈕。

一切如我們所料,現在又得到了一個Shell。接下來再看看殺毒軟體的檢測情況如何?

還不錯,這回檢測率從16/36下降到了3/38。這完全要歸功於通過用戶在特定功能內的交互行為和Codecave來觸發Shellcode的方法。同時也暴露了大部分反病毒檢測原理的弱點——如果一個已知且未經編碼的msfvenom Shellcode,位於Codecave中並且在用戶交互過程中觸發,它們就不能再被檢測出來。

3/38的檢測率確實不錯,但還沒有達到我們在標題中所說的「完全無法檢測」,因此我們還要繼續進行探索。還記得在最開始,我們自行加了一些限制,基於這些限制,我們目前似乎只能對Shellcode進行自定義編碼,並在內存中執行時對其進行解碼。

8. 自定義編碼Shellcode


在上述這些嘗試與成果的基礎之上,我們想要使用XOR編碼器去對Shellcode進行編碼。

那麼,為什麼會想到XOR呢?有下面幾個原因。首先,XOR相對容易實現。其次,我們並不需要為其編寫一個解碼器,只需要XOR兩次,就能得到原始值。

所以,我們對Shellcode進行一次XOR操作,並將其保存。然後,我們只要在運行過程中,在內存里再對編碼後的值執行一次XOR操作,就能得到原始的Shellcode。由於這個過程是在內存中完成的,所以反病毒軟體將無法捕捉到這一行為!

為此,我們就需要兩個Codecave了,一個用來放Shellcode,另一個用來放編碼/解碼器。在此前7.1的尋找過程中,我們恰好發現了兩個大於700位元組的Codecave,它們都有足夠的空間來放Shellcode和編碼/解碼器。下面是執行流的流程圖:

因此,在程序執行後,當用戶點擊域名按鈕時,執行流就會被劫持到CC2的起始地址0047972E,將執行編碼/解碼器的XOR操作,並將編碼/解碼後的shellcode存放在CC1的起始地址00477857。在CC2執行完成後,將會跳轉到CC1開始執行,會產生一個Shell。當CC1執行完成後,我們將通過CC1跳轉到最初劫持執行流的地方,也就是點擊域名按鈕的操作,以此來確保7zip的程序功能與之前仍然是一樣的。上述這些,聽起來就像是一次長途旅行。

接到消息後,我們從地址0044A8E5(單擊域名按鈕)劫持執行流到CC2的起始地址0047972E,並在磁碟上保存修改後的文件。我們再在Ollydbg中運行修改後的7zip文件,並通過單擊「域名」按鈕觸發劫持過程。

現在我們在CC2的位置,在寫XOR編碼器之前,我們首先要跳轉到CC1的起始地址並且植入我們的Shellcode,這樣我們就能夠得到XOR編碼器所需要用到的準確地址。請注意,第一步中的劫持到CC2也可以在最後執行,因為它不會影響到上面流程圖所示的整個執行流程。

我們跳轉到CC1,採用相同的操作,植入、修改Shellcode並恢復執行流到0044A8E5。由於此前已經解釋了植入、修改Shellcode和恢復執行流的方法,在此就不再贅述。

如上圖所示,這是CC1中Shellcode的最後幾行,我們記下了Shellcode結束的地址是0047799B,接下來的指令就是恢復執行流。因此,我們必須對起始地址00477859到結束地址0047799B之間的Shellcode進行編碼。

我們將CC2的起始地址移動到00477857,隨後開始編寫XOR編碼器,以下就是XOR編碼器的具體實現:

PUSH ECX, 00477857 // Push the starting address of shellcode to ECX.nXOR BYTE PTR DS:[EAX],0B // Exclusive OR the contents of ECX with key 0BnINC ECX // Increase ECX to move to next addressesnCMP ECX,0047799B // Compare ECX with the ending address of shellcodenJLE SHORT 00479733 // If they are not equal, take a short jump back to address of XOR operationnJMP 7zFM2.00477857 // if they are equal jump to the start of shellcoden

當我們在CC1中進行編碼操作時,我們必須要確保CC1所在的Header Section是可寫的,否則Ollydbg將會產生訪問衝突錯誤。使其可寫、可執行的方法已經在此前的7.1中詳細講解過。

在進行編碼後,我們在JMP 7zFM2.00477857處添加一個斷點,就會跳轉到編碼的Shellcode。如果我們此時回到CC1,就可以看到Shellcode目前均已經被編碼。

接下來,我們將CC1中的Shellcode與CC2中的編碼/解碼器全部保存,將文件命名為7zFMowned.exe。最後,讓我們來共同看看它是否可以按照預想的那樣來工作。

8.1 生成Shell

我們在Kali Box的8080埠上設置一個監聽器,在Windows環境中運行7zFMbackdoored.exe,點擊「域名」按鈕。此時,一切都按預想的那樣工作,7zip的官網頁面可以打開,我們也隨之得到了Shell。

接下來,我們再來看看反病毒軟體的檢測率如何。

9. 總結


通過本文的講解,我們已經清楚知道了在保證功能相同、大小不變的情況下,如何植入一個完全無法檢測的後門。希望本文的講解能對大家有所幫助!


推薦閱讀:

Chrome Trubofan 優化不當而導致的 RCE
常見web攻擊
金石人才培養計劃導師公布啦!——你敢說你不認識他們嗎?!
淺談DDos攻擊與防禦
網路掃黃,從技術上如何實現?

TAG:软件后门 | 网络安全 |