- 概述
为了确保通信安全和隐私以及应对各种窃听和中间人攻击,越来越多的网络流量被加密,然而,攻击者也可以通过这种方式来隐藏自己的信息和行踪。近期我们捕获了一个样本,此样本就是使用了加密通信,为了深入研究此样本的加密通信机制,接下来我们来逐层剖析它。
域名 | *.ddns.net |
威胁类型 | 木马 |
样本性质 | 曾关联海莲花等APT组织 |
- 准备工作
解密硬编码字符串
将样本记录的硬编码字符串的每一个字节加0x23,可以获得密钥、域名、注册表键
字符串 | 作用 |
*.ddns.net | C2服务器域名 |
Softwaremicrosoftwindows NTCurrentversion | 注册表键 |
ProductName | 注册表键,系统版本 |
ComSpec | 环境变量:CMD.EXE的路径 |
2q36kj8*6t9w5 | 密钥:数据加密解密时使用的密钥 |
- 通信行为-接收
3.1 建立通信
样本采用TCP自定义加密通信,IP为域名(*.ddns.net)解析成功后得到的IP,端口为5832。
3.2 接收、校验数据
样本使用TCP协议传输数据,TCP载荷部分使用自定义加密协议,并且协议格式中含有身份校验位,只有校验通过才解析后面的内容,不通过则继续接收数据。
包类型 | 1、2、3、4、5字节 | 6、7字节 | 8、9字节 | 10、11字节 | 后续 |
连接包 | 会话ID | / | / | / | / |
命令与控制包 | 会话ID | 数据大小 | 指令码 | 是否解密标志位 | 传输的数据 |
备注 | 单次会话值相同 | 做大小校验 | 不同指令执行不同的操作 | 为0则不解密数据,大于0解密 | 需要解密的数据 |
接收数据包格式一览表
每次对接收的数据的校验方式如上表。第一次连接或者重新连接的数据包的前5个字节的值作为会话ID。
接收的数据包由三部分组成:
- 填充数据(长度可变)
- 11个字节的校验数据、指令
- 后续操作需要的参数、数据
为了防止单次会话中接收的数据因为前5个字节相同而出现规律性,会在校验前先获取有效的传输数据即移除填充数据,找到数据中与同一次会话的标志值相同的数据的位置,这也算是第一次校验。
接下来,校验有效数据的大小,有效数据的大小记录在第6、7字节,校验通过会根据第10、11字节的值来决定是否解密后续的数据。
3.3 解密数据
解密操作就是由硬编码得到的密钥和数据进行按位异或,返回的数据包也是这种方式加密的。
- 执行指令
接收数据的第8、9字节的值是样本的指令码,根据不同的指令执行不同的操作。
指令大致分为三类
- 获取基本信息
- 操作EXE
- 关闭进程、线程
4.1 获取信息
获取电脑系统信息、磁盘盘符、文件信息、进程信息以及TCP&UDP表的信息,并将获取的信息按照不同的格式拼接,然后将拼接好的数据与密钥做加密操作,并且将加密后的数据拷贝到发送缓冲区中。(具体的发送格式以及指令功能见文章末尾的发送数据包结构一览表)
4.2 操作CMD.EXE
创建两个匿名管道,获取环境变量ComSpec的值即CMD.EXE的路径,以这个路径创建进程CMD.EXE,并且在创建进程的时候将进程的输入、输出各绑定一个匿名管道,这样就可以通过管道来对CMD.EXE进行远程操作,其中输入CMD的指令就是有效数据中解密后的数据,输出即回显通过管道获取,再拼接相应的格式后加密存放到发送缓冲区中。
4.3 关闭进程、线程
关闭CMD.EXE进程
- 通信行为—发送
发送的数据格式如下表,按照自定义格式组成数据包内容后,加密发送:
指令码 | 操作 | 发包格式1、2、3、4、5字节 | 发包格式6、7字节 | 数据 | 备注 |
3017 | 结束指定线程,断开连接,然后重新启动网络连接 | / | / | / | 不发包 |
3000 | 获取电脑基本信息 | 会话ID | 3000 | 电脑名称|系统版本|用户名|主模块全路径|AN|.10* | 单个数据包 |
3001 | 获取磁盘盘符信息 | 会话ID | 3001 | C:\D:\(电脑所有盘符信息)| | 单个数据包 |
3002 | 遍历文件信息 | 会话ID | 3002 | <>文件名😕文件大小😕文件时间字符串😕 | 单个数据包
数据信息小于9084字节 |
遍历文件信息 | 会话ID | 3003 | xxxx(多次发包的个数INT)xxxx(多个包的实际大小) | 单个数据包
数据信息大于9084字节 发送数据总大小 |
|
3004 | 文件信息 | 会话ID | 3004 | 9084字节数据(或者剩下不足9084字节的数据) | 多个数据包 |
3005 | 创建文件 | 会话ID | 3010 | q7gf | 创建文件失败 |
创建文件 | 会话ID | 3006 | 1 | 创建文件成功 | |
3006 | 写文件 | 会话ID | 3006 | x(文件操作次数) | 单个数据包 |
3007 | 文件大小 | 会话ID | 3008 | xxxx(假设9084字节为页,这里记录的页数INT)xxxx(文件的实际大小) | 单个数据包 |
3009 | 文件数据 | 会话ID | 3009 | 9084字节数据(或者剩下不足9084字节的数据) | 多个数据包 |
3012 | 创建远程可交互式CMD匿名管道传输数据 | 会话ID | 3013 | 回显数据 | 单个数据包
数据信息小于9084字节 |
匿名管道传输数据 | 会话ID | 3014 | xxxx(多次发包的个数INT)xxxx(多个包的实际大小) | 单个数据包
数据信息大于9084字节 发送数据总大小 |
|
3013 | 给CMD传输命令 | 会话ID | 3013 | 回显数据 | 单个数据包
数据信息小于9084字节 |
给CMD传输命令 | 会话ID | 3014 | xxxx(多次发包的个数INT)xxxx(多个包的实际大小) | 单个数据包
数据信息大于9084字节 发送数据总大小 |
|
3015 | 发送回显数据 | 会话ID | 3015 | 9084字节数据(或者剩下不足9084字节的数据) | 多个数据包 |
3016 | 关闭CMD进程 | / | / | / | 不发包 |
3019 | 遍历TCP、UDP终结点表 | 会话ID | 3019 | TCP信息UDP信息 | 单个数据包
数据信息小于9084字节 |
遍历TCP、UDP终结点表 | 会话ID | 3020 | xxxx(多次发包的个数INT)xxxx(多个包的实际大小) | 单个数据包
数据信息大于9084字节 发送数据总大小 |
|
3021 | 负责TCPUDP表信息传输 | 会话ID | 3021 | 9084字节数据(或者剩下不足9084字节的数据) | 多个数据包 |
3022 | 关闭指定进程 | 会话ID | 3022 | t | 关闭进程成功 |
关闭指定进程 | 会话ID | 3022 | #%r | 关闭进程失败 | |
3023 | 遍历进程信息 | 会话ID | 3023 | (进程ID)8tr$(进程名字)8tr$(AD)t#21 | 单个数据包
数据信息小于9084字节 |
遍历进程信息 | 会话ID | 3024 | xxxx(多次发包的个数INT)xxxx(多个包的实际大小) | 单个数据包
数据信息大于9084字节 发送数据总大小 |
|
3025 | 进程信息传输 | 会话ID | 3025 | 9084字节数据(或者剩下不足9084字节的数据) | 多个数据包 |
/ | 每60秒 | xxxx(与接收数据包前4字节相同) | / | / | 每当间隔大于60秒判断一次,如果发送的数据不是多包中的数据则发送一个单独的包
|
发送数据包结构一览表
- 总结
样本使用TCP自定义加密通信,通信成功会首先进行身份校验、然后解析数据中的指令码,根据指令码的不同执行不同的功能,其中有一个高危的功能,通过匿名管道的方式实现远程可交互式CMD,CMD执行的命令和执行结果(回显)在通信流量载荷中加密传输。
利用TCP/UDP等协议承载自定义加密载荷进行攻击的APT组织、各类黑客工具层出不穷。因自定义加密格式不定,变化灵活,因此这种加密流量检测的难度进一步提高。我们一直针对各类使用自定义加密的最新威胁保持密切跟踪,并随时更新方案进行应对。