1.概述
2022年5月,安全公司Malwarebytes在可能用于針對約旦政府的一份武器化文件中新發(fā)現(xiàn)了一個名為“Saitama”的惡意軟件樣本。Saitama植入軟件使用DNS隧道作為其唯一的命令和控制信道,并利用長時間睡眠和隨機(jī)化(子)域名來逃避檢測。這些特性使得即使植入程序不使用DNS over HTTPS(DoH)來加密其DNS查詢,也難以通過流量檢測到它。由于沒有該植入程序的服務(wù)器端實(shí)現(xiàn),分析人員難以對此類惡意流量的檢測效果進(jìn)行測試。
雖然某些入侵指標(biāo)可用于追溯可能的感染,但分析人員更傾向(接近)實(shí)時地檢測威脅。為了評估和調(diào)整現(xiàn)有的惡意流量檢測覆蓋范圍,需要更詳細(xì)地了解植入程序的內(nèi)部工作原理。本文將使用Saitama植入來說明惡意DNS隧道如何建立,以及這種方式如何影響檢測過程。
2.重建Saitama流量
??從受害者機(jī)器的角度來看,Saitama植入程序的行為已經(jīng)在其他地方得到了記錄。然而,為了生成植入程序行為的完整記錄,需要一個C2服務(wù)器來正確控制和指示植入程序。當(dāng)然,植入程序的實(shí)際開發(fā)人員使用的C2服務(wù)器的源代碼是無法使用的。
如果最終目標(biāo)是實(shí)時檢測惡意軟件,則檢測工作應(yīng)側(cè)重于植入程序產(chǎn)生流量的方式,而非流量發(fā)送到的特定域名。檢測方法依據(jù)的是PCAP包,通俗來說,即“要么產(chǎn)生PCAP,要么就當(dāng)什么也沒發(fā)生”。因此,在構(gòu)建檢測時,本文沒有依賴于假設(shè),而是構(gòu)建了Saitama的服務(wù)器端組件,以便能夠生成PCAP。
從攻擊者的角度來看,使用DNS作為C2通信的信道有一些好處,也有一些主要的缺點(diǎn)。雖然在許多環(huán)境中DNS確實(shí)相對不受限制,但協(xié)議本身并不是為傳輸大量數(shù)據(jù)而設(shè)計(jì)的。此外,DNS查詢的緩存特點(diǎn)迫使植入程序必須確保發(fā)送的每個DNS查詢都是唯一的,從而保證DNS查詢能夠到達(dá)C2服務(wù)器。
為此,Saitama植入程序依賴于對用于構(gòu)造DNS查詢的字符集的連續(xù)打亂。雖然這種打亂使得兩個連續(xù)的DNS查詢幾乎不可能是相同的,但它需要服務(wù)器和客戶端完全同步,以便它們以相同的方式打亂字符集(見圖1)。
圖1:服務(wù)器端與客戶端打亂字母表采用相同的方式
在啟動時,Saitama植入程序生成一個介于0和46655之間的隨機(jī)數(shù),并將其分配給一個計(jì)數(shù)器變量。客戶端使用共享密鑰(“haruto”用于此處討論的變體)和共享初始字符集(“razupgnv2w01eos4t38h7yqidxmkljc6b9f5”),對該計(jì)數(shù)器進(jìn)行編碼,并通過DNS將其發(fā)送到C2服務(wù)器。然后將此計(jì)數(shù)器用作偽隨機(jī)數(shù)發(fā)生器(PRNG)的種子。
為了對該計(jì)數(shù)器進(jìn)行編碼,植入程序依賴于名為“_IntToString”的函數(shù)(見圖2)。此函數(shù)接收一個整數(shù)和一個“基本字符串”,對于第一個DNS查詢,該字符串與上一段中標(biāo)識的初始共享字符集相同。在整數(shù)變量等于或小于零之前,函數(shù)使用該整數(shù)變量從基本字符串中選擇一個字符,并將其放置到變量“str”之前,將拼接后的字符串作為函數(shù)輸出返回。在每次循環(huán)迭代結(jié)束時,輸入數(shù)除以基串參數(shù)的長度,從而降低整數(shù)變量的值。
圖2:用于將整數(shù)轉(zhuǎn)換為編碼字符串的函數(shù)
要確定初始種子,服務(wù)器必須執(zhí)行此函數(shù)的逆運(yùn)算,以將編碼字符串轉(zhuǎn)換回其原始數(shù)字。但是,在客戶端轉(zhuǎn)換過程中,由于此轉(zhuǎn)換中的除法并未保留小數(shù),可能會導(dǎo)致信息的丟失。服務(wù)器嘗試使用簡單的乘法來完成此轉(zhuǎn)換的逆運(yùn)算。因此,服務(wù)器可能會計(jì)算出一個不等于客戶端發(fā)送的種子的數(shù)字,此時必須驗(yàn)證逆函數(shù)是否計(jì)算了正確的種子。如果不是這種情況,服務(wù)器會嘗試更高的數(shù)字,直到找到正確的種子。
一旦克服了這個障礙,服務(wù)器端實(shí)現(xiàn)的其余部分就變得微不足道了。客戶端將其當(dāng)前計(jì)數(shù)器的值附加到發(fā)送到服務(wù)器的每個DNS查詢。此計(jì)數(shù)器用作偽隨機(jī)數(shù)發(fā)生器PRNG的種子。此PRNG用于將初始字符集打亂為新字符集,然后用于對客戶端發(fā)送到服務(wù)器的數(shù)據(jù)進(jìn)行編碼。
因此,當(dāng)服務(wù)器和客戶端使用相同的種子(計(jì)數(shù)器變量)來生成偽隨機(jī)數(shù)以打亂字符集時,會得到完全相同的字符集。這允許服務(wù)器和植入程序以相同的“語言”進(jìn)行通信。然后,服務(wù)器簡單地將打亂后的字母表中的字符替換回“基本”字母表,以獲得客戶端發(fā)送的數(shù)據(jù)。
3.植入程序規(guī)避檢測的方法??
許多C2框架允許攻擊者手動設(shè)置植入程序的最小和最大睡眠時間。雖然較少的睡眠時間使攻擊者能夠更快地執(zhí)行命令和接收輸出,但較多的睡眠時間會在受害者網(wǎng)絡(luò)中產(chǎn)生較少的噪聲以規(guī)避檢測。流量檢測通常依賴于設(shè)定的一個閾值,可疑行為僅在特定時間內(nèi)發(fā)生多次時才會觸發(fā)警報。
Saitama植入程序使用硬編碼睡眠值(見圖3)。在通信期間(例如當(dāng)它將命令輸出返回到服務(wù)器時),最小睡眠時間為40秒,而最大睡眠時間為80秒。在發(fā)送的每個DNS查詢中,客戶端將選擇40到80秒之間的隨機(jī)值。此外,DNS查詢并不是每次都發(fā)送到同一個域名,而是分布在三個域名中。在每個請求中,隨機(jī)選擇其中一個域名。植入程序無法在運(yùn)行時改變睡眠時間,也無法完全“跳過”睡眠步驟。
圖3: 植入程序的睡眠配置(整數(shù)表示以毫秒為單位的睡眠時間)
這些睡眠時間和通信分布阻礙了檢測工作,因?yàn)樗鼈冊试S植入程序進(jìn)一步“融入”合法的網(wǎng)絡(luò)流量。雖然對于經(jīng)驗(yàn)豐富的研究人員來說,流量本身并不是正常的,但睡眠時間和分布使得捕獲這種惡意流量無異于大海撈針。對于攻擊者來說,選擇睡眠時間值是在保持植入程序隱蔽性和可用性之間的平衡。對于Saitama的睡眠時間,由于每個單獨(dú)的DNS查詢只傳輸15字節(jié)的輸出數(shù)據(jù),故植入程序的可用性非常低。
圖4:服務(wù)器實(shí)現(xiàn)和植入程序之間的傳輸
植入程序包含一組硬編碼命令,這些命令只能使用一個命令代碼觸發(fā),而不是將整個命令從服務(wù)器發(fā)送到客戶端。然而,由于無法知道這些硬編碼命令是否被攻擊者使用,或者作為誤導(dǎo)手段留在植入程序中,歸因與溯源受到了嚴(yán)重阻礙。此外,這些硬編碼命令的輸出仍然必須以與任何其他發(fā)送命令相同的延遲發(fā)送回C2服務(wù)器。
4.檢測DNS植入程序的方法
檢測DNS隧道一直是研究的重點(diǎn),因?yàn)檫@種技術(shù)可以以多種不同的方式實(shí)現(xiàn)。此外,通信信道的復(fù)雜性迫使攻擊者制造更多噪音,因?yàn)樗麄儽仨毻ㄟ^非專用信道發(fā)送大量數(shù)據(jù)。雖然“空閑”植入程序可能很難檢測到,因?yàn)楹苌偻ㄟ^有線介質(zhì)進(jìn)行通信,但任何DNS植入程序在開始接收命令和發(fā)送命令輸出時都必須發(fā)出更多噪聲。這些“突發(fā)”通信是可以更好地檢測DNS隧道的地方。本節(jié)將舉例說明檢測Saitama的方法和實(shí)際上對手使用的一些常見工具。
(1)基于簽名
在可能的情況下,本文的目標(biāo)是編寫基于簽名的檢測,因?yàn)檫@種檢測方法提供了堅(jiān)實(shí)的基礎(chǔ)和快速的工具溯源。如前所述,Saitama植入程序使用的隨機(jī)化域名使得基于特征的檢測在這種情況下具有挑戰(zhàn)性,但并非不可能。當(dāng)主動傳送命令輸出時,Saitama植入程序生成大量隨機(jī)DNS查詢。這種隨機(jī)化確實(shí)遵循一種特定的模式,可以用以下Suricata規(guī)則來概括:
alert dns $HOME_NET any -> any 53 (msg:”FOX-SRT – Trojan – Possible Saitama Exfil Pattern Observed”; flow:stateless; content:”|00 01 00 00 00 00 00 00|”; byte_test:1,>=,0x1c,0,relative; fast_pattern; byte_test:1,<=,0x1f,0,relative; dns_query; content:”.”; content:”.”; distance:1; content:!”.”; distance:1; pcre:”/^(?=[0-9]+[a-z]\\|[a-z]+[0-9])[a-z0-9]{28,31}\\.[^.]+\\.[a-z]+$/”; threshold:type both,track by_src, count 50, seconds 3600;classtype:trojanActivity;priority:2;reference:url,https://github.com/fox-it/saitama-server metadata:ids suricata; sid:21004170; rev:1;)
此簽名可能看起來有點(diǎn)復(fù)雜,但如果將其分解為單獨(dú)的部分,則會變得相對直觀。28-31個字符的選擇基于包含輸出的DNS查詢的結(jié)構(gòu)。首先,一個字節(jié)專用于“發(fā)送和接收”命令代碼。然后跟隨植入程序的編碼ID,該ID可以占用1到3個字節(jié)。緊接其后是2個字節(jié)專用于輸出數(shù)據(jù)的字節(jié)索引和20字節(jié)的base-32編碼輸出。最后,將發(fā)送“計(jì)數(shù)器”變量的當(dāng)前值。由于該數(shù)字的范圍在0到46656之間,因此需要1到5個字節(jié)。Suricata IDS 規(guī)則的內(nèi)容匹配如下表所示:
內(nèi)容匹配 | 行為 |
00 01 00 00 00 00 00 00 | DNS查詢標(biāo)頭。此匹配主要用于將指針放在byte_test內(nèi)容匹配的正確位置。 |
byte_test:1,>=,0x1c,0,relative; | 下一個字節(jié)應(yīng)至少為十進(jìn)制 28。此字節(jié)表示即將到來的子域名的長度 |
byte_test:1,<=,0x1f,0,relative;< p=””> | 與前一個字節(jié)相同的字節(jié)最多應(yīng)為 31。 |
dns_query; content:”.”; content:”.”; distance:1; content:!”.”; | DNS 查詢應(yīng)正好包含兩個“.”字符 |
pcre:”/^(?=[0-9][a-z]|[a-z][0-9])[a-z0-9] {28,31}\\.[^.]\\.[a-z]$/”; | DNS 查詢中的子域名應(yīng)至少包含一個數(shù)字和一個字母,并且不能包含其他類型的字符。 |
threshold:type both, track by_src, count 50, seconds 3600 | 僅當(dāng)過去3600 秒中的查詢超過 50個時才觸發(fā)。并且每3600 秒僅觸發(fā)一次。 |
(2)基于行為
使創(chuàng)建簽名變得困難的隨機(jī)化域名也對防御者有利:大多數(shù)正常DNS 查詢并非隨機(jī)。如下表所示,列出的每個黑客工具都至少有一個子域名具有加密或編碼的部分。
黑客工具 | 舉例 |
DNScat2 | 35bc006955018b0021636f6d6d616e642073657373696f6e00.domain.tld |
Weasel | pj7gatv3j2iz-dvyverpewpnnu–ykuct3gtbqoop2smr3mkxqt4.ab.abdc.domain.tld |
Anchor | ueajx6snh6xick6iagmhvmbndj.domain.tld |
Cobalt Strike | Api.abcdefgh0.123456.dns.example.com 或 post. 4c6f72656d20697073756d20646f6c6f722073697420616d65742073756e74207175697320756c6c616d636f206420646f6c6f7220616c69717569702073756e7420636f6d6f646f20656975736d6f642070726.c123456.dns.example.com |
Sliver | 3eHUMj4LUA4HacKK2yuXew6ko1n45LnxZoeZDeJacUMT8ybuFciQ63AxVtjbmHD.fAh5MYs44zH8pWTugjdEQfrKNPeiN9SSXm7pFT5qvY43eJ9T4NyxFFPyuyMRDpx.GhAwhzJCgVsTn6w5C4aH8BeRjTrrvhq.domain.tld |
?Saitama | 6wcrrrry9i8t5b8fyfjrrlz9iw9arpcl.domain.tld |
遺憾的是,DNS查詢中的隨機(jī)性檢測本身并不是一個可靠的指標(biāo),無法在不產(chǎn)生大量誤報的情況下檢測DNS隧道。然而,DNS隧道的第二個限制是DNS查詢只能承載有限數(shù)量的字節(jié)。要成為有效的C2通道,攻擊者需要能夠發(fā)送多個命令并接收相應(yīng)的輸出,從而導(dǎo)致較短時間內(nèi)集中產(chǎn)生了大量的查詢。
這基于行為的檢測的第二步:簡單地計(jì)算被分類為“隨機(jī)化域名”的唯一查詢的數(shù)量。這些集中產(chǎn)生的大量查詢在細(xì)節(jié)上因使用工具而異,但一般來說,兩個查詢之間沒有空閑時間或空閑時間很少。而Saitama是一個例外,它在兩個查詢之間有40到80秒的均勻分布的睡眠時間,這意味著平均有一分鐘的延遲。60秒的預(yù)期睡眠是確定閾值的直觀開始。如果我們聚合超過一小時,預(yù)計(jì)平均將有60個查詢分布在3個域名上,在50%的情況下,一小時內(nèi)的查詢少于60次。
圖5:模擬出的查詢操作的均勻隨機(jī)觀測值之和近似正態(tài)分布(1h)
為了確保檢測結(jié)果,無論隨機(jī)睡眠時間如何,都可以利用均勻隨機(jī)觀測值之和近似正態(tài)分布這一事實(shí)。通過這種分布計(jì)算出產(chǎn)生可接受概率的查詢數(shù)。如圖5所示,該值可取為53(此數(shù)字因檢測工具而異,并非內(nèi)置閾值。不同工具的不同閾值可用于平衡誤報)。保險起見,為了涵蓋可能的數(shù)據(jù)包丟失和其他意外因素,在簽名和其他規(guī)則中此值可取為50。
總之,將對隨機(jī)出現(xiàn)的DNS查詢的檢測與每小時隨機(jī)類DNS查詢的最小閾值相結(jié)合,可以成為檢測DNS隧道的有效方法。分析人員在測試中發(fā)現(xiàn)仍然存在一些誤報,例如由防病毒解決方案引起的誤報。因此,最后還要為已驗(yàn)證為正常的域名創(chuàng)建一個排除列表,以防止正常域名產(chǎn)生的誤報。
雖然還可以使用更復(fù)雜的檢測方法,但該方法已經(jīng)足夠強(qiáng)大(至少足以捕獲該惡意軟件),更重要的是,該方法易于在網(wǎng)絡(luò)傳感器或SIEM等不同平臺以及各種類型的日志上使用。
5. 結(jié)論
當(dāng)出現(xiàn)新的惡意軟件時,分析人員的核心工作應(yīng)該在于確保現(xiàn)有的檢測工作在新遇到的威脅上能夠正確觸發(fā)。雖然某些入侵指標(biāo)可用于追溯尋找可能的感染,但研究人員更傾向(接近)實(shí)時地檢測威脅。本文概述了作者如何開發(fā)植入程序的服務(wù)器端實(shí)現(xiàn),以創(chuàng)建植入程序行為的正確記錄,最終用于檢測工程目的。
強(qiáng)隨機(jī)化(如在Saitama植入程序中觀察到的)顯著阻礙了基于簽名特征的檢測。本文通過檢測其規(guī)避方法(在本例中為隨機(jī)化)來檢測威脅。正常的DNS流量很少由隨機(jī)出現(xiàn)的子域名組成,當(dāng)看到這種情況在以前看不到的域名中大量出現(xiàn)時,很可能是出現(xiàn)了惡意流量。
參考鏈接:https://blog.fox-it.com/2022/08/11/detecting-dns-implants-old-kitten-new-tricks-a-saitama-case-study/
來源:國家網(wǎng)絡(luò)威脅情報共享開放平臺