导语:在本文中,我将解释如何对Ostap进行反混淆处理,并描述我编写的Python脚本(deobfuscate_ostap.py),该脚本可以自动对此JScript恶意软件进行反混淆处理,可在GitHub上下载。
介绍
威胁行为者在危害系统时,通常需要考虑如何进入目标网络才能避免被检测到,而传递恶意附件的网络钓鱼邮件往往就充当了初始感染媒介的角色。
此外,攻击者还需要一种方法,在安全监控产品的眼皮底下执行代码。最常见的一种代码执行技术就是使用解释脚本语言,可以在操作系统上运行而不需要额外的依赖关系。以Windows为例,受到攻击者青睐的语言包括PowerShell、VBScript、JScript、VBA,以及滥用cmd.exe来执行指令。
攻击者和防御者的关系就像猫和老鼠,在进步的道路上不断追逐。我们经常看到恶意行为者为了增加入侵的成功率,花了很多心思在工具改进上,尤其是最开始破坏系统的下载器上。
2019年8月初,我们注意到传播TrickBot的钓鱼邮件行动中开始出现了Ostap的身影,这是一种基于JavaScript的商业下载器。在过去,传播TrickBot的活动往往依赖于使用了混淆shell命令,或是PowerShell命令的下载器,再由VBA AutoOpen宏触发,进而下载并执行恶意payload。
在本文中,我将解释如何对Ostap进行反混淆处理,并描述我编写的Python脚本(deobfuscate_ostap.py),该脚本可以自动对此JScript恶意软件进行反混淆处理,可在GitHub上下载。
TrickBot,也被称为The Trick,是一种模块化银行木马,被至少三个威胁团伙运作过,分别是TA505、Grim Spider和Wizard Spider。虽然基于javascript的下载器并不新鲜,但TrickBot最新的下载器以其大小、虚拟机检测和反分析措施而闻名。曾有分析人员做过检测,Ostap样本在两个不同的公共沙箱中的生成并不完整,也没有下载各自的TrickBot payload。此外,上传到VirusTotal的样本在首次上传时检测率仅有6/55(11%),这表明Ostap可有效避开大多数反病毒检测。
图1.Ostap样本的VirusTotal检测
Ostap——TrickBot的JScript下载器
下载器的目的是从一个或多个远程服务器上检索及运行次级payload,它们的功能往往比较简单,即使混淆后,也很少有超过几百行代码的。Ostap却完全不符合这一规律,因为它非常大,包含了近35,000行经过美化的混淆代码。历史上的TrickBot活动表明,操作人员为了绕过检测,用的混淆层数往往比其他恶意软件要多。
图2.Ostap样本的行,字和字节数,有34,757行
宏分析
下载器伪装在一个启用了宏的Microsoft Word 2007的文档里,文档包含下载器的两个组件:VBA宏和JScript(图3)。电子邮件订单交易为主题,表明这些活动可能旨在针对企业而非个人。
图3.下载器的诱饵文档
下载器的JScript组件以白色文本的形式存储在文档正文中,从而导致单词和页数较高。
图4 .诱饵文档中的JScript
VBA宏保存在名为“Sorry”的项中。打开文档时,它首先将JScript复制到用户默认Word模板目录 (%AppData%\Microsoft\Templates)中名为2angola.dot和2angola.dotu的文件中。该过程由Document.Open事件触发。
图5.打开文档时运行的带注释的VBA代码
宏的其余部分仅在文档关闭时运行,这是通过监视Document.Close事件来实现的(图6)。这是一种反沙箱措施,利用不会模仿用户活动的沙箱来阻止行为分析,例如关闭文档的动作。
图6.文档关闭时运行的带注释的VBA代码
如果文档已关闭,宏将2angola.dot重命名为2angola.Jse然后运行它,步骤如下:
1、宏从Win32_Process WMI类调用Create方法,以2angola.Jse作为命令行参数运行新的Explorer.exe进程(图7)。[13]
2、当Explorer.exe进程已经在运行,需要创建一个的新的时,将使用/ factory {75DFF2B7-6936-4C06-A8BB-676A7B00B24B} -Embedding命令行参数创建(图8)。 CLSID对应于名为“CLSID_SeparateMultipleProcessExplorerHost”的ProgID。
3、Explorer使用Windows脚本宿主(WScript.exe)运行2angola.Jse,这是JScript编码文件(.JSE)的默认文件处理程序,如图9所示。2angola.dot的文件扩展名重命名为.Jse确保由WScript.exe打开。这种默认的文件关联性,意味着宏可以通过间接引用WScript来逃避检测,WScript是一种通常在宏的上下文中用于恶意目的的程序。
图7.Sysmon事件显示了一个Explorer.exe进程,它在WMI Provider Host (WmiPrvSE.exe)启动后运行JScript文件
图8.Sysmon事件显示由参数 /factory,CLSID {75DFF2B7-6936-4C06-A8BB-676A7B00B24B} -Embedding创建的新Explorer.exe进程
图9.图9 – Sysmon事件,显示运行JScript文件的WScript.exe
反分析措施
值得注意的是,Ostap包含一个假的Windows Script Host runtime错误,在脚本运行后不久发生。此举可能是为了阻止对下载器的手动检查。
图10.在下载器运行前期时显示的假错误消息
图11.TrickBot的下载器中假错误消息的变量
一些下载器样本在JSE文件的开头包含字符** /,这是另一种反分析措施,用于干扰自动化JavaScript分析工具,分析工具可能会将脚本的其余部分解释为注释块的一部分,而不是可执行代码。
消除混淆后会发现其他一些反分析措施。例如,Ostap通过查找运行进程的名单来查询WMI是否在虚拟机中运行,名单如下:
· AgentSimulator.exe
· anti-virus.EXE
· BehaviorDumper
· BennyDB.exe
· ctfmon.exe
· fakepos_bin
· FrzState2k
· gemu-ga.exe (Possible misspelling of Qemu hypervisor’s guest agent, qemu-ga.exe)
· ImmunityDebugger.exe
· KMS Server Service.exe
· ProcessHacker
· procexp
· Proxifier.exe
· python
· tcpdump
· VBoxService
· VBoxTray.exe
· VmRemoteGuest
· vmtoolsd
· VMware2B.exe
· VzService.exe
· winace
· Wireshark
许多沙箱在其guest image中运行进程,例如Cuckoo Sandbox及其使用Python代理的衍生产品,此脚本还会检查主机名和用户名的黑名单:
· Emily
· HANSPETER-PC
· HAPUBWS
· Hong Lee
· IT-ADMIN
· JOHN-PC
· Johnson
· Miller
· MUELLER-PC
· Peter Wilson
· SystemIT | admin
· Timmy
· WIN7-TRAPS
脚本美化
写入磁盘的JScript只有一行,因此很难手工分析。为了提高可读性,您可以使用Einar Lielmanis的JS Beautifier工具对代码进行重新格式化并添加缩进,该工具也适用于JScript,因为它们具有相似的语法。
js-beautify 2angola.Jse> 2angola.Jse.beautified
识别代码结构、关键变量和函数
现在代码是可读的,我们就可以开始分析脚本的结构、变量和函数了。我们的目标是确定负责对下载器进行反混淆处理的函数。
该脚本包含许多垃圾变量,这些变量在脚本的其他任何地方都没有使用。我们可以简单地删除这些变量。通常可以将由混淆器自动生成的变量与有意义的变量区分开来,因为它们的命名约定会有所不同。
例如,在图12中看到脚本中的一些变量赋值。所有这些都是垃圾代码,除了名为gunsder的变量,它看起来很值得关注,因为它包含字符串“from”,也被引用了2,515次。
图12.脚本中的一些变量
图13中,在第15行看到一个名为xxqneol的函数。我们推测变量gnsder与其他字符串连接在一起。连接后,可以看到返回的字符串是对fromCharCode()方法的引用,该方法将Unicode字符代码转换为字符。该函数提供了一个名为etsfhis的参数。在调用fromCharCode之前,函数会检查第二个参数vqjpvi是否为字符h。此函数也被引用了7,540次,因此该函数很可能用于脚本的反混淆处理。
现在我们了解了函数的作用,我们可以给它和它的变量、参数赋予一些有意义的名称(图14)。
图13.去混淆之前的函数xxqneol
图14.重命名xxqneol函数
字符代码计算函数分析
接下来,我们可以查看引用fromCharCode的函数,以了解它是如何使用的。清理完图15中的代码后,您可以看到该函数使用算术运算符,以存储在pkkwrit4数组中的值来计算Unicode字符代码,然后将Unicode字符代码和字符h提供给fromCharCode函数,该函数返回Unicode字符。在本样本中,返回的字符是f。下载器中的每个字符都有自己的函数来计算其字符代码。此样本具有7,540个函数,用于计算所有字符代码。
图15.用于计算Unicode字符代码的众多函数之一
图16.清理函数
编写Python脚本(deobfuscate_ostap.py)进行反混淆处理
由于不想手动计算和解码7,540个Unicode字符代码,我编写一个Python脚本来执行此操作。
通过查找代码相似性,可以确定我们需要脚本执行哪些操作。在计算Unicode字符代码的函数中,最终的字符代码值总是使用数组索引0和索引1处的元素来计算。在将这些元素提供给fromCharCode函数之前,会对这些元素执行一些算术运算。到目前为止,我们在野外Ostap样本中只看到加法和减法的使用。
我们可以使用Python的re模块编写正则表达式来匹配索引0和索引1处每个数组中的元素,并将它们存储在列表中;接下来使用re.sub()函数清理匹配项,然后将它们转换为整数;然后使用Python的zip()函数对索引0和1列表中的值执行算术运算;脚本通过加减法操作以对下载器去混淆;最后,脚本将字符代码转换为Unicode字符,删除换行符并打印结果。
该脚本可在GitHub上下载。为了测试此脚本,我还编写了一个YARA规则来检测Ostap,然后对从2019年8月开始的100个样本运行测试。提取和重复数据删除的URL位于本文末尾。
去混淆的下载器分析
运行脚本后,检查下载器中的反混淆字符串,以及托管TrickBot payload的URL:
hxxps://185.180.199[.]102/angola/mabutu.php?min=14b
图17.使用deobfuscate_ostap.py对Ostap样本进行反混淆处理后的字符串
这些字符串与2018年以后的旧Ostap样本非常相似,这使我们能够做出一个高度的信心评估,即用于在2019年8月传播TrickBot的下载器属于这类恶意软件。公开报告显示,自2016年以来,这种恶意软件一直被用于与TrickBot无关的活动中,传播各种金融恶意软件家族。通过Ostap传递各种恶意软件的做法表明,它是一种商品恶意软件,在不同的威胁行为者中很受欢迎,包括现在的TrickBot运营商。
与使用其他解释脚本语言的下载器相比,Ostap具有强大的反分析功能和较低的检测率,这使得它对恶意软件运营商充满着吸引力。
YARA Rule
rule win_ostap_jse { meta: author = "Alex Holland @cryptogramfan (Bromium Labs)" date = "2019-08-29" sample_1 = "F3E03E40F00EA10592F20D83E3C5E922A1CE6EA36FC326511C38F45B9C9B6586" sample_2 = "38E2B6F06C2375A955BEA0337F087625B4E6E49F6E4246B50ECB567158B3717B" strings: $comment = { 2A 2A 2F 3B } // Matches on **/; $array_0 = /\w{5,8}\[\d+\]=\d{1,3};/ $array_1 = /\w{5,8}\[\d+\]=\d{1,3};/ condition: ((($comment at 0) and (#array_0 > 100) and (#array_1 > 100)) or ((#array_0 > 100) and (#array_1 > 100))) and (filesize > 500KB and filesize < 1000KB) }
Hashes (SHA-256)
F3E03E40F00EA10592F20D83E3C5E922A1CE6EA36FC326511C38F45B9C9B6586 – Last_order_specification_1217492.docm 38E2B6F06C2375A955BEA0337F087625B4E6E49F6E4246B50ECB567158B3717B – Heiress_Documents_id18598.docm
提取的URL
hxxps://185.130.104[.]149/odr/updateme.php?oxx=p hxxps://185.130.104[.]149/odr/updateme.php?oxx=up hxxps://185.130.104[.]149/odr/updateme.php?oxx=z hxxps://185.130.104[.]236/deerhunter/inputok.php?min=29h hxxps://185.130.104[.]236/deerhunter/inputok.php?min=up3 hxxps://185.130.104[.]236/deerhunter2/inputok.php?min=6h hxxps://185.130.104[.]236/deerhunter2/inputok.php?min=8h hxxps://185.130.104[.]236/deerhunter2/inputok.php?min=9a hxxps://185.130.104[.]236/deerhunter2/inputok.php?min=9h hxxps://185.130.104[.]236/targ/inputok.php?min=13s hxxps://185.130.107[.]236/deerhunter3/inputok.php?min=12a hxxps://185.159.82[.]15/hollyhole/c644.php?min=up hxxps://185.159.82[.]15/hollyhole/c644.php?min=17ha hxxps://185.159.82[.]15/hollyhole/c644.php?min=18h hxxps://185.159.82[.]15/hollyhole/c644.php?min=19a hxxps://185.159.82[.]15/hollyhole/c644.php?min=19h hxxps://185.159.82[.]15/hollyhole/c644.php?min=a hxxps://185.159.82[.]15/hollyhole/c644.php?min=m hxxps://185.159.82[.]15/hollyhole/c644.php?min=m2 hxxps://185.159.82[.]15/hollyhole/c644.php?min=t2 hxxps://185.159.82[.]15/hollyhole/c644.php?min=tu hxxps://185.159.82[.]15/hollyhole/c644.php?min=w hxxps://185.159.82[.]15/hollyhole2/c644.php?min=19h hxxps://185.159.82[.]15/hollyhole2/c644.php?min=79 hxxps://185.159.82[.]20/t-30/x644.php?min=m hxxps://185.159.82[.]20/t-34/x644.php?min=24 hxxps://185.159.82[.]20/t-34/x644.php?min=f hxxps://185.159.82[.]20/t-34/x66744.php?min=u2 hxxps://185.180.199[.]102/angola/mabutu.php?min=14b hxxps://189.130.104[.]236/deerhunter3/inputok.php?min=13h