Kimsuky组织最新Linux.Gomir后门功能&通信模型剖析及攻击场景复现
Contents
概述
近期,笔者在浏览威胁情报的时候,发现symantec公司的Threat Hunter Team团队于2024年5月16日发布了一篇报告,报告对Kimsuky组织使用的Linux后门程序进行了简单的介绍。
由于在笔者的印象中,好像此前并未见过Kimsuky组织使用Linux后门,因此,笔者也觉得比较有意思,决定对其进行详细的分析研究:
Golang语言编写:结合逆向分析,笔者发现此Linux后门是由Golang语言编写,虽然对Golang语言编写的二进制程序分析不多,但所幸此后门反编译后的代码含有符号信息,因此,可以基于符号信息对样本功能进行梳理;
动态调试:为了能够详细的对后门程序的功能及运行逻辑进行梳理,笔者尝试了多种方法对其进行动态调试,最终发现还是使用GDB对其进行调试比较稳定;
通信模型初探究:像之前的文章一样,笔者在分析此后门程序时,想对其通信模型进行深入探究,但是在动态调试的过程中,笔者发现Golang语言编写的Linux程序的某些变量数据不是特别好追踪,因此,笔者也是尝试了多次,发现一时有点不知从何下手。
扩线分析:对此后门中的相关特征信息、码址信息进行关联扩线,笔者发现此Linux后门还对应的有Windows版本;此外,笔者还发现Kimsuky组织此前还曾使用过此后门C&C地址的C段IP。
自启动
install参数启动
通过分析,发现当样本以install参数启动时,则样本将执行如下操作用于将自身安装为服务:
调用getegid32函数检查是否以root权限运行;
将自身程序复制至/var/log/syslogd路径;
创建systemd 服务,服务名为syslogd;
执行如下指令启动服务:systemctl daemon-reload、systemctl reenable syslogd、systemctl start syslogd
删除原始程序;
相关操作截图如下:
相关代码截图如下:
创建定时任务
通过分析,发现当样本运行后,样本将调用getegid32函数检查是否以非root权限运行,若为非root权限运行,则样本将执行如下操作用于创建定时任务:
创建cron.txt文件,并在其中添加如下内容:@reboot 程序路径(在系统启动时执行程序);
执行/bin/sh -c crontab -l命令,并将命令输出追加到cron.txt文件中;
执行如下命令更新crontab配置:${SHELL} -c crontab cron.txt;
相关代码截图如下:
通信加密算法
通过分析,发现在样本通信过程中,发现样本将对通信数据进行字节加密,然后再对其进行Base64编码。
相关代码截图如下:
字节加密运算代码截图如下:
字节解密运算代码截图如下:
接收远控指令
通过分析,发现样本运行后,将向C&C服务器发起POST请求,用于接收远控指令,相关通信载荷截图如下:
内置外链地址截图如下:
相关代码截图如下:
远控功能
远控指令(16进制) 远控指令 远控功能 备注
Info == 0x3431 14 添加并启动sock5代理 mirror_En_En_Kernel_Process_SocksAdd
Info == 0x3531 15 返回sock5代理列表 Socks list\r\n
Info == 0x3231 12 休眠 mirror_En_En_Kernel_Process_Hibernate
Info == 0x3331 13 响应消息 "Not implemented on Linux!"
Info == 0x3033 30 上传文件 mirror_En_En_Kernel_Process_Upload
Info == 0x3133 31 下载文件 mirror_En_En_Kernel_Process_Download
Info == 0x3031 10 配置shell命令的执行程序 "CmdPath: "
Info == 0x3131 11 配置shell命令的终端代码页 "Codepage: "
Info == 0x3730 07 返回进程路径 mirror_En_En_Kernel_Process_Where
Info == 0x3830 08 获取目录信息 mirror_En_En_Kernel_Process_Dirsize
Info == 0x3930 09 获取系统信息 mirror_En_En_Kernel_Process_GetInfo
Info == 0x3530 05 探测网络节点 mirror_En_En_Kernel_Process_Conn
Info == 0x3630 06 退出进程 mirror_En_En_Kernel_Process_Exit
Info == 0x3330 03 查看当前工作目录 mirror_En_En_Kernel_Process_Pwd
Info == 0x3430 04 更改当前工作目录 mirror_En_En_Kernel_Process_Cd
Info == 0x3130 01 休眠 mirror_En_En_Kernel_Process_Sleep
Info == 0x3230 02 执行shell命令 mirror_En_En_Kernel_Process_Cmd
添加并启动sock5代理
通过分析,发现当远控指令为14(0x3431)时,样本将根据远控指令内容添加sock5代理,然后将开启sock5代理,相关代码截图如下:
进一步分析,发现此样本内部调用sock5代理的核心代码为https://github.com/kost/revsocks项目代码,相关对比代码截图如下:
返回sock5代理列表
通过分析,发现当远控指令为15(0x3531)时,样本将根据远控指令内容返回sock5代理列表,相关代码截图如下:
上传文件
通过分析,发现当远控指令为30(0x3033)时,样本将根据远控指令内容上传指定文件,相关代码截图如下:
下载文件
通过分析,发现当远控指令为30(0x3033)时,样本将根据远控指令内容下载指定文件,相关代码截图如下:
获取系统信息
通过分析,发现当远控指令为09(0x3930)时,样本将根据远控指令内容返回系统信息,系统信息包括:主机名、用户名、系统硬件信息及网络信息等。相关代码截图如下:
探测网络节点
通过分析,发现当远控指令为05(0x3530)时,样本将根据远控指令内容向指定服务器建立TCP连接,用于探测网络节点。相关代码截图如下:
执行shell命令
通过分析,发现当远控指令为02(0x3230)时,样本将根据远控指令内容执行指定shell命令。相关代码截图如下:
同源分析
基于网络调研,笔者发现此样本与奇安信威胁情报中心于2024年01月30日发布的《软件安装包伪装下的Kimsuky(APT-Q-2)窃密行动》报告中的后门程序同源,同源内容主要包括:
运行逻辑相同:均会根据运行参数实现自启动
通信载荷结构相同
远控指令编号及函数名相同
攻击者资产剖析
尝试对C&C站点(216.189.159.34)进行分析,笔者发现此站点当前已经挂掉,基于网络调研,笔者发现微步云沙箱中记录了此样本的通信数据(数据包通信时间:2024年1月29日),相关截图如下:
尝试对其响应载荷进行分析,发现此响应载荷结构并非样本远控指令对应的响应载荷内容,因此,推测此载荷为木马C&C静默状态下的响应数据。
进一步分析,笔者发现此C&C地址的C段IP早在2020年11月就已存在被Kimsuky组织利用的记录,相关报告截图如下:
后续
在上半部分文章中,笔者对Kimsuky组织使用的最新Linux.Gomir后门的功能进行了简单剖析,同时也对其通信模型剖析进行了简单尝试,最后由于动态调试的原因,一时未能对其有所突破。
虽然暂时未能对其通信模型进行突破,笔者也曾自我怀疑的一会。。。
所以,在写完上半部分文章后,笔者又开始尝试对其通信模型进行剖析,不过好在功夫不负有心人,笔者最终还是成功对其通信模型梳理清楚,同时还基于其通信模型,模拟构建了此后门所对应的控制端C&C站点程序。
为了能够完整复现Linux.Gomir后门的攻击场景,笔者从如下角度开展了研究分析工作:
一个小坑:结合网络中的分析报告,才发现是由于笔者动态调试时赋值的数据载荷长度不够,导致一直无法进入后续远控功能代码,让笔者误以为后门功能分析错误。
关键代码剖析:结合逆向分析,对此Linux.Gomir后门的通信关键代码进行详细剖析。
后门C&C站点效果:基于模拟构建的Linux.Gomir后门C&C站点程序,模拟复现Linux.Gomir后门的远程控制行为。
后门通信模型剖析:结合动态调试,研究分析Linux.Gomir后门的通信模型。
模拟构建后门C&C站点:构建Linux.Gomir后门C&C站点。
一个小坑
可能是技术思维习惯了,笔者在对此后门程序进行分析的过程中,遇到问题总是容易陷入在自己想办法解决的状态,所以在笔者冷静了几天,再次对此后门程序进行剖析的过程中,笔者发现:原来在symantec公司的Threat Hunter Team团队发布的报告中,里面就有一句话对其通信数据结构进行了简单描述,相关截图如下:
基于报告再次回想对比分析,笔者发现,其实笔者的初探分析结果是与其相同的:笔者也曾使用S开头的字符串+Base64数据作为响应数据,但是比较遗憾的是,笔者构建的Base64解码前的数据一直是4至5字节,因此导致后门程序在运行过程中一直无法进入处理远控指令的逻辑代码处。
结合报告内容,笔者才突然醒悟,原来是我构造的通信数据载荷太小了。。。有点小无语。。。
关键代码剖析
POST请求
通过分析,发现此后门程序运行后,将调用mirror_common_HttpPostForm函数发起POST请求,相关代码截图如下:
构建模拟通信环境,提取HTTP POST请求通信数据包,梳理发现POST请求载荷结构为:
a[9个随机字符]=2&b[9个随机字符]=g-[ID信息]1&c[9个随机字符]=
相关通信数据包截图如下:
相关代码截图如下:
POST请求响应
通过分析,发现POST请求成功后,此后门程序将调用io.ReadAll函数从HTTP响应数据中提取载荷内容,相关代码截图如下:
判断载荷标志
通过分析,发现此后门程序在开始对其通信载荷进行解密前,将对其载荷标志进行判断,判断其是否是以S字符开头的字符串,相关代码截图如下:
Base64编码
通过分析,发现若通信载荷是以S字符开头的字符串,则此后门程序将对其S字符后续的字符串内容进行Base64解码,相关代码截图如下:
自定义加密算法
通过分析,发现若成功对其S字符后续的字符串进行Base64解码,则此后门程序将调用自定义加解密算法对其通信载荷进行字节解密,相关代码截图如下:
提取远控指令
通过分析,发现成功对其通信载荷进行字节解密后,则此后门程序将对其解密后的载荷数据长度进行判断,若长度大于等于2,则样本将提取前两个字节数据作为远控指令,相关代码截图如下:
后门C&C站点效果
结合逆向分析,笔者对此后门程序的通信模型进行了简单梳理,并尝试模拟构建了一款后门控制端C&C站点程序,经过简单测试,可有效的与Kimsuky组织的最新Linux.Gomir后门进行交互。
C&C站点程序启用后,我们可正常访问其WEB服务,相关截图如下:
Kimsuky组织最新Linux.Gomir后门上线后,即可开展正常的远控行为,相关截图如下:
通信过程中C&C站点中内置的远控指令如下:
通信过程中C&C站点记录的远控指令响应结果如下:
F:\GolandProjects\awesomeProject5>awesomeProject5.exe
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
Send: 3133@
[GIN] 2024/05/25 - 17:57:39 …
近期,笔者在浏览威胁情报的时候,发现symantec公司的Threat Hunter Team团队于2024年5月16日发布了一篇报告,报告对Kimsuky组织使用的Linux后门程序进行了简单的介绍。
由于在笔者的印象中,好像此前并未见过Kimsuky组织使用Linux后门,因此,笔者也觉得比较有意思,决定对其进行详细的分析研究:
Golang语言编写:结合逆向分析,笔者发现此Linux后门是由Golang语言编写,虽然对Golang语言编写的二进制程序分析不多,但所幸此后门反编译后的代码含有符号信息,因此,可以基于符号信息对样本功能进行梳理;
动态调试:为了能够详细的对后门程序的功能及运行逻辑进行梳理,笔者尝试了多种方法对其进行动态调试,最终发现还是使用GDB对其进行调试比较稳定;
通信模型初探究:像之前的文章一样,笔者在分析此后门程序时,想对其通信模型进行深入探究,但是在动态调试的过程中,笔者发现Golang语言编写的Linux程序的某些变量数据不是特别好追踪,因此,笔者也是尝试了多次,发现一时有点不知从何下手。
扩线分析:对此后门中的相关特征信息、码址信息进行关联扩线,笔者发现此Linux后门还对应的有Windows版本;此外,笔者还发现Kimsuky组织此前还曾使用过此后门C&C地址的C段IP。
自启动
install参数启动
通过分析,发现当样本以install参数启动时,则样本将执行如下操作用于将自身安装为服务:
调用getegid32函数检查是否以root权限运行;
将自身程序复制至/var/log/syslogd路径;
创建systemd 服务,服务名为syslogd;
执行如下指令启动服务:systemctl daemon-reload、systemctl reenable syslogd、systemctl start syslogd
删除原始程序;
相关操作截图如下:
相关代码截图如下:
创建定时任务
通过分析,发现当样本运行后,样本将调用getegid32函数检查是否以非root权限运行,若为非root权限运行,则样本将执行如下操作用于创建定时任务:
创建cron.txt文件,并在其中添加如下内容:@reboot 程序路径(在系统启动时执行程序);
执行/bin/sh -c crontab -l命令,并将命令输出追加到cron.txt文件中;
执行如下命令更新crontab配置:${SHELL} -c crontab cron.txt;
相关代码截图如下:
通信加密算法
通过分析,发现在样本通信过程中,发现样本将对通信数据进行字节加密,然后再对其进行Base64编码。
相关代码截图如下:
字节加密运算代码截图如下:
字节解密运算代码截图如下:
接收远控指令
通过分析,发现样本运行后,将向C&C服务器发起POST请求,用于接收远控指令,相关通信载荷截图如下:
内置外链地址截图如下:
相关代码截图如下:
远控功能
远控指令(16进制) 远控指令 远控功能 备注
Info == 0x3431 14 添加并启动sock5代理 mirror_En_En_Kernel_Process_SocksAdd
Info == 0x3531 15 返回sock5代理列表 Socks list\r\n
Info == 0x3231 12 休眠 mirror_En_En_Kernel_Process_Hibernate
Info == 0x3331 13 响应消息 "Not implemented on Linux!"
Info == 0x3033 30 上传文件 mirror_En_En_Kernel_Process_Upload
Info == 0x3133 31 下载文件 mirror_En_En_Kernel_Process_Download
Info == 0x3031 10 配置shell命令的执行程序 "CmdPath: "
Info == 0x3131 11 配置shell命令的终端代码页 "Codepage: "
Info == 0x3730 07 返回进程路径 mirror_En_En_Kernel_Process_Where
Info == 0x3830 08 获取目录信息 mirror_En_En_Kernel_Process_Dirsize
Info == 0x3930 09 获取系统信息 mirror_En_En_Kernel_Process_GetInfo
Info == 0x3530 05 探测网络节点 mirror_En_En_Kernel_Process_Conn
Info == 0x3630 06 退出进程 mirror_En_En_Kernel_Process_Exit
Info == 0x3330 03 查看当前工作目录 mirror_En_En_Kernel_Process_Pwd
Info == 0x3430 04 更改当前工作目录 mirror_En_En_Kernel_Process_Cd
Info == 0x3130 01 休眠 mirror_En_En_Kernel_Process_Sleep
Info == 0x3230 02 执行shell命令 mirror_En_En_Kernel_Process_Cmd
添加并启动sock5代理
通过分析,发现当远控指令为14(0x3431)时,样本将根据远控指令内容添加sock5代理,然后将开启sock5代理,相关代码截图如下:
进一步分析,发现此样本内部调用sock5代理的核心代码为https://github.com/kost/revsocks项目代码,相关对比代码截图如下:
返回sock5代理列表
通过分析,发现当远控指令为15(0x3531)时,样本将根据远控指令内容返回sock5代理列表,相关代码截图如下:
上传文件
通过分析,发现当远控指令为30(0x3033)时,样本将根据远控指令内容上传指定文件,相关代码截图如下:
下载文件
通过分析,发现当远控指令为30(0x3033)时,样本将根据远控指令内容下载指定文件,相关代码截图如下:
获取系统信息
通过分析,发现当远控指令为09(0x3930)时,样本将根据远控指令内容返回系统信息,系统信息包括:主机名、用户名、系统硬件信息及网络信息等。相关代码截图如下:
探测网络节点
通过分析,发现当远控指令为05(0x3530)时,样本将根据远控指令内容向指定服务器建立TCP连接,用于探测网络节点。相关代码截图如下:
执行shell命令
通过分析,发现当远控指令为02(0x3230)时,样本将根据远控指令内容执行指定shell命令。相关代码截图如下:
同源分析
基于网络调研,笔者发现此样本与奇安信威胁情报中心于2024年01月30日发布的《软件安装包伪装下的Kimsuky(APT-Q-2)窃密行动》报告中的后门程序同源,同源内容主要包括:
运行逻辑相同:均会根据运行参数实现自启动
通信载荷结构相同
远控指令编号及函数名相同
攻击者资产剖析
尝试对C&C站点(216.189.159.34)进行分析,笔者发现此站点当前已经挂掉,基于网络调研,笔者发现微步云沙箱中记录了此样本的通信数据(数据包通信时间:2024年1月29日),相关截图如下:
尝试对其响应载荷进行分析,发现此响应载荷结构并非样本远控指令对应的响应载荷内容,因此,推测此载荷为木马C&C静默状态下的响应数据。
进一步分析,笔者发现此C&C地址的C段IP早在2020年11月就已存在被Kimsuky组织利用的记录,相关报告截图如下:
后续
在上半部分文章中,笔者对Kimsuky组织使用的最新Linux.Gomir后门的功能进行了简单剖析,同时也对其通信模型剖析进行了简单尝试,最后由于动态调试的原因,一时未能对其有所突破。
虽然暂时未能对其通信模型进行突破,笔者也曾自我怀疑的一会。。。
所以,在写完上半部分文章后,笔者又开始尝试对其通信模型进行剖析,不过好在功夫不负有心人,笔者最终还是成功对其通信模型梳理清楚,同时还基于其通信模型,模拟构建了此后门所对应的控制端C&C站点程序。
为了能够完整复现Linux.Gomir后门的攻击场景,笔者从如下角度开展了研究分析工作:
一个小坑:结合网络中的分析报告,才发现是由于笔者动态调试时赋值的数据载荷长度不够,导致一直无法进入后续远控功能代码,让笔者误以为后门功能分析错误。
关键代码剖析:结合逆向分析,对此Linux.Gomir后门的通信关键代码进行详细剖析。
后门C&C站点效果:基于模拟构建的Linux.Gomir后门C&C站点程序,模拟复现Linux.Gomir后门的远程控制行为。
后门通信模型剖析:结合动态调试,研究分析Linux.Gomir后门的通信模型。
模拟构建后门C&C站点:构建Linux.Gomir后门C&C站点。
一个小坑
可能是技术思维习惯了,笔者在对此后门程序进行分析的过程中,遇到问题总是容易陷入在自己想办法解决的状态,所以在笔者冷静了几天,再次对此后门程序进行剖析的过程中,笔者发现:原来在symantec公司的Threat Hunter Team团队发布的报告中,里面就有一句话对其通信数据结构进行了简单描述,相关截图如下:
基于报告再次回想对比分析,笔者发现,其实笔者的初探分析结果是与其相同的:笔者也曾使用S开头的字符串+Base64数据作为响应数据,但是比较遗憾的是,笔者构建的Base64解码前的数据一直是4至5字节,因此导致后门程序在运行过程中一直无法进入处理远控指令的逻辑代码处。
结合报告内容,笔者才突然醒悟,原来是我构造的通信数据载荷太小了。。。有点小无语。。。
关键代码剖析
POST请求
通过分析,发现此后门程序运行后,将调用mirror_common_HttpPostForm函数发起POST请求,相关代码截图如下:
构建模拟通信环境,提取HTTP POST请求通信数据包,梳理发现POST请求载荷结构为:
a[9个随机字符]=2&b[9个随机字符]=g-[ID信息]1&c[9个随机字符]=
相关通信数据包截图如下:
相关代码截图如下:
POST请求响应
通过分析,发现POST请求成功后,此后门程序将调用io.ReadAll函数从HTTP响应数据中提取载荷内容,相关代码截图如下:
判断载荷标志
通过分析,发现此后门程序在开始对其通信载荷进行解密前,将对其载荷标志进行判断,判断其是否是以S字符开头的字符串,相关代码截图如下:
Base64编码
通过分析,发现若通信载荷是以S字符开头的字符串,则此后门程序将对其S字符后续的字符串内容进行Base64解码,相关代码截图如下:
自定义加密算法
通过分析,发现若成功对其S字符后续的字符串进行Base64解码,则此后门程序将调用自定义加解密算法对其通信载荷进行字节解密,相关代码截图如下:
提取远控指令
通过分析,发现成功对其通信载荷进行字节解密后,则此后门程序将对其解密后的载荷数据长度进行判断,若长度大于等于2,则样本将提取前两个字节数据作为远控指令,相关代码截图如下:
后门C&C站点效果
结合逆向分析,笔者对此后门程序的通信模型进行了简单梳理,并尝试模拟构建了一款后门控制端C&C站点程序,经过简单测试,可有效的与Kimsuky组织的最新Linux.Gomir后门进行交互。
C&C站点程序启用后,我们可正常访问其WEB服务,相关截图如下:
Kimsuky组织最新Linux.Gomir后门上线后,即可开展正常的远控行为,相关截图如下:
通信过程中C&C站点中内置的远控指令如下:
通信过程中C&C站点记录的远控指令响应结果如下:
F:\GolandProjects\awesomeProject5>awesomeProject5.exe
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
Send: 3133@
[GIN] 2024/05/25 - 17:57:39 …