龙空技术网

警惕:魔改后的CIA攻击套件Hive进入黑灰产领域

码农世界 3128

前言:

目前大家对“c语言获取mac地址siocgifhwaddr”大致比较看重,咱们都需要剖析一些“c语言获取mac地址siocgifhwaddr”的相关知识。那么小编在网摘上收集了一些有关“c语言获取mac地址siocgifhwaddr””的相关文章,希望看官们能喜欢,各位老铁们快快来学习一下吧!

概述

2022年10月21日,360Netlab的蜜罐系统捕获了一个通过F5漏洞传播,VT 0检测的可疑ELF文件ee07a74d12c0bb3594965b51d0e45b6f,流量监控系统提示它和IP45.9.150.144产生了SSL流量,而且双方都使用了伪造的Kaspersky证书,这引起了我们的关注。经过分析,我们确认它由CIA被泄露的Hive项目server源码改编而来。这是我们首次捕获到在野的CIA HIVE攻击套件变种,基于其内嵌Bot端证书的CN=xdr33, 我们内部将其命名为xdr33。关于CIA的Hive项目,互联网中有大量的源码分析的文章,读者可自行参阅,此处不再展开。

概括来说,xdr33是一个脱胎于CIA Hive项目的后门木马,主要目的是收集敏感信息,为后续的入侵提供立足点。从网络通信来看,xdr33使用XTEA或AES算法对原始流量进行加密,并采用开启了Client-Certificate Authentication模式的SSL对流量做进一步的保护;从功能来说,主要有beacon,trigger两大任务,其中beacon是周期性向硬编码的Beacon C2上报设备敏感信息,执行其下发的指令,而trigger则是监控网卡流量以识别暗藏Trigger C2的特定报文,当收到此类报文时,就和其中的Trigger C2建立通信,并等待执行下发的指令。

功能示意图如下所示:

Hive使用BEACON_HEADER_VERSION宏定义指定版本,在源码的Master分支上,它的值29,而xdr33中值为34,或许xdr33在视野之外已经有过了数轮的迭代更新。和源码进行对比,xdr33的更新体现在以下5个方面:

添加了新的CC指令对函数进行了封装或展开对结构体进行了调序,扩展Trigger报文格式Beacon任务中加入CC操作

xdr33的这些修改在实现上来看不算非常精良,再加上此次传播所所用的漏洞为N-day,因此我们倾向于排除CIA在泄漏源码上继续改进的可能性,认为它是黑产团伙利用已经泄漏源码魔改的结果。考虑到原始攻击套件的巨大威力,这绝非安全社区乐见,我们决定编写本文向社区分享我们的发现,共同维护网络空间的安全。

漏洞投递Payload

我们捕获的Payload的md5为ad40060753bc3a1d6f380a5054c1403a,它的内容如下所示:

代码简单明了,它的主要目的是:

1:下载下一阶段的样本并将其伪装成/command/bin/hlogd

2:安装logd服务以实现持久化。

样本分析

我们只捕获了一个X86 架构的xdr33样本,它的基本信息如下所示:

MD5:ee07a74d12c0bb3594965b51d0e45b6fELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, strippedPacker: None

简单来说,xdr33在被侵入的设备运行时,首先解密所有的配置信息,然后检查是否有root/admin权限,如果没有,则输出Insufficient permissions. Try again...并退出;反之就初始化各种运行时参数,如C2,PORT,运行间隔时间等。最后通过beacon_startTriggerListen两个函数开启Beacon,Trigger两大任务。

下文主要从2进制逆向的角度出发,分析Beacon,Trigger功能的实现;同时结合源码进行比对分析,看看发生了哪些变化。

解密配置信息

xdr33通过以下代码片段decode_str解密配置信息,它的逻辑非常简单即逐字节取反

在IDA中可以看到decode_str的交叉引用非常多,一共了152处。为了辅助分析,我们实现了附录中IDAPython脚本 Decode_RES,对配置信息进行解密。

解密结果如下所示,其中有Beacon C2 45.9.150.144,运行时提示信息,查看设备信息的命令等。

Beacon Task

Beacon的主要功能是周期性的收集PID,MAC,SystemUpTime,进程以及网络相关的设备信息;然后使用bzip,XTEA算法对设备信息进行压缩,加密,并上报给C2;最后等待执行C2下发的指令 。

0x01: 信息收集MAC通过SIOCGIFCONSIOCGIFHWADDR查询MAC

SystemUpTime通过/proc/uptime收集系统的运行时间

进程以及网络相关的信息通过执行以下4个命令收集进程,网卡,网络连接,路由等信息

0x02: 信息处理

Xdr33通过update_msg函数将不同的设备信息组合在一起

为了区别不同的设备信息,Hive设计了ADD_HDR,它的定义如下所示,上图中的“3,4,5,6”就代表了不同的Header Type。

typedef struct __attribute__ ((packed)) add_header {	unsigned short type;	unsigned short length;} ADD_HDR;

那“3,4,5,6”具体代表什么类型呢?这就要看下图源码中Header Types的定义了。xdr33在此基础上进行了扩展,新增了0,9俩个值,分别代表Sha1[:32] of MAC,以及PID of xdr33

xdr32在虚拟机中的收集到的部分信息如下所示,可以看出它包含了head type为0,1,2,7,9,3的设备信息。

值得一提的是type=0,Sha1[:32] of MAC,它的意思是取MAC SHA1的前32字节。以上图中的的mac为例,它的计算过程如下:

mac:00-0c-29-94-d9-43,remove "-"result:00 0c 29 94 d9 43sha1 of mac:result:c55c77695b6fd5c24b0cf7ccce3e464034b20805sha1[:32] of mac:result:c55c77695b6fd5c24b0cf7ccce3e4640

当所有的设备信息组合完毕后,使用bzip进行压缩,并在头部增加2字节的beacon_header_version,以及2字节的OS信息。

0x03: 网络通信

xdr33与Beacon C2通信过程,包含以下4个步骤,下文将详细分析各个步骤的细节。

双向SSL认证获取XTEA密钥向C2上报XTEA加密的设备信息执行C2下发的指令Step1: 双向SSL认证

所谓双向SSL认证,即要求Bot,C2要确认彼此的身份,从网络流量层面来看,可以很明显看到Bot,C2相互请求彼此证书并校验的过程。

xdr33的作者使用源码仓库中kaspersky.conf,以及thawte.conf 2个模板生成所需要的Bot证书,C2证书,CA证书。

xdr32中硬编码了DER格式的CA证书,Bot证书和PrivKey。

可以使用openssl x509 -in Cert -inform DER -noout -text查看Bot证书,其中CN=xdr33,这正是此家族名字的由来。

可以使用openssl s_client -connect 45.9.150.144:443 查看C2的证书。Bot,C2的证书都伪装成与kaspersky有关,通过这种方式降低网络流量的可疑性。

CA证书如下所示,从3个证书的有效期来看,我们推测此次活动的开始时间在2022.10.7之后。

Step2: 获取XTEA密钥

Bot和C2建立SSL通信之后,Bot通过以下代码片段向C2请求XTEA密钥。

它的处理逻辑为:

Bot向C2发送64字节数据,格式为"设备信息长度字串的长度(xor 5) + 设备信息长度字串(xor 5) + 随机数据"Bot从C2接收32字节数据,从中得到16字节的XTEA KEY,获取KEY的等效的python代码如下所示:XOR_KEY=5 def get_key(rand_bytes): offset = (ord(rand_bytes[0]) ^ XOR_KEY) % 15 return rand_bytes[(offset+1):(offset+17)]Step3: 向C2上报XTEA加密的设备信息

Bot使用Step2获得的XTEA KEY 对设备信息进行加密,并上报给C2。由于设备信息较多,一般需要分块发送,Bot一次最多发送4052字节,而C2则会回复已接受的字节数。

另外值得一提的是,XTEA加密只在Step3中使用,后续的Step4中网络流量仅仅使用SSL协商好的加密加密套件,不再使用XTEA。

Step4: 等待执行指令(xdr33新增功能)

当设备信息上报完毕后,C2向Bot发送8字节的本周期任务次数N,若N等于0就休眠一定时间,进入下一个周期的Beacon Task;反之就下发264字节的任务。Bot接收到任务后,对其进行解析,并执行相应的指令。

支持的指令如下表所示:

INDEX

FUNCTION

0x01

Download File

0x02

Execute CMD with fake name "[kworker/3:1-events]"

0x03

Update

0x04

Upload File

0x05

Delete

0x08

Launch Shell

0x09

Socket5 Proxy

0x0b

Update BEACONINFO

网络流量示例实际中xdr33产生的step2流量step3中的交互,以及step4的流量我们从中能得到什么信息呢?设备信息长度字串的长度,0x1 ^ 0x5 = 0x4设备信息长度,0x31,0x32,0x37,0x35 分别 xor 5得到 4720tea key 2E 09 9B 08 CF 53 BE E7 A0 BE 11 42 31 F4 45 3AC2会确认BOT上报的设备信息长度,4052+668 = 4720,和第2点是能对应上的本周期任务数00 00 00 00 00 00 00 00,即无任务,所以不会下发264字节的具体任务

关于加密的设备信息,可以通过以下代码进行解密,以解密前8字节65 d8 b1 f9 b8 37 37 eb为例,解密后的数据为00 22 00 14 42 5A 68 39,包含了beacon_header_version + os+ bzip magic,和前面的分析能够一一对应。

import hexdumpimport structdef xtea_decrypt(key,block,n=32,endian="!"):    v0,v1 = struct.unpack(endian+"2L", block)    k = struct.unpack(endian+"4L",key)    delta,mask = 0x9e3779b9,0xffffffff    sum = (delta * n) & mask    for round in range(n):        v1 = (v1 - (((v0<<4 ^ v0>>5) + v0) ^ (sum + k[sum>>11 & 3]))) & mask        sum = (sum - delta) & mask        v0 = (v0 - (((v1<<4 ^ v1>>5) + v1) ^ (sum + k[sum & 3]))) & mask    return struct.pack(endian+"2L",v0,v1)def decrypt_data(key,data):    size = len(data)    i = 0    ptext = b''    while i < size:        if size - i >= 8:            ptext += xtea_decrypt(key,data[i:i+8])        i += 8    return ptextkey=bytes.fromhex("""2E 09 9B 08 CF 53 BE E7  A0 BE 11 42 31 F4 45 3A""")enc_buf=bytes.fromhex("""65 d8 b1 f9 b8 37 37 eb""")hexdump.hexdump(decrypt_data(key,enc_buf))
Trigger Task

Trigger主要功能是监听所有流量,等待特定格式的Triggger IP报文,当报文以及隐藏在报文中的Trigger Payload通过层层校验之后,Bot就和Trigger Payload中的C2建立通信,等待执行下发的指令。

0x1: 监听流量

使用函数调用socket( PF_PACKET, SOCK_RAW, htons( ETH_P_IP ) ),设定RAW SOCKET捕获IP报文,再通过以下代码片段对IP报文处理,可以看出Tirgger支持TCP,UDP,报文Payload最大长度为472字节。这种流量嗅探的实现方式会加大CPU的负载,事实上在socket上使用BPF-Filter效果会更好。

0x2: 校验Trigger报文

符合长度要求的TCP,UDP报文使用相同的处理函数check_payload进行进一步校验,

check_payload的代码如下所示:

可以看出它的处理逻辑:

使用CRC16/CCITT-FALSE算法计算报文中偏移8到92的CRC16值,得到crcValue通过crcValue % 200+ 92得到crcValue在在报文中的偏移值,crcOffset校验报文中crcOffset处的数据是否等于crcValue,若相等进入下一步校验报文中crcOffset+2处的数据是否是127的整数倍,若是,进入下一步Trigger_Payload是加密的,起始位置为crcOffset+12,长度为29字节。Xor_Key的起始位置是crcValue%55+8,将2者逐字节XOR,就得到了Trigger_Paylaod

至此可以确定Trigger报文格式是这样的:

0x3: 校验 Trigger Payload

如果Trigger报文通过校验,则通过check_trigger函数继续对Trigger Payload进行校验

可以看出它的处理逻辑:

取出Trigger Payload最后2字节,记作crcRaw将Trigger Payload最后2字节置0,计算其CRC16,记作crcCalc比较crcRaw,crcCalc,若相等,说明Trigger Payload在结构上是有效的

接着计算过Trigger Payload中的key的SHA1,和Bot中硬编码的SHA1 46a3c308401e03d3195c753caa14ef34a3806593进行比对。如果相等,说明Trigger Payload在内容是也是有效的,可以进入到最后一步,和Trigger Payload中的C2建立通信,等待执行其下发的指令。

至此可以确定Trigger Payload的格式是这样的:

0x4: 执行Trigger C2的指令

当一个Trigger报文通过层层校验之后,Bot就主动和Trigger Payload中指定的C2进行通信,等待执行C2下发指令。

支持的指令如下表所示:

INDEX

FUNCTION

0x00,0x00a

Exit

0x01

Download File

0x02

Execute CMD

0x04

Upload File

0x05

Delete

0x06

Shutdown

0x08

Launch SHELL

0x09

SOCKET5 PROXY

0x0b

Update BEACONINFO

值得一提的是,Trigger C2与Beacon C2在通信的细节上有所不同。Bot与Trigger C2在建立SSL隧道之后,会使用Diffie-Helllman密钥交换以建立共享密钥,这把钥匙用于AES算法创建第二层加密。

实验

为了验证Trigger部分逆向分析的正确性,我们对xdr33的SHA1值进行了Patch,填入了NetlabPatched,Enjoy! 的SHA1,并实现了附录的GenTrigger代码,用以产生UDP类型Trigger 报文。

我们在虚拟机192.168.159.133运行Patch后的xdr33样本,构造C2为192.168.159.128:6666的Trigger Payload,并以UDP的方式发送给192.168.159.133。最终效果如下,可以看到xdr33所在的implanted host在收到UDP Trigger报文后,和我们预想中的一样,向预设的Trigger C2发起了通信请求,Cool!

联系我们

至此xdr33的分析告一段落,这是我们目前掌握的关于这个魔改攻击套件的情况。如果社区有更多线索,以及感兴趣的读者,可以在 twitter 或者通过邮件netlab[at]360.cn联系我们。

原文地址:

标签: #c语言获取mac地址siocgifhwaddr