概述
“海莲花”,又名APT32和OceanLotus,是疑似越南背景的黑客组织。该组织至少自2012年开始活跃,长期针对中国能源行业、海事机构、边防机构、卫生部门、海域建设部门、科研院所和航运企 业等进行网络攻击。除中国外,“海莲花”的目标还包含全球的政府、军事机构和大型企业,以及本 国的媒体、人权和公民社会等相关的组织和个人。在历史攻击手法中,“海莲花”一直在尝试不同方法以实现在目标系统上执行恶意代码和绕过安全检 测。此外,在2020年“海莲花”组织也开始注重资产侧的流量隐藏,利用攻击手段拿下的国内外 IoT、OA服务器作为流量中转。
本样本针对Linux x86架构
样本信息
gvfsd-helper |
(n/a) – 133632bytes |
MD5 |
1d45cd2c1283f927940c099b8fab593b |
SHA1 |
7c6665aaba3b7da391ca8a6dd152bd32fafbad88 |
SHA256 |
a18bec90b2b6185362eeb67c516c82dd34cd8f6a7423875921572e97ae1668b0 |
控制指令
0x1B25503 |
在本进程内以dll注入的方式运行插件(回传payload数据为成功标志) |
0x25D5082 |
在本进程内以dll注入的方式运行插件(回payload数据为空) |
0x2E25992 |
传递文件、插件,写入文件内容 |
0x2CD9070 |
查看本进程是否加载插件 |
0x208307A |
无功能传送回文件头 |
0x25360EA |
读取文件内容返回C2服务器 |
0x1532E65 |
卸载关闭插件 |
0x12B3629 |
循环删除文件或插件 |
0x138E3E6 |
退出进程 |
0x17B1CC4 |
无功能传送回文件头 |
0x18320E0 |
返回设备信息 |
加解密分析
Send/recv的内容header与key经过异或1b和循环右移3位加密,后面的payload为可选加密,可选为zlib1.2.8版本加密或使用key经过AES-CBC加密或使用zlib与AES-CBC双加密,内部配置数据通过AES-CBC,右移4位双加密,key为14 ba ee 23 8f 72 1a 6a
行为分析
静态内容解密
本地硬编码数据解密:
第一次aes解密后需要排除后面固定七字节填充和前面八字节干扰项
通信传输数据解密:
加几个字节用于后面zlib解压缩
判断root与普通用户,普通用户创建守护进程且必须在隐藏文件夹下才能执行后续控制,root则直接控制
解密后的文件目录
拼接后路径
System函数 执行下面命令
(grep -q 'gvfsd-helper' '/home/galashark/.bashrc' || echo "# AddGNOME's helper designed to workwith the I/O abstraction of GIO.# this environment variable is set, gvfsd will not start the fuse filesystem.if[ -d ${HOME} ]; then..${HOME}/.gvfsd/.profile/gvfsd-helper.fi." '/home/galashark/.bashrc')>/dev/null 2>&1
释放文件为同一个文件
Autostart持久化服务文件
判断位置,只有到了指定位置才能执行,也就是后面的释放位置,必须通过样本自定义服务启动
流量分析
第一阶段初始化socket后向C2服务器发送上线包,并recv等待C2服务器发送确认包
第二阶段持续recv,服务器close则退出,继续第一阶段
每一次通信接收一次header后可选接收至多两次recv
ReuseStruct [0] = header
ReuseStruct [1] = key
ReuseStruct [2] = payload
Header与key都用rotate加密,payload使用可选加密方式
加密为 首先异或1b再循环右移3个字节
0x52 header
(_int8)header+0x0 = rand()
(_int32)Header + 0x5 = 初始化模块初始化为0x4FB0CB1 (一定)
(_int32) header + 0x9 = size_payload
(_int16) header + 0xd = size_key
(_int32) header + 0xf = flag_switch 控制指令(上线确认包必须72 02 17 02)
(_int8) header + 0x13 = flag_decrypt 服务器发送给样本时样本需要进行解密选项
(_int32) header + 0x14 =flag_processfaild
(_int32)header + 0x19 = 当前出错信息
(_int8)Recvheader + 0x1d = flag_Encrypt 样本发送给服务器的加密选项
(_int32)Recvheader + 0x1e = size zlib解压缩后的大小
*(_BYTE *)(header + 0x42) = checkmechine()检测是64位还是32位 200 | 77
Header->flag_decrypt
解密成功继续执行控制指令,解密失败则直接send服务器失败
(_int8)Recvheader + 0x13 Flag_decrypt ==0x3d Aes单加密
(_int8)Recvheader + 0x13 Flag_decrypt ==0x4d Zlib单加密
(_int8)Recvheader + 0x13 Flag_decrypt ==0x7f 不加密
(_int8)Recvheader + 0x13 Flag_decrypt ==0xc2 AES Zlib双加密
Header->flag_processfaild
0x1206420 执行成功标志
0x1956B1D执行失败标志
0x1FBDA6F执行失败标志
0x1B7A437什么都没有标志
Recv的bufstruct与Send的bufstruct复用
Send 发送的消息是分两次send。第一次send发送header+key
如果payload有内容则再发送一次payload
动态通信分析
上线包流量
构造确认包header
加密后header内容为
构造控制指令0x18320E0返回设备信息,双方都不使用加密方式进行
前四个字节为length,后面为控制内容
选择的7f为明文传送所以发送与回显都是数据明文
关于pcap通信包获取关注私信回复:海莲花双头龙pcap
原文始发于微信公众号(CrackME安全):海莲花双头龙分析报告