【Day 28】Cmd 指令很乱,主办单位要不要管一下 (下) - Cmd 指令混淆

环境

  • Windows 10 19043
  • System Monitor v13.01

前情提要

【Day 27】Cmd 指令很乱,主办单位要不要管一下 (上) - Cmd 指令混淆我们说明了指令混淆的用处与侦测方法,也介绍一些指令混淆的技巧,这篇要继续介绍更多混淆的技巧。

Cmd 混淆技巧

括弧(Parentheses)

括弧中的指令会被当作是一组指令,无意义的括弧可以用来混淆指令,以下举个例子。

# cmd /c (  (powershell))
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

这个混淆技巧可以绕过动态侦测,如下图 Sysmon 日志。

逗号与分号

,; 在指令中可以取代空白作为指令参数之间的分割字元,它们可以任意被插入在参数之间需要空白的地方,以下用 netstat 举例。

# cmd;;,,/c,;netstat

Active Connections

这个混淆技巧可以绕过动态侦测,如下图 Sysmon 日志。

Call

call 在 Cmd 指令中用来执行另一段指令,虽然它本身不是用来做混淆的,但是却可以让混淆的行为更低调。首先看看下面的例子,可以观察到例子中用 && 串接两个指令,第一个设定环境变数,第二个印出环境变数。然而在没有 callcmd /c 的情况下,直接 echo 不会把环境变数转成设定的值,因为同个 Cmd.exe Session 不会自动转换环境变数。

# cmd /c "set test=net&&echo %test%"
%test%

# cmd /c "set test=net&&call echo %test%"
net

# cmd /c "set test=net&&cmd /c echo %test%"
net

callcmd /c 都会转换环境变数,但是两者的差别在於 call 不会产生 Child Process;而 cmd /c 会。因此使用 call 会比 cmd /c 更低调。

For-Loop Encoding

与 For Loop Value Extraction 不同,For-Loop Encoding 不会使用 Tokens、Delims 的方式拼凑出指令,而是直接写 For 回圈把需要的字元从环境变数的目标 Index 取出。

首先先来看看指令中 For 的用法,以下的例子会把 (0 1 2 3) 照顺序印出来。

# cmd /c "for %a in (0 1 2 3) do echo %a"

# echo 0
0

# echo 1
1

# echo 2
2

# echo 3
3

也可以在 For 回圈後加入条件判断,以下例子判断如果目前回圈跑到的值为 a 就印出 haha

# cmd /c "for %a in (0 1 2 a) do if %a==a (call echo haha) else (call echo %a)"

# if 0 == a (call echo haha )  else (call echo 0 )
0

# if 1 == a (call echo haha )  else (call echo 1 )
1

# if 2 == a (call echo haha )  else (call echo 2 )
2

# if 3 == a (call echo haha )  else (call echo 3 )
3

# if a == a (call echo haha )  else (call echo a )
haha

以上的 For 回圈使用方法再配上前面环境变数的混淆技巧,就可以做到把指令混淆的效果。以下例子最终会执行 netstat /ano。先设两个环境变数 finaluniquefinal 会存放最终要执行的指令,一开始是空的。接着回圈的每一轮都会从 unique 取出一个字元并添加在 final 後面。最後会判断目前回圈跑到的 Index 是否为 a,是的话就 call %final% 执行指令。

# cmd /c "set final= &&set unique=nets /ao&&for %a in (0 1 2 3 2 6 2 4 5 6 0 7 a) do if %a==a (call %final%) else (call set final=%final%%unique:~%a,1%)

# if 0 == a (call %final% )  else (call set final=%final%%unique:~0,1% )

# if 1 == a (call %final% )  else (call set final=%final%%unique:~1,1% )

# if 2 == a (call %final% )  else (call set final=%final%%unique:~2,1% )

# if 3 == a (call %final% )  else (call set final=%final%%unique:~3,1% )

# if 2 == a (call %final% )  else (call set final=%final%%unique:~2,1% )

# if 6 == a (call %final% )  else (call set final=%final%%unique:~6,1% )

# if 2 == a (call %final% )  else (call set final=%final%%unique:~2,1% )

# if 4 == a (call %final% )  else (call set final=%final%%unique:~4,1% )

# if 5 == a (call %final% )  else (call set final=%final%%unique:~5,1% )

# if 6 == a (call %final% )  else (call set final=%final%%unique:~6,1% )

# if 0 == a (call %final% )  else (call set final=%final%%unique:~0,1% )

# if 7 == a (call %final% )  else (call set final=%final%%unique:~7,1% )

# if a == a (call %final% )  else (call set final=%final%%unique:~a,1% )

Active Connections

这个混淆技巧可以绕过动态侦测,如下图 Sysmon 日志。

Reversal

这个混淆技巧也是使用 For 回圈,不过参数中会使用 /L,用法有点像 Python 的 in range(),使用者可以自己定义回圈的范围。以下例子使用 For 回圈从 3 开始,每次减 1,直到 0 为止,每次回圈都会印出目前的数字。

# cmd /c "for /L %a in (3 -1 0) do echo %a"

# echo 3
3

# echo 2
2

# echo 1
1

# echo 0
0

知道 for /L 的使用方法之後,直接看看它用来混淆的例子。我们设一个环境变数 revnetstat /ano 的反转字串,然後用 For 回圈从最後一个字元开始往回一一添加在环境变数 final 後。当回圈跑到 0 时就执行 %final%

# cmd /c "set final= &&set rev=ona/ tatsten&&for /l %a in (11 -1 0) do call set final=%final%%rev:~%a,1%&&if %a==0 call %final%

# call set final=%final%%rev:~11,1%  && if 11 == 0 call %final%

# call set final=%final%%rev:~10,1%  && if 10 == 0 call %final%

# call set final=%final%%rev:~9,1%  && if 9 == 0 call %final%

# call set final=%final%%rev:~8,1%  && if 8 == 0 call %final%

# call set final=%final%%rev:~7,1%  && if 7 == 0 call %final%

# call set final=%final%%rev:~6,1%  && if 6 == 0 call %final%

# call set final=%final%%rev:~5,1%  && if 5 == 0 call %final%

# call set final=%final%%rev:~4,1%  && if 4 == 0 call %final%

# call set final=%final%%rev:~3,1%  && if 3 == 0 call %final%

# call set final=%final%%rev:~2,1%  && if 2 == 0 call %final%

# call set final=%final%%rev:~1,1%  && if 1 == 0 call %final%

# call set final=%final%%rev:~0,1%  && if 0 == 0 call %final%

Active Connections

上面这个例子已经让人眼花撩乱了,不过还可以更混淆一点。for /L 後面接的范围每次不一定只能递减 1,可以递减任意值。所以原本的环境变数 rev 是放 netstat /ano 的反转字串,现在可以在指令之间塞入混淆用的字元。以下例子把原本的 rev 字串的每个字元之间插入 X,并把 for /L 的递减值改为 2。

# cmd /c "set final= &&set rev=oXnXaX/X XtXaXtXsXtXeXn&&for /l %a in (22 -2 0) do call set final=%final%%rev:~%a,1%&&if %a==0 call %final%

# call set final=%final%%rev:~22,1%  && if 22 == 0 call %final%

# call set final=%final%%rev:~20,1%  && if 20 == 0 call %final%

# call set final=%final%%rev:~18,1%  && if 18 == 0 call %final%

# call set final=%final%%rev:~16,1%  && if 16 == 0 call %final%

# call set final=%final%%rev:~14,1%  && if 14 == 0 call %final%

# call set final=%final%%rev:~12,1%  && if 12 == 0 call %final%

# call set final=%final%%rev:~10,1%  && if 10 == 0 call %final%

# call set final=%final%%rev:~8,1%  && if 8 == 0 call %final%

# call set final=%final%%rev:~6,1%  && if 6 == 0 call %final%

# call set final=%final%%rev:~4,1%  && if 4 == 0 call %final%

# call set final=%final%%rev:~2,1%  && if 2 == 0 call %final%

# call set final=%final%%rev:~0,1%  && if 0 == 0 call %final%

Active Connections

这个混淆技巧可以绕过动态侦测,如下图 Sysmon 日志。

FinCoding

全名为 Fin-Style Encoding,因为 APT 组织 FIN7 的使用而得名。原理其实就是把指令的其中几个字元替换掉,之後再改回来而已。先看看基本的字串取代方法,下面例子把 zXzXX 改成 e,变成 zeze

# cmd /c "set a=zXzX&&call echo %a:X=e%
zeze

混淆指令也差不多,以下例子把原本的 netstat /ano 一开始先设成 neXsXaX /ano,之後再把 X 改成 t

# cmd /c "set cmd1=neXsXaX /ano&&call set cmd2=%cmd1:X=t%&&call %cmd2%"

Active Connections

这个混淆技巧可以绕过动态侦测,如下图 Sysmon 日志。

参考资料


<<:  [Day - 28] - 运用Spring MockMvc 迈向自动化测试之路

>>:  [Lesson28] Kotlin - Generics

【LeetCode】刷题技巧心得及资源

若确认自己想去的公司会考 live coding,那总得练习。 就算不会,我个人认为多写一点也是好事...

[Day 30] 会员登入及登出(二)

今天继续使用者登入的部分. 登入资料验证 当接收到表单送来的资讯之後, 首先我们要针对资料作验证. ...

Day 6 - 用 canvas 复刻 小画家 直线

直线 在上一篇章我们学会提取点击时的位置,本篇章也会用到相同的 function,我们先将他移出。 ...

[Day 15 - 小试身手] 用HTML、CSS、JS打造个人网站 (2)

在上一篇:用HTML、CSS、JS打造个人网站 (1),讲解了开发网页的前置作业,以及 Heade...

第二十八天:UI切版 & 元件-清单表格、弹出视窗

※ 今天的内容 一、清单表格:QTable、QMarkupTable 二、弹出视窗:QDialog、...