分享

【译文】windows命令行混淆

 wujingsha 2022-02-13

引言

原文链接:

Windows Command-Line Obfuscation (wietzebeukema.nl)

出于兼容性或易用性的原因,同一命令行可以被不同的windows应用用不同的方法表达出来。由于变量的数量不同,命令行的参数被表达的不一致,使得检测特定命令变得更加困难。这篇文章展示了 40 多个常用的内置 Windows 应用程序如何容易受到命令行混淆形式的攻击,并提供了一种用于分析其他可执行文件的工具。

命令行参数

事实证明,当谈到计算机时,这句 16 世纪的名言仍然非常适用。

图片

毕竟,在大多数操作系统上,进程都有一个“命令行”组件,它允许(启动的)父进程将信息传递给子进程。这个新创建的进程可以访问命令行,它可能会根据在命令行中找到的内容来更改其进程流。这个概念是“计算机”的核心:它能够执行一组指令、程序、接受各种输入。

尽管它在计算中发挥着重要作用,人们对于如何称呼这些命令行的部分并没有达成一致。有些人认为命令行参数、参数、选项、标志、开关是相同的,但对有些人来说它们具有不同的含义。这篇文章中将使用以下术语:

图片

整个行是命令行,它由命令行参数(由空格分隔)组成。尽管它们都是参数,但它们具有不同的作用:例如,第一个参数通常是被调用的进程,或者,如果放在命令提示符中,这将是命令。在上面的图片中,命令的后面跟着更多的参数。更具体地说,前三个是命令行选项,通常以特殊字符开头。在这三个选项中,前两个是开关,因为它们不需要进一步的输入,而第三个是一个标志,因为它后面跟着更多的参数,这些参数是这个参数的“输入”。

选项是用作命令行选项前缀的字符。在 Windows 系统中,这通常是正斜杠 (/),在类 Unix 系统中,主要使用连字符 (-)。这不是惯例,而是规则:因为命令行是由正在执行的程序解析的,所以开发人员可以完全自由地定义应该以什么格式传递参数。

达成约定是一件很难的事。计算机的历史告诉我们,如果没有标准化,事情往往会以混乱告终——这当然适用于命令行。

兼容性

命令行解析实例缺乏标准化导致了许多用户的困惑:很容易混淆不同的实例,导致执行不成功以及产生挫败感。为了帮助用户,一些程序被设计为可以接受多种约定。一个常见的例子是同时接受正斜杠和连字符作为选项字符,这将在下一节中更详细地讨论。
另一个令人迷惑的事情是存在不同字符编码。这导致了旧程序(通常只接受 ASCII)和新程序(现在通常接受 UTF-8 或 Unicode)之间的各种兼容性问题。一些程序试图通过过滤掉某些字符或将特定字符转换为 ASCII 等价物来修复这些不兼容性。
这导致了一些程序将各种不同的命令行参数视为同一个参数的情况。您可以将此类实例称为同义命令行,因为尽管传递给进程的数据不同,但它们的执行和结果是相同的。

检测的难题

尽管能够以不同的方式表达相同的命令可能对某些用户有所帮助,但它往往会使检测和预防工作变得更加困难。大多数威胁检测软件(AV、EDR 等)都会监控进程执行,并查找可能指示恶意使用的命令行参数。由于攻击者希望不被发现,他们可能会利用命令行的灵活性来逃避检测。他们尝试的范围从小调整到绕过基于关键字的检测,再到全面的命令行混淆以隐藏原始命令。
命令行级别混淆的一个很好的例子是 Daniel Bohannon 的出色工作,DOSfuscation [1, 2],它特别关注 Windows 命令行提示符 CMD。即使执行的 CMD “理解”并执行了混淆的命令,它对人类来说可能看起来难以理解,监控软件也可能被蒙在鼓里。
同义命令行的现象超越了 DOSfuscation,因为它适用于更多的程序,而不仅仅是 CMD。这里的关键区别在于,您不仅可以欺骗命令行提示符,还可以欺骗正在执行的程序本身。正如稍后将显示的,虽然 DOS 混淆工作最终可能以未混淆的形式被记录在检测软件使用的记录器中,同义命令行参数不会。

方法:同义命令行

我们下面将展示五种不同的可以造成同义命令行的方法。

选项(option)符号替代法
比如Windows 可执行 ping。因为该程序是原始 Unix 版本的一个端口,所以帮助页面建议命令行选项应该使用连字符作为选项字符,例如ping-n0 127.0.0.1。这与大多数其他使用正斜杠的 Windows 原生命令行工具不一致。大概是为了帮助困惑的用户,该程序也接受正斜杠作为选项:ping /n 0 127.0.0.1。
大多数使用连字符的内置 Windows 可执行文件也接受正斜杠,但反之则不然。例如,命令 find /i 关键字将显示所有包含单词“关键字”的文件,而 find -i 关键字将导致错误。
尽管正斜杠和连字符是最常见的可用选项,但有些程序支持更多选项字符。certutil 恰好接受连字符、斜杠和斜杠的大多数 Unicode表示,例如除斜杠 (0x2215)和分数斜杠 (0x2044)[3]。
正如我们将在其他变体中看到的那样,可执行文件的文档中很少记录这些替代命令行选项,需要您或者偶然发现它们,或者通过“暴力”或逆向工程的方式才可以发现。

字符替代法
另一种方法是用相似的字符替换命令行中的其他字符(即选项字符以外的字符)。特别是当您在整个 Unicode 范围查找时,有许多字母的变体也可以在ASCII码范围内被找到,而这是一些进程可能接受的。
Unicode 包含间距修饰符字母 (0x02B0 - 0x02FF)[4] 的范围,其中包括 ˪、ˣ 和 ˢ 等字符。一些命令行解析器将它们识别为字母并将它们分别转换回 l、x 和 s。这方面的一个例子是 reg,它将 reg export HKCU out.reg 和 reg eˣport HKCU out.reg 视为同一个命令。

图片

事实证明,有更多的unicode编码可以被一些程序所接受。

字符插入法
类似地,有时可以在命令行中插入额外的字符,这些字符将被执行程序忽略。例如,某些可执行文件可能会删除不可打印的字符,而某些可打印的字符也可能会被过滤掉。
例如,Windows 事件日志工具 wevtutil 似乎接受在随机位置插入特定范围的 Unicode 字符的命令行。因此,执行 wevtutil gli hardwareevents 和 wevtutil gࢯli hardwareevents 将产生完全相同的输出,尽管后者在第一个参数的中间包含一个阿拉伯字母。

图片

因为可用于此技术的字符有时在命令行提示符的标准输入中不受支持(例如,因为它们不可打印),您可能必须使用字节表示法(\u)插入字符。从屏幕截图中可以看出,在这种情况下,字符被正确传递给进程。

引号插入法
另一种修改命令行却保持进程流完整性方法是插入引号。尽管这听起来像是先前技术的一个子集,但这里的要求是引号成对出现。
您可能熟悉在参数周围加上引号的概念。以 dir 'c:\windows\' 为例,由于缺少空格,它实际上与 dir c:\windows\ 相同。大多数程序都接受这个约定。鲜为人知的是,大多数程序在任意位置都接受引号:命令 dir c:\'win'd''ow's' 也可以使用。只要每个参数的引号数量是偶数并且后续引号不超过两个,大多数程序似乎都接受这一点。

图片

值得注意的是,在命令提示符CMD中使用引号可能会很棘手,因为它们通常会在将引号传递给底层程序之前自己处理引号。例如,在 cmd 中解决此问题的一种方法是将每个引号加倍,因此要获得如上所示的执行结果,您必须运行 netsh ad''vfi''rewall show currentprofile state。

简写法
插入和替换字符后,我们还需要尝试删除字符。一些应用程序允许对其他冗长的命令行选项进行“简写”,从而更容易输入它们。
这是基于 Unix 的工具中的一个众所周知的概念(例如 grep -i 关键字与 grep --ignore-case 关键字),但在 Windows 上则较少。然而,一些程序接受缩短的版本。一些程序采用与 Unix 类似的方法并接受单字母版本(例如 cmdkey /l 与 cmdkey /list),一些程序接受其他缩写版本(例如 wevtutil gli 与 wevtutil get-loginfo),而其他程序则采用“通配符”方法。这类的一个例子是 PowerShell,它的许多关键字允许您在关键字末尾省略一个或多个字符 [5]。

图片

也许除了最短的变体 /e 之外,在我看来,几乎没有程序通过接受这些简写而对使用者产生帮助,而它确实使事情变得更加复杂和不可预测。例如,PowerShell 仅在不会导致另一个命令之间产生歧义的情况下才接受缩短的版本。出于这个原因,关键字 /noprofile 的最短变体是 /nop,因为 /no 会与例如/noexit冲突。在这种“通配符方法”旁边,PowerShell 在某些情况下还接受首字母缩略词,因此尽管未在屏幕截图中显示,/ec 也可以用作 /encodedcommand 的简写。

找到可以使用混淆命令行的程序

如前几节所述,程序在处理命令行参数时是没有标准的。有些程序非常严格,而有些程序会非常努力地将用户输入的内容变成它可以理解的东西。找出特定程序的命令行行为也是有困难的:帮助页面通常只指定传递参数的“首选”方式(方法 1 和 5),并且通常从不描述如何处理意外字符(方法 2-4 )。
确定这一点的最准确方法似乎是逆向工程。但是,这是一项非常耗时的活动,尤其是考虑到某些程序的复杂性时。因此,更实用的方法是简单地用不同的字符重复尝试所有绕过技术并比较结果。
这种方法 [6] 的poc使我们能够快速分析所描述的五种行为中的哪一种适用。您可以在 GitHub 项目页面上找到关于 PoC 的更详细说明、其基本假设和注意事项。
出于本文的目的,PoC 这里被用来分析 40 多个经常被用于攻击的内置 Windows 可执行文件,您可以在 GitHub [6] 上找到每个经过测试的可执行文件的完整报告,包括经过测试的命令和找到的字符。

一些备注:
1这里使用的windows版本是Windows 10 version 2004;
2对于每一个window可执行文件,只是用了一个特定的命令来测试,其他的命令也可能导致不同的结果;
3用星号 (*) 表示的条目表示该参数接受任意一种变体。例如,在 nslookup -querytype=ALL (...) 的情况下,PoC 发现无论插入什么字符都返回了预期的输出。事实证明,nslookup 会忽略命令行选项(在本例中为 -q)的第一个字母之后的所有字母,这意味着可能的排列数量几乎是无限的。

其他

排版太难了,剩下一部分关于检测的我放到语雀,需要的自取~

https://www./rdzxytfcv/rrsa3t/awbg9u

一部分参考链接:

[1]https://github.com/danielbohannon/Invoke-DOSfuscation#/

[2]https://www./content/dam/fireeye-www/blog/pdfs/dosfuscation-report.pdf#/

[3]https:///articles/TaniumotherEDRHIDSbypass

[4]https://www./charts/nameslist/n_02B0.html

[5]https://www./blog/circumventing-encodedcommand-detection-powershell/

[6]https://github.com/wietze/windows-command-line-obfuscation

[7]https://github.com/SigmaHQ/sigma#/

[8]https://github.com/Neo23x0/sigma/wiki/Rule-Creation-Guide#detection

[9]https://attack./techniques/T1082/

[10]https://attack./techniques/T1070/001/

终于艰难决定开始更新了,新的一年总要有新的开始嘛,大家一起加油!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多