远程终端管理工具Xshell被植入后门代码事件分析报告
文档信息
| 文档编号 | 360Ti-2017-0005 |
|---|---|
| 关键字 | Xshell backdoor |
| 发布日期 | 2017-08-15 |
| 更新日期 | 2017-08-18 |
| TLP | WHITE |
| 分析团队 | 360威胁情报中心、360安全监测与响应中心 |
事件概要
| 攻击目标 | 使用Xshell远程管理工具进行系统管理的用户 |
|---|---|
| 攻击目的 | 收集系统相关的信息,可能通过专用插件执行远程控制类的功能 |
| 主要风险 | 系统相关的敏感信息泄露,相关的基础设施被非授权控制 |
| 攻击入口 | 下载安装执行某个官方版本的Xshell类软件 |
| 使用漏洞 | 无 |
| 通信控制 | 通过DNS隧道进行数据通信和控制 |
| 抗检测能力 | 无文件落地、插件工结构、繁复的二进制代码加密变换以抵抗分析 |
| 受影响应用 | Xshell 5.0 Build 1322Xshell 5.0 Build 1325Xmanager Enterprise 5.0 Build 1232 Xmanager 5.0 Build 1045Xftp 5.0 Build 1218Xlpd 5.0 Build 1220 |
| 已知影响 | 目前评估国内受影响用户在十万级别,已知部分知名互联网公司中招 |
| 分析摘要:· 战术· 技术· 过程 | 1. Xshell的开发厂商NetSarang极可能受到渗透,软件的组件nssock2.dll被插件后门代码,相应的软件包在官网被提供下载使用,所发布出来的程序有厂商的合法数字签名。2. 后门版本的Xshell软件被执行以后,内置的后门Shellcode得到执行,通过DNS隧道向外部服务器报告主机信息,并激活下一阶段的恶意代码。3. 后门代码的C&C通信使用了DGA域名,每月生成一个新的。4. 后门恶意代码采用了插件式的结构,无文件落地方式执行,配置信息注册表存储,可以执行攻击者指定的任意功能,完成以后不留文件痕迹。恶意代码内置了多种抵抗分析的机制,显示了非常高端的技术能力。 |
事件简述
近日,非常流行的远程终端Xshell被发现被植入了后门代码,用户如果使用了特洛伊化的Xshell工具版本会导致本机相关的敏感信息被泄露到攻击者所控制的机器甚至被远程控制执行更多恶意操作。
Xshell特别是Build 1322在国内的使用面很大,敏感信息的泄露及可能的远程控制导致巨大的安全风险,我们强烈建议用户检查自己所使用的Xshell版本,如发现,建议采取必要的补救措施。
事件时间线
2017年8月7日
流行远程管理工具Xshell系列软件的厂商NetSarang发布了一个更新通告,声称在卡巴斯基的配合下发现并解决了一个在7月18日的发布版本的安全问题,提醒用户升级软件,其中没有提及任何技术细节和问题的实质,而且声称没有发现漏洞被利用。
2017年8月14日
360威胁情报中心分析了Xshell Build 1322版本(此版本在国内被大量分发使用),发现并确认其中的nssock2.dll组件存在后门代码,恶意代码会收集主机信息往DGA的域名发送并存在其他更多的恶意功能代码。360威胁情报中心发布了初始的分析报告,并对后续更复杂的恶意代码做进一步的挖掘分析,之后其他安全厂商也陆续确认了类似的发现。
2017年8月15日
卡巴斯基发布了相关的事件说明及技术分析,与360威胁情报中心的分析完全一致,事件可以比较明确地认为是基于源码层次的恶意代码植入。非正常的网络行为导致相关的恶意代码被卡巴斯基发现并报告软件厂商,在8月7日NetSarang发布报告时事实上已经出现了恶意代码在用户处启动执行的情况。同日NetSarang更新了8月7日的公告,加入了卡巴斯基的事件分析链接,标记删除了没有发现问题被利用的说法。
影响面和危害分析
目前已经确认使用了特洛伊化的Xshell的用户机器一旦启动程序,主机相关基本信息(主机名、域名、用户名)会被发送出去。同时,如果外部的C&C服务器处于活动状态,受影响系统则可能收到激活数据包启动下一阶段的恶意代码,这些恶意代码为插件式架构,可能执行攻击者指定任意恶意功能,包括但不仅限于远程持久化控制、窃取更多敏感信息。
根据360网络研究院的C&C域名相关的访问数量评估,国内受影响的用户或机器数量在十万级别,同时,数据显示一些知名的互联网公司有大量用户受到攻击,泄露主机相关的信息。
解决方案
检查目前所使用的Xshell版本是否为受影响版本,如果组织保存有网络访问日志或进行实时的DNS访问监控,检查所在网络是否存在对于附录节相关IOC域名的解析记录,如发现,则有内网机器在使用存在后门的Xshell版本。
目前厂商NetSarang已经在Xshell Build 1326及以后的版本中处理了这个问题,请升级到最新版本,修改相关系统的用户名口令。厂商修复过的版本如下:
Xmanager Enterprise Build 1236
Xmanager Build 1049
Xshell Build 1326
Xftp Build 1222
Xlpd Build 1224
软件下载地址:https://www.netsarang.com/download/software.html
技术分析
基本执行流程
Xshell相关的用于网络通信的组件nssock2.dll被发现存在后门类型的代码,DLL本身有厂商合法的数字签名,但已经被多家安全厂商标记为恶意:

360威胁情报中心发现其存在加载执行Shellcode的功能:

我们将这段代码命名为loader_code1, 其主要执行加载器的功能,会再解出一段新的代码(module_Activation),然后动态加载需要的Windows API和重定位,跳转过去。
经过对进程执行的整体分析观察,对大致的执行流程还原如下图所示:

基本插件模块
Module_Activation
module_Activation会开启一个线程,然后创建注册表项:HKEY_CURRENT_USER\SOFTWARE\-[0-9]+(后面的数字串通过磁盘信息xor 0xD592FC92生成),然后通过RegQueryValueExA查询该注册表项下”Data ”键值来执行不同的功能流程。

当注册表项”Data”的值不存在时,进入上传信息流程,该流程主要为收集和上传主机信息到每月一个的DGA域名,并保存服务器返回的配置信息,步骤如下:
获取当前系统时间,根据年份和月份按照下面的算法生成一个长度为10-16的字符串,然后将其与”.com”拼接成域名。


年份-月份 和 生成的域名对应关系如下:
| 2017-06 | vwrcbohspufip.com |
|---|---|
| 2017-07 | ribotqtonut.com |
| 2017-08 | nylalobghyhirgh.com |
| 2017-09 | jkvmdmjyfcvkf.com |
| 2017-10 | bafyvoruzgjitwr.com |
| 2017-11 | xmponmzmxkxkh.com |
| 2017-12 | tczafklirkl.com |
| 2018-01 | vmvahedczyrml.com |
| 2018-02 | ryfmzcpuxyf.com |
| 2018-03 | notyraxqrctmnir.com |
| 2018-04 | fadojcfipgh.com |
| 2018-05 | bqnabanejkvmpyb.com |
| 2018-06 | xcxmtyvwhonod.com |
| 2018-07 | tshylahobob.com |
接着,将前面收集的网络、计算机、用户信息按照特定算法编码成字符串,然后作为上面的域名前缀,构造成查询*. nylalobghyhirgh.com 的DNS TXT的数据包,分别向8.8.8.8 | 8.8.4.4 | 4.2.2.1 | 4.2.2.2 | [cur_dns_server] 发送,然后等待服务器返回。

服务器返回之后(UDP)校验数据包,解析之后把数据拷贝到之前传入的参数中,下一步将这些数据写入前面设置的注册表项,也就是HKEY_CURRENT_USER\SOFTWARE\-[0-9]+的Data键中。这些数据应该是作为配置信息存放的,包括功能号,上次活跃时间,解密下一步Shellcode的Key等等。

当RegQueryValueExA查询到的Data键值存在数据时,则进入后门执行流程,该流程利用从之前写入注册表项的配置信息中的Key解密loader_code2后跳转执行。

解密loader_code2的算法如下:先取出module_Activation偏移0×3128处的original_key,接着取key的最后一个byte对偏移0x312C处长度为0xD410的加密数据逐字节进行异或解码,每次异或后original_key再与从配置信息中读取的key1、key2进行乘、加运算,如此循环。
| original_keykey1 | 0x340d611e |
|---|---|
| key1 | 0xC9BED351 |
| key2 | 0xA85DA1C9 |

解密之后跳转到loader_code2中, loader_code2其实和loader_cod e1是一样的功能,也就是一个loader,其再次从内存中解密出下一步代码:module_ROOT, 然后进行IAT的加载和重定位,破坏PE头,跳转到ROOT模块的入口代码处。
Module_ROOT
ROOT模块即真正的后门核心模块,为其他插件提供了基本框架和互相调用的API,其会在内存中解密出5个插件模块Plugin、Online、Config、Install和DNS,分别加载到内存中进行初始化,如果插件在初始化期间返回没有错误,则被添加到插件列表中。
| ID | Name |
|---|---|
| 100 | Root |
| 101 | Plugin |
| 102 | Config |
| 103 | Install |
| 104 | Online |
| 203 | DNS |
每个插件由DLL变形而成,加载后根据fwReason执行不同功能 (其中有一些自定义的值100,101,102,103,104).不同的插件模块fwReason对应的功能可能有细微的差异,整体上如下:
| fwReason | 功能 |
|---|---|
| 1 | Plugin_Initialize 该操作获取模块功能函数列表 |
| 100 | Plugin_SetFnTable该操作设置模块的ROOT函数列表,将Root函数列表指针设置到模块的全局函数列表指针 |
| 101 | Plugin_Clear 插件去初始化 |
| 102 | Plugin_GetId该操作获取模块ID |
| 103 | Plugin_GetName获取模块名称字符串,由第三个参数返回字符串 |
| 104 | Plugin_GetFnTable返回插件函数表的指针 |
接着ROOT模块搜索ID为103(“Install”)的插件,并调用其函数表的第二个函数。 进行安装操作。

同时ROOT模块也通过把自身函数表地址提供给其他模块的方式为其他模块提供API,这些API主要涉及跨模块调用API、加解密等功能。

另外其中解密的函数以及加载插件的函数也是由动态解出来的一段shellcode,可见作者背后的煞费苦心:


Module_Plugin
Plugin模块为后门提供插件管理功能,包括插件的加载、卸载、添加、删除操作,管理功能完成后会通过调用Online的0×24项函数完成回调,向服务器返回操作结果。模块的辅助功能为其他插件提供注册表操作。
Plugin的函数列表如下:

其中比较重要的是fuc_switch和CreateLoadRegThread。
fuc_switch
此函数根据第二个参数结构体的0×4偏移指令码完成不同操作,指令码构造如下:
(ID<<0×10)| Code
0×650000功能
此功能获取当前加载的插件列表字符串,此功能遍历全局ModuleInfo结构体获取模块名称列表,完成后通过Online模块的0×24执行调用者参数的回调函数,该回调为网络通知函数。

0×650001功能
此功能首先通过参数ID获取模块信息,如果该ID未被加载,则调用Root的加密函数加密模块数据,随后更新对应注册表值,完成模块更新,模块数据加密后保存,在Root模块初始化过程中会调用Plugin的注册表监听线程,该线程检测到注册表项变动后加载此模块:

0×650002功能
此功能通过文件名称加载PE结构的插件,Root模块的0×30项调用LoadLibrary函数加载DLL,并将插件结构插入全局插件双链表:

0×650003功能
该功能通过模块基址查找指定模块,内存卸载模块后删除对应注册表键值,彻底卸载模块:

0×650004功能
此功能检测参数指定模块ID是否被加载,如果该ID已被加载,通过Online的网络回调发送一个长度为1,数据为0×00的负载网络包,如果ID未被加载则发送一个长度为0的负载网络包。

CreateLoadRegThread
该函数创建线程,异步遍历注册表项“SOFTWARE\Microsoft\<MachineID>”,其中MachineID根据硬盘序列号生成。随后创建Event对象,使用RegNotifyChangeKeyValue 函数监测插件注册表键值是否被更改,被更改后则遍历键值回调中解密并加载模块并插入全局插件ModuleInfo。
Plugin模块的维护数据结构为双链表,并为每个插件定义引用计数,当引用计数为0时才从内存卸载插件。结构大致如下:

Module_Online
该模块主要功能是与服务器连接,获取服务器返回的控制指令,然后根据控制指令中的插件ID和附加数据来调用不同的插件完成相应的功能。同时Online也提供API接口给其他插件模块用于回传数据。
Online模块的函数表如下,可以看到其提供了一系列收发数据的API

网络连接开始时首先调用Config表中的第二个函数读取配置信息,通过InternetCrackUrlA将配置信息中的字符串(默认为dns://www.notepad.com)取得C&C地址,并根据字符串前面的协议类型采取不同的连接方式,每个协议对应一个ID,同时也是协议插件的ID,目前取得的样本中使用的DNS协议对应ID为203。(虽然有HTTP和HTTPS,但是ONLINE只会使用HTTP),协议与ID的对应关系如下:
| TCP | 200 |
|---|---|
| HTTP | 201 |
| HTTPS | 204(无效) |
| UDP | 202 |
| DNS | 203 |
| SSL | 205 |
| URL | 内置,无需额外插件 |


在建立起与C&C服务器的连接之后,可以根据接收到的服务器指令调用指定的插件执行指定的操作,并返回执行结果。首先先接收0×14字节的头部数据,这些数据将用于解压和解密下一步接收的指令数据。

接受的指令结构大致如下:
struct Command
{
DWORD HeaderSize;
WORD OpCode;
WORD PluginID;
DWORD DWORD0;
DWORD DataSize;
DWORD DWORD1;
DWORD DataBuff
...
};
小龙