译者注

本文翻译自Fireeye https://www.fireeye.com/blog/threat-research/2018/11/obfuscated-command-line-detection-using-machine-learning.html

译者力求贴近文章原意,即使经过了逐句逐词地翻译校对,仍需在此做一些说明以便于读者对本文的学习与理解:

obfuscation detector "混淆检测器" 文中指识别混淆过的命令行的程序

Malicious actors 恶意的行动者,指黑客

living off the land "不落地" 指恶意软件不在磁盘存储

machine learning (ML) 机器学习

Pattern Matching 模式匹配

Neural Networks 神经网络

Convolutional Neural Network (CNN) 卷积神经网络

natural language processing 自然语言处理

Gradient Boosted Decision Tree 梯度增强的决策树

caret 即符号^

pipe symbols 管道符号 即|

discriminator 鉴别器

classifier 分类器

Gradient Boosted Tree,GBT 梯度增强树

机器学习效果的常用评测指标

F1值( F1-score)综合指标
准确率(Precision),简单说就是找得对
召回率(Recall),简单说就是找得全

前言

这篇博客文章介绍了一种机器学习(ML)方法,用于解决新出现的安全问题:在终端上检测混淆的Windows命令行调用。
我们首先介绍这种相对较新的威胁,然后讨论处理这些问题的传统办法。再说明解决此问题的机器学习方法,并指出ML如何极大地简化了强大的混淆检测器的开发和维护。最后,我们展示了使用2种不同的ML技术获得的结果,并比较了每种技术的优点。

介绍

恶意的行动者逐渐变得“不落地”,使用PowerShell和Windows Command Processor(cmd.exe)等系统内置的实用程序作为其感染工作流程的一部分,以尽量减少恶意软件被检测的机会,并绕过白名单防御策略。
新发布的混淆工具通过添加一个中接层(在可见的语法和命令的最终的行为之间),使得检测这类威胁变得更加困难。例如最近发布的两个混淆命令的工具:
Invoke-Obfuscation 自动混淆Powershell命令
Invoke-DOSfuscation 混淆Windows的cmd.exe命令行

(用于检测混淆的)传统的"模式匹配"和"基于规则的方法"难以开发和归纳,并且可能对防御者造成巨大的维护问题。我们将展示如何使用ML技术来解决这个问题。

"检测混淆过的命令行"是一种非常有用的技术,因为它为可能的恶意活动提供了强大的过滤器,减少了防御者必须查看的数据。虽然在野外有一些“合法”混淆的例子,但在绝大多数情况下,混淆的存在通常是一种恶意意图的信号。

背景

混淆技术被用来隐藏恶意软件的存在,已经有很长的历史了:包括恶意有效载荷的加密(从Cascade病毒开始)和字符串的混淆,到JavaScript混淆。

混淆的目的有两个:

  • 使防御类的软件越来越难找到:易于检测它们(可执行代码、字符串或脚本)的模式。
  • 使逆向工程师和分析师更难以破译并完全理解恶意软件正在做什么。

从这个意义上讲,命令行混淆不是一个新问题 - 只是混淆的目标(Windows命令处理器 cmd.exe)相对较新。最近发布的等工具如Invoke-Obfuscation(用于PowerShell)和Invoke-DOSfuscation(用于cmd.exe)已经证明了这些命令的灵活性,并且经过混淆的非常复杂的命令仍然可以有效运行。

如图所示,混淆过的命令行 与 非混淆的命令行,空间图中有两个轴:

  • 简单的(simple) -> 复杂的(complex)
  • 明文的(clear) -> 混淆的(obfuscated)

对于本次讨论中:

  • "简单的"("simple")表示简短且相对不太复杂,但仍然可以包含混淆;
  • "复杂的"("complex")表示长而复杂的字符串(可能会混淆,也可能不被混淆)

因此,简单/复杂 轴 与 混淆/未混淆 轴 正交。这两个轴的相互作用产生许多边界情况,其中用于检测脚本是否被混淆的简单启发式方法(例如,命令的长度)会在未经混淆处理的样本上产生误报。
从ML的角度来看,命令行处理器(command line processor)的灵活性使"分类"成为一项困难的任务。

图1:混淆的维度

-

图2:弱混淆和强混淆

传统的混淆检测办法

传统的混淆检测办法可以分为三种。

第一种方法

编写大量复杂的正则表达式以匹配Windows命令行中最常被滥用的语法。

例1
如这个正则表达式,试图匹配在混淆中常见的"使用call命令的&符号链"这一混淆模式。
(set [a-zA-Z0-9]+=.* &&)+ (call set [a-zA-Z0-9]+=%[a-zA-Z0-9%]+%).* call %.*%

它能够匹配到这个样本(以混淆的方式调用echo
set env1=ec && set env2=ho && call set env3=%env1% %env2% && call %env3%

译者专门测试了这个正则表达式的匹配 如图,可以匹配到这个样本。
可点击查看匹配效果 https://regex101.com/r/PvGq1u/1

这种方法存在两个问题:

  • 不可能开发非常多的正则表达式来涵盖每一种命令行可能的滥用方式,而且命令行的灵活性可以导致非常规的语句,用正则表达式表示这些语句是能做但不切实际的。
  • 即使恶意样本使用的混淆技术存在对应的正则表达式能够匹配到,一个决心强的攻击者也能够对混淆后的命令继续进行一些微小修改,不被之前的正则表达式匹配到。图5显示了对图4中序列的一个小修改,它避免了正则表达式检测。

对例1中的样本进行一些小调整变为如下语句,即可不被例1中的正则表达式匹配到。

set env1 =ec && set env2=ho ^&^& call set env3=:%env1% %env2% && call %env3%

译者专门比较了具体的修改点 如图

第二种方法

第二种方法更接近ML方法,涉及编写一些复杂的if-then规则,但是这些规则难以推导,验证起来复杂,并且随着作者本人逐渐开发出绕过这些规则的一些语句,给这种办法造成了沉重的维护负担。

例2 一个if-then规则
可能指出混淆(注意这个规则宽松 可能出现误报)

If COUNT("set") >= 2 and COUNT("%") >= 4 and COUNT("&") >=4 and COUNT("call")>= 2 then obfuscated

第三种方法

第三种方法是组合正则表达式和if-then规则。
这使开发和维护的负担极大地增加,并且仍然存在前两种方法的缺点。

例3 一个带有正则表达式的if-then规则(if-then规则与正则表达式的组合),用于检测混淆

If length()>= 20 and COUNT(“&")> 8 and MATCHES_REGEXP("(set [a-zA-Z0-9]+=.* &&)+ (call set [a-zA-Z0-9]+=%[a-zA-Z0-9%]+%).* call %. *%") then obfuscated

显然,很容易意识到生成、测试、维护并确保这些规则的效果是多么麻烦。

真正的手工构建的混淆检测器,将由数十或数百个规则组成,并且在检测中仍然存在gaps(漏洞、缺口)。

机器学习方法 - 超越模式匹配和规则

使用ML简化了这些问题的解决方案。
本文举例说明两种ML方法:

  • 1.基于特征的方法(a feature-based approach)
  • 2.无特征的端到端方法(a feature-less end-to-end approach)

有一些ML技术可以处理任何类型的原始数据(只要数据是数字类型的数据就行),神经网络就是一个很好的例子。大多数其他ML算法要求建模者在将原始数据输入算法之前从原始数据中提取有关信息(称为特征)。后一种类型的一些示例是基于树的算法,如本博客发过的这篇文章:Building Machine Learning Models for the SOC | FireEye Inc,其中我们使用了Gradient-Boosted树型模型,描述了基于树的算法的结构和用途。

ML基础 - 神经网络

神经网络是一种ML算法,最近变得非常流行。它由一系列称为神经元(neurons)的元素组成。神经元本质上是一个元素,它接受一组输入,计算这些输入的加权和(weighted sum),然后将总和输入非线性函数。已经表明,相对浅的(微弱的)神经元网络可以近似输入和输出之间的任何连续映射。
我们用于当前这项研究的特定类型的神经网络是所谓的卷积神经网络(CNN),它主要是为计算机视觉应用开发的,但也在包括自然语言处理在内的其他领域取得了成功。神经网络的主要优点之一是它可以在不必手动设计特征的情况下进行训练。

无特征的ML

神经网络可以与特征数据一起使用,这种方法的一个吸引人的地方是它可以处理原始数据(转换为数字形式)而无需进行任何特征设计或提取。
模型的第一步是将文本数据转换为数字形式。我们使用了基于字符的编码,其中每个字符类型都由实际数值编码。该值在训练过程中自动获得,并在字符应用于cmd.exe时,传送有关字符之间的关系的语义信息。

基于特征的ML

我们还尝试了手工设计的特征和梯度增强的决策树算法。
为这个模型开发的特征基本上是统计性质的——源于字符集和关键字的出现和频率。
例如,存在数十个字符或长而连续的字符串可能有助于检测潜在的混淆。虽然任何单特征都不能完美地分离这两个类,但是基于树的模型中存在的"多个特征的组合"能够学习数据中的灵活模式(flexible patterns)。预期这些模式是足够健壮的,并且可以通用到、普及到未来的混淆变体。

数据和实验

为了开发我们的模型,我们从数万个终端的事件中收集了非混淆的数据,并使用工具Invoke-DOSfuscation中的各种方法生成了混淆过的数据。我们使用大约80%的数据作为训练数据开发出了我们的模型,并用剩余的20%数据来测试了这些模型。我们保证我们的训练和测试是分割明确的。
对于无特征的ML(即神经网络),我们只需将Unicode码位输入到CNN模型的第一层,第一层将码位转换为语义上有意义的数字表示(这个叫做embeddings),然后将其提供给神经网络的其余部分。

对于渐变增强树方法,我们从原始命令行生成了许多特性。以下是其中一些:

对于梯度增强树(Gradient Boosted Tree)方法,我们从原始命令行中生成了许多特性。如这些:

  • 命令行的长度
  • 命令行中的插入^符号的数量
  • 管道符号|的数量
  • 命令行中的空白符号的分数
  • 特殊字符的分数
  • 字符串的熵
  • 命令行中字符串cmdpower的频率

虽然每一个单独的特征都是一个弱信号,并且每个自身都不可能是一个很好的鉴别器,但是一个灵活的分类器,如梯度增强树(Gradient Boosted Tree)使用这些特征对足够的数据进行训练,能够对混淆过的和非混淆的命令行进行分类,尽管有上述的一些困难。

结果

根据我们的测试集进行评估,我们能够从 梯度增强树(Gradient Boosted Tree) 和 神经网络模型 得到几乎相同的结果。

GBT模型,F1值( F1-score)、准确率(Precision)和召回率(Recall)等指标均接近1.0。GBT模型接近完美。
CNN模型,准确性略低。

虽然我们当然不指望能在现实世界中获得完美的结果,但这些实验室结果仍然是令人鼓舞的。回想一下,我们所有混淆的示例都是由一个源生成的,即Invoke-DOSfuscation工具。虽然Invoke-DOSfuscation生成各种混淆样本,但在现实世界中,我们期望至少看到一些与Invoke-DOSfuscation生成的样本非常不同的样本。我们目前正在收集真实世界混淆过的命令行,以便更准确地了解此模型对来自实际恶意参与者的混淆样本的通用性。我们预计cmd命令混淆,类似于之前的PowerShell混淆,将继续出现在新的恶意软件家族中。

作为一个额外的测试,我们请Daniel Bohannon(Invoke-DOSfuscation这一Windows命令行混淆工具的作者)提供一些混淆的样本,根据他的经验,这些样本很难被传统的混淆检测器识别。
实测每种情况,我们的ML探测器仍然都能够检测到混淆。一些样本如下:

cmd.exe /v/r "set 9S=e3zo Hi Vi3tor and Vikray!&set Zq=!9S:3=c!&setZYk9=!Zq:y=m!&set rQ2=!ZYk9:z=h!&&cmd /r %rQ2%
cmd /r "set a=tat -ano&set b=nets&cmd /r %b% %a%
cmd /v /r "set a=ona- tatsten&for/L %b in(11 -1 0) do setc=!c!!a:~%b,1!&if %b equ 0 call %c:~3%

我们还创建了看起来非常难理解的"文本"(这些文本是有效的Windows命令行),并且没有混淆,但是对于人类直观看到它们会感觉有点混淆。这样做是为了通过边界样本来测试一下检测器的有效性。在这种情况下,检测器也能够正确地将文本分类为非混淆文本。

这样的样本如下:
第一眼看上去好像是被混淆的样本,但实际上并没有混淆。而且很可能欺骗非ML的解决方案(但是ML混淆检测器目前能够将其标识为非混淆)

例4

cmd.exe /c 'C:\windows\system3213636363bsdshshshshsGF@#&()____.737.473783873.bat

最后,是一个复杂但没有混淆过的命令行,它被我们的ML混淆检测器正确分类,但可能会根据统计特征欺骗非ML的检测器(例如用手工的权衡方案和一个阈值的基于规则的检测器,"使用特殊字符的比例"、"命令行的长度"或"命令行的熵"等特征。

例5 使用简单统计特征的ML检测器可能错误分类的样本(但是,我们的ML混淆检测器目前将其识别为非混淆)

cmd /c echo nbt local > C:\windows\temp\nessus_L571HG8Q.txt & nbtstat-n>> C:\windows\tempnessus_L571HG8Q.txt & echo nbt_cache >> C:windows\temp\nessus_L571HG8Q.txt & nbtstat C >> C:\windows\temp\nessus_L57 1HG8Q.txt & echonbt_session_ip > C:\windows\temp\nessus_L571HG8Q.txt & nbtstat -S >> C:\windows\temp\nessus_L571HG8Q.txt & echo nbt_session_name >> C:windows\temp\nessus_L571HG8Q.txt & nbtstat -S >> C:\windows\temp\nessus_L571HG8Q.txt

结果如下:
GBT分类器自信地预测了"非混淆",得分为19.7%

[INFO] FeatureExtractor extraction complete.
{'prediction': 'non-obf, 'score': 19.73551018580834, 'reasons': []}

CNN与GBT的结果对比

我们比较了使用精心选择的特征构建的高度调优的GBT分类器 和 使用原始数据(无特征ML)训练的CNN分类器的结果。
虽然CNN的结构没有进行大量调整,但有趣的是,例4所示的样本,GBT分类器自信地预测了"非混淆",得分为19.7%(这是对分类器的结果"非混淆"的信心度量的补充)。同时,CNN分类器预测"非混淆"的置信概率为50%——正好在混淆和非混淆的边界处。CNN模型的误分类次数也多于梯度增强树(GBT)模型。这两种情况都很可能是CNN调优不足的结果,而不是无特征方法的根本缺陷。

总结

在这篇博文中,我们描述了一种ML方法来检测混淆过的Windows命令行,它可以作为一个信号来帮助识别恶意的命令行。通过使用ML技术,我们演示了一种非常精确的机制来检测此类命令行,而不需要借助于维护复杂if-then规则和正则表达式的技术(这种技术通常是不充分的,而且成本很高)。更全面的ML方法足够灵活,可以捕捉混淆中的新变化,当检测到gaps(漏洞、缺口)时,通常可以这样处理:通过向训练集添加一些精心选择的evader样本并重新训练模型。

这次ML技术的成功ML的成功应用再次证明了ML在替代"复杂的手工或编程方法"解决计算机安全问题方面的有效性。

在未来几年,我们预计ML将在网络安全公司中扮演越来越重要的角色。

点击收藏 | 0 关注 | 2
登录 后跟帖