MSWord-用欄位程式碼混淆

Editor發表於2017-11-10

MSWord-用欄位程式碼混淆

幾周前Saif El-Sherei和我在SensePost的部落格上發表了一篇關於DDE和在無需巨集的情況下在MSWord中執行命令列的文章。這篇部落格得到了比我預期多得多的關注。現在DDE已經被用在釣魚郵件和惡意軟體傳播活動中,同時也被合法的紅隊採用。隨著使用DDE進行的攻擊的快速增長,對其的檢測也開始加強,大多數防毒引擎已經有內建對DDE的基本檢測。大多數這類檢測基於Yara規則,通過在.docx和.doc文件中查詢DDE或DDEAUTO欄位實現。這讓我開始思考是否能在文件外混淆DDE。目前已經有一兩種這類嘗試出現,威脅者已經改變DDE字串的樣式,並且將其分解到多行中,如這篇文章描述: Macroless DOC malware that avoids detection with Yara rule


在這篇部落格中,我將分享我在混淆和繞過檢測方面的嘗試。希望這可以同時幫助攻擊者和防禦者。


——混淆載荷

——隱藏DDE/DDEAUTO

——防禦提示

——混淆載荷


在深入探究混淆DDE和DDEAUTO欄位程式碼的方法之前,我決定先關注混淆載荷。這樣做的原因是雙重的。首先,載荷是一段簡單的字串,而不是一段保留的欄位程式碼,這意味著混淆不太可能打破其功能性。再者,我們在載荷混淆上有更多的空間,嘗試去隱藏3個字元(DDE)比混淆255個字元有挑戰性多了。


看著我們正在處理的欄位程式碼,它感覺就像一個能發現一些更多混淆的好地方。對“list field codes word”的快速搜尋指引我們到了這篇微軟的支援文章,這篇文章包含一系列受支援的欄位程式碼,這對於我們是有幫助的。在花了一些時間瀏覽這些不同的欄位後,其中一個因其可能有幫助而引起了我的注意。這就是QUOTE欄位,它有被描述為“Quote與插入指定的文字到一個文件” 的功能。這聽起來讓我們鼓舞,因為我們正在查詢能操作載荷字串的方法,而QUOTE欄位允許操作一個字串並且將其插入到一個文件。


作為一個旁註,記住這個欄位程式碼可以被嵌入word是重要的,下面提供了一個使用QUETO欄位的例子:

{ QUOTE { IF { DATE \@ "M" } = 1 "12" "{= { DATE \@ "M" } -1 }/1/03" \@ "MMMM"} }


這裡我們嵌入了欄位程式碼,QUOTE欄位包含內部的IF欄位程式碼的結果,它反過來包含DATE或格式化的時間,基於一個公式(=)。


QUOTE欄位可以被用來提供一個字元原始值,它會自動轉換這個值到對應的字元(很不幸我沒有在發現關於這個的引用)。作為一個例子,如果我們想要去找出65這個值對應的字元,我們可以在Word裡面使用下面的欄位:

{ QUOTE 65 }


這最終會展示A而不是65,這正是我們在尋找的。我們現在可以將載荷表示為整數並且在DDE執行前讓word將它們自動轉換為字元。讓這些起作用的整個系列的欄位程式碼將會是:

{SET c "{QUOTE 65 65 65 65}"}

{SET d "{QUOTE 71 71 71 71}"}

{DDE {REF c} {REF d}}


這會有效地轉換為:

{DDE "AAAA" "GGGG"}


現在你可以發揮你的想象,並知道我們將會用相應的載荷替換AAAA和GGGG。為了讓這變得更簡單,我寫了一個快速的Python指令碼來簡單地將一個給定的字串轉化為相應的QUOTE欄位。

#!/usr/env/python

print("Converts a string to the {QUOTE} Field code")

st = raw_input("String to convert: ")

v = map(lambda y: "%s"%ord(y),st)

print("{ QUOTE %s }"%' '.join(v))


為了彈出powershell,我們現在可以使用下面的欄位程式碼:

{SET C "{QUOTE

67 58 92 92 80 114 111 103 114 97 109 115 92 92 77 105 99 114 111 115

111 102 116 92 92 79 102 102 105 99 101 92 92 77 83 87 111 114 100 46

101 120 101 92 92 46 46 92 92 46 46 92 92 46 46 92 92 46 46 92 92 119

105 110 100 111 119 115 92 92 115 121 115 116 101 109 51 50 92 92 119

105 110 100 111 119 115 112 111 119 101 114 115 104 101 108 108 92 92

118 49 46 48 92 92 112 111 119 101 114 115 104 101 108 108 46 101 120

101} "}

{DDE {REF C}  "a"}

髒連結

需要指出的一件事是DDEAUTO會在文件開啟時自動更新,正如它的名字所示。然而,並不是所有欄位都會自動更新,除非我們在文件開啟時點選“更新連結”。為了做到這點(或許有比我更好的方式),我們需要去將我們的連結標記為“髒的”或將文件設定為自動更新連結。

一旦你建立了你的.docx文件,你可以用壓縮軟體開啟這個檔案,而且你需要修改document.xml。為了標記連結為骯的並且要求更新,需要在每個開始的地方增加

w:dirty="true"。

儲存document.xml並且更新這個壓縮檔案。現在你開啟.docx,所有連結將會被自動更新。你也會接收到更為乾淨的“你是否想要自動更新”對話方塊。

MSWord-用欄位程式碼混淆

結果

最大的問題是,除了使用QUOTE外,我們達到了任何目的嗎?看起來是的。這個簡單啟動powershell的樣本(我認為word開啟powershell是惡意軟體的一個指標)在VirusTotal上只有1/59的檢出率。

MSWord-用欄位程式碼混淆

通常你能夠簡單地將.docx檔案儲存為.doc並得到相同的程式碼執行。不幸的是,在這裡你使用這種方法會在嘗試開啟.doc檔案的時候收到“錯誤!沒有指定的應用程式”,這是因為嵌入的欄位程式碼並不能正確地自動更新。可能有一種強制更新所有欄位程式碼的方法,但是我的Word知識有限,所以並不能找到一個這樣的方法。

隱藏DDE

下一個挑戰是嘗試去從現有檢測中隱藏,這包括YARA規則和對DDE連結的抽取。

YARA規則

大多數我見過的YARA規則嘗試檢測.docx文件(我關注.docx是因為它容易被修改)中instrText元素裡面的DDE和DDEAUTO其中之一或兩者。其中最早的一條YARA規則是被Nvsi Labs釋出的並且包含以下正則:

/.+?\b[Dd][Dd][Ee]\b.+?/

這在第一批惡意文件中工作得很好,但是隨後就被分解為多行的變種所繞過。我(在多行的樣本出現前)發現了另一個關於這個正則的問題,並將其報告給了Didier Stevens。當檢視Office Open XML檔案格式規範時,你會發現fldchar欄位是“複合欄位”型別,並且可以有一個額外屬性。增加這個可選屬性後既繞過了上面的YARA規則,也允許我們去使用DDE而不是DDEAUTO。這個屬性叫做dirty,這個值如果被設定為布林值的true,就會強制一次更新,正如在格式文件裡描述的“特別的,這個值被一個應用程式標記以指明它的當前結果已經不再正確”那樣。

這是和我上面在QUOTE欄位裡面使用以強制更新值的同一個屬性。為了將其加入文件,簡單地和之前那樣並且手動修改.docx即可。

正則馬上就失效了,因為它不能匹配到這個可選屬性。我向Didier提交了下列更新,這可以同時匹配到有可選屬性的情況和XML可以包含任意空格的事實。

.+?\b[Dd][Dd][Ee]\b.+?

Oletools - msodde.py

decalage2的python-oletools工具是一個我之前從未嘗試過的相當有趣的專案。它在從所有DDE“攻擊”的變種抽取DDE載荷方面工作得非常好。如果我們使用它來抽取我們的QUOTE版本,抽取出的DDE連結是清晰的,而且我們仍然可以知道DDE是存在的。

MSWord-用欄位程式碼混淆

這需要稍微多一點的工作,但是你可以很容易地解碼這些QUOTE值到可被執行的字串。我們該如何繞過它呢?

回到Office Open XML檔案格式規範(我喜愛規範),我們得知存在另一個我們可以使用來引用欄位程式碼的元素。從上面使用到現在的是都是fldchar的“Complex Field”欄位,然而,還有一個“簡單欄位”的版本叫做:fldSimple。fldSimple元素並沒有與fldchar相同的子元素,它事實上將欄位作為一個屬性包含;w:instr="FIELD CODE"。

來自規範文件的例子如下:

Rex Jaeschke

這給了我們能自動執行的DDE,並且繞過了Oletools:

MSWord-用欄位程式碼混淆

我向oletools推送了更新去檢測嵌入在fldSimple元素裡面的DDE連結。

這在對抗防毒引擎方面也相當不錯

MSWord-用欄位程式碼混淆

記住基於行為的防毒引擎應當能檢測到這種型別的載荷執行,所以這些結果應該被視為“繞過靜態掃描。”

副作用

當使用fldSimple時會帶來一些副作用。如果你決定去使用DDEAUTO並且包含w:dirty="true",在想要執行DDE應用程式之前,終端使用者會被提示3次(不清楚為什麼會有3次而不是2次)。這確實因為這你有3次他們點選“是”的機會而不是像通常一樣。

有趣的是當使用fldSimple和c:\\windows\\system32\\cmd.exe /k powershell啟動powershell時,powershell將會在cmd視窗內被執行,而不是直接啟動powershell控制檯。這和你從已存在的cmd例項中啟動powershell是一樣的行為。並且你會收到一則“不能載入PSReadLine模組”的訊息。控制檯執行時沒有PSReadline”(截圖)。也許有人會對深入研究這一點有興趣?

MSWord-用欄位程式碼混淆

沒有DDE

現在,最後的勝利將會是在文件中完全沒有DDE或DDEAUTO,這可能嗎?這是肯定的,而且有甜化社會工程方面的額外好處。MSWord會足夠友好去詢問使用者關閉保護模式以檢視文件內容。

為了這一點,我們可以濫用另一個遺留特性(難道這些還不夠好嗎)。在某個時間點Word變成了一個任何相關文字的一站式商店,這包括建立網頁。Word在某個點上是一個HTML的IDE,HTML從來不漂亮但是它能工作。大約在這個時間點被引入的事物是frames和framesets。Frames允許你去載入不同的HTML/Text頁面到word的內部frames,HTML會自動解析和轉換成Word格式的內容。這個功能似乎在Word 2016的使用者介面中已被移除(也許更早),但是下層的處理例程還在。這意味這你可以建立一個嵌入frames的文件,Word將會仍然為你解析。

為了插入一個frameset,你需要回去編輯一個新的.docx文件。首先解壓,然後開啟webSetting.xml。然後你需要去新增新的XML元素frameset:

這應當進入已存在的元素,就在元素前面。接下來你將需要在rId1中增加對我們文件連結到外部文件的連結。這通過增加一個叫webSettings.xml.rels的新檔案到word/_rels/來實現。

這個文件的內容應當如下:

xmlns="http://schemas.openxmlformats.org/package/2006/relationships">

當你的目標是包含DDE的.docx文件時。在這個例子裡我們將要去從位於x.x.x.x的http伺服器去載入樣本.docx檔案。儲存所有修改/建立的檔案,並且更新.docx壓縮檔案。現在你可以傳送到修改過的文件到你的目標,他們將會開啟它。因為它有mark of the web標記,所以會在保護模式下開啟。然而,因為Word檢測到檔案需要外部內容以正確顯示,內容會被顯示為“連結文件和另外功能已被禁止。要還原這個功能,你必須去編輯該文件”——注意這是來自Word的預設提示,我們無法控制這個。

MSWord-用欄位程式碼混淆

只要保護模式被禁止,Word就會下載包含我們DDE的外部文件。這將不會收到“mark of the web”標記並且被Word解析。觸發正常的DDE訊息。這是一個在避免被防毒軟體掃描到的情況下偷渡我們的DDE載荷的相當有用的方式。

防禦

最好的防禦似乎就是禁止自動更新連結,這種方法並不依賴防毒軟體。更改你的office設定去忽略連結和保護自動更新這些的操作步驟被Will Dormannn - @wdormann建立,並且在這裡可以訪問到:https://gist.github.com/wdormann/732bb88d9b5dd5a66c9f1e1498f31a1b。

我超想嘗試的另一個機制是在Windows 10秋季創意者更新版本里面引入的Defender Exploit Guard:https://docs.microsoft.com/en-us/windows/threat-protection/windows-defender-exploit-guard/attack-surface-reduction-exploit-guard 。這個機制的美妙之處在於你可以防止Word/Excel/Powerpoint派生子程式。這應該不僅能停止這類攻擊,而且也能停止DDE和內嵌的OLE。需要記住的是,Matt Nelson - @enima0x3已經證明Outlook和Access都沒有被註冊到ASR。

如上面提到的,我對oletools的專案中有一次更新的提交請求,而且大多在wordDDE或者DDEAUTO存在時能觸發的YARA規則仍能起作用。如果你正在尋找像powershell這樣的字串的話,你有必要更新一下你的邏輯了 ;)

本文由看雪翻譯小組 銀雁冰 編譯,來源staaldraad@Jordan Bowman 轉載請註明來自看雪社群

相關文章