天天看點

Windows下免殺思路總結

1.簡介

在安全廠商日趨成熟的背景下,編寫免殺馬的難度和成本日益增長。好用新興的開源項目在短時間内就被分析并加入特征庫。筆者調研了部分開源項目,其中也有項目做了類似的分析 [1],目前能夠免殺的項目初步統計,其特征一是star數不過千,二是釋出時間不會很長。盡管以上開源測試項目已經無法免殺,也有兩種可以發展的方向,一個是學習其思想,自己實作并去特征免殺;二是改造原有項目,自己查特征、去特征,經過測試也能達到免殺。

免殺方法和思路很多,但據筆者觀察,目前免殺分為兩大流派。一是二進制流,利用彙編配合上C++,調用系統底層函數進核心的方式免殺。殺軟如果直接在使用者态檢測其行為特征會比較困難。二是新工具新項目、小衆工具流,其主要思想是尋找反病毒廠商未覆寫的方法和工具,一個是尋找新的語言工具和項目,跟廠商比速度。另一個是偏僻語言,使用者量小,廠商一直并未發現或者工作重心不在上面。舉個例子,可以用各種語言二次編譯,配合上一些語言特性如python反序列化達成免殺。通過現有工具的組合有效提高複雜度,在反病毒人員的盲區裡進行。兩種各有優劣,後續若有文章會測試更多的免殺用例。這裡推薦一個靜态免殺學習項目[2]和52pojie上的免殺項目,利用了大部分後文中提到的免殺技術[3]。

2.防毒軟體檢測方法

以下的内容多為前人總結。因為雲清除本質上也是基于特征清除,顧不單獨列出。

2.1特征碼檢測

對檔案或記憶體中存在的特征做檢測,一般的方法是做模糊哈希或者機器學習跑模型,優點是準确度高,缺點是對未知木馬缺乏檢測能力。是以目前依賴廠商的更新,廠商做的更新及時能有效提高殺軟的防護水準。目前一些殺軟對相似的病毒有一定的檢測能力,猜測是基于模糊哈希做的。部分殺軟同樣對于加殼也有檢測能力,對于不同的廠家有不同的政策,有些會對檔案進行标記,而某數字會直接告警。

2.1.1關聯檢測

檢測的特征不僅僅是惡意payload的特征,也可能是一組關聯的代碼,把一組關聯資訊作為特征。比如在使用加載器加載shellcode時,需要開辟記憶體,将shellcode加載進記憶體,最後執行記憶體區域shellcode。這些步驟就被反病毒人員提取出來作為特征,在調用了一組開辟記憶體的函數比如virtualAlloc之後對該記憶體使用virtualProtect來更改标示位為可執行并且對該記憶體進行調用就會觸發報毒。以上隻是一個簡單的例子,具體情況具體分析,部分廠商對其進行了擴充,是以現在使用另外幾個函數進行調用也無法免殺。不過其本質還是黑名單,還存在沒有被覆寫到的漏網之魚。

2.2行為檢測

行為檢測通過hook關鍵api,以及對各個高危的檔案、元件做監控防止惡意程式對系統修改。隻要惡意程式對系統資料庫、啟動項、系統檔案等做操作就會觸發告警。最後,行為檢測也被應用到了沙箱做為動态檢測,對于避免沙箱檢測的辦法有如下幾個:

  • 延時,部分沙箱存在運作時間限制
  • 沙箱檢測,對諸如硬碟容量、記憶體、虛拟機特征做檢測
  • 部分沙箱會對檔案重命名,可以檢測自身檔案名是否被更改

2.3小結

以上是對殺軟檢測做的一個小結,目前學術界對惡意代碼的檢測集中在機器學習上,已經有部分殺軟已經應用落地了,如微軟。對殺軟檢測手法更多的了解有助于我們寫免殺馬。

3.繞過技術

目前,随着cs的流行,越來越多的人使用cs的shellcode,而放棄了自己開發編寫的木馬,或者使用改造的msf馬。本篇文章也會以shellcode加載器作為例子。後續文章将會涉及更深入的内容。

3.1經典技術

經典免殺技術如下,由于篇幅所限,本篇隻含部分免殺技術。

  • 特征碼修改
  • 花指令免殺
  • 加殼免殺
  • 記憶體免殺
  • 二次編譯
  • 分離免殺
  • 資源修改
  • 白名單免殺

3.2修改特征

一個加載器存在兩個明顯的特征,一個是shellcode和寫死字元串。我們需要消除這些特征,比較友善的方案,使用base64等對上述特征進行編碼,最好使用多種編碼手段。對于shellcode,使用base64并不安全,是以更安全的方案是加密,一個簡單的異或加密就能消除shellcode的特征。第二個是加載器的關聯特征也需要消除,對于代碼中出現連續調用的virtualAlloc,virtualProtect進行插入花指令,通過加入無意義的代碼幹擾反病毒引擎。

筆者的一點想法,進一步混淆源代碼,在不加殼的情況下稍微增加靜态分析難度。也有論文提出可以使用ROP來提高代碼的分析難度,因為現存的代碼分析引擎對間接跳轉和調用的支援存在瑕疵,複雜邏輯的代碼更需要人工分析[12]。

3.3記憶體免殺

shellcode直接加載進記憶體,避免檔案落地,可以繞過檔案掃描。但是針對記憶體的掃描還需對shellcode特征做隐藏處理。對windows來說,新下載下傳的檔案和從外部來的檔案,都會被windows打上标記,會被優先重點掃描。而無檔案落地可以規避這一政策。同時申請記憶體的時候采用漸進式申請,申請一塊可讀寫記憶體,再在運作改為可執行。最後,在執行時也要執行分離免殺的政策。

3.4修改資源

殺軟在檢測程式的時候會對諸如檔案的描述、版本号、建立日期作為特征檢測[7]。可用restorator對目标修改資源檔案。

3.5隐藏IAT

每調用一個系統函數就會在導入表中存在,這對于反病毒人員是個很好的特征,直接通過檢測導入表中有沒有調用可疑函數。這裡就需要隐藏我們的導入函數。一個比較通用的辦法是直接通過getProcessAddress函數擷取所需要函數的位址。知道位址也就能直接調用,這樣整個程式内除了getProcessAddress其他函數都不會出現在IAT表中。盡管這樣已經能繞過上面的檢測,但還有種更保險的做法,用彙編從Teb裡找到kernel32.dll的位址,再從其導出表中擷取所需系統函數。

Windows下免殺思路總結

3.6分離免殺

整個shellcode加載器分為兩個部分,分離下載下傳shellcode和執行。加載器處在stage0階段,其作用除了加載大馬外并無其他作用。但是直接執行大馬會被檢測到,是以需要用到分離免殺。

Windows下免殺思路總結

通常殺軟隻檢測一個程序的行為,是以如果存在兩個惡意程序通過程序間通信就能逃過檢測、達到免殺。

分離免殺的方法多種多樣,既可以用windows的管道[4][6],也可以用socket通信[5]。

3.7二次編譯免殺

像msf或者cs的shellcode在各個廠商裡都盯的比較嚴,對于這些shellcode已經提取好特征隻要使用就會被檢測出。是以會使用各種編碼器進行免殺。編碼器有很多種,這裡僅推薦msf的shikata_ga_nai,是一種多态編碼器,每次生成的payload都不一樣。

3.7.1其他語言編譯免殺

因為各種語言特性不同,對于不同語言編寫的加載器廠商不一定第一時間跟進,導緻了一段時間内可以繞過。在2020年初的時候,使用python作為加載器[11]免殺一陣,現在針對這類加載器逐漸嚴格,導緻直接加載報毒,需要更多的混淆還改進。在2020年5月,奇安信紅隊出過一篇文章,利用python反序列化來加載python加載器[8],目前截止本文測試2021年1月已經無法使用了,是個比較好的思路。

3.8系統函數白名單免殺-uuid方式

Gamma實驗室在2021年2月3号釋出了一篇微信公衆号的文章[9],分析了Check Point Research研究的apt攻擊的文章。其中的亮點在記憶體中shellcode的編碼方式和調用都沒有使用傳統編碼和調用的方式,利用了系統函數的特性,這次的例子是uuid。使用的是系統給UuidFromStringA函數将payload的uuid數組轉化為shellcode加載進記憶體,其特點就是程式中存在大量寫死的uuid。另一個,調用使用的是EnumSystemLocalesA函數,它的第一個參數是回調函數指針,也就意味着參數一隻要傳入shellcode首位址就會執行惡意指令。現已被殺,但是這裡給出一個比較重要的思路,還有其他可以利用的Windows系統函數可以利用。另外現已經有項目實作了使用調用guid來進行免殺。

3.9某數字公布的stage uri檢測

因為cs密鑰都是寫死的,被逆向出來後,隻要使用stage分階段的方式加載cs,其流量都會被解密并能檢測其特征[10]。對抗的方式,二次打包改密鑰,或更改cs的配置檔案使得關閉stage。同時使用stageless,也得更換自己的dll,cs的beacon.dll同樣在檢測清單中。其實用改造過的msf馬也不錯,這也就是上文提到的過的開源項目,目前這個項目已經被某數字檢測了,是以需要對項目進行改造。

4.總結

以上總結了主流的免殺方式,後文的免殺就是以上技術的混合使用。本文還未涉及到諸如加殼,dll以及使用powershell免殺等,這些會在之後的文章中提出。