3

Mirai 源码分析与样本分析

 1 year ago
source link: https://scorpionre.github.io/2022/11/11/mirai/#Mirai%E6%A0%B7%E6%9C%AC%E5%88%86%E6%9E%90
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Scorpion

Mirai 源码分析与样本分析

Created2022-11-11|Updated2023-03-12|malware
Word count:1.6k|Reading time:5min|Post View:1

Mirai 源码分析

大概看了下整体结构和流程,然后细看了一下加解密部分。

代码结构:

loader/src   将payload上传到受感染的设备
mirai/bot 在受感染设备上运行的恶意payload
mirai/cnc 恶意者进行控制和管理的接口
mirai/tools 提供的一些工具

其中,cnc部分是Go语言编写的,余下都是C语言

整体网络拓扑关系如下图所示,受感染的设备扫描其他可能受感染的设备,扫描到之后就讲设备信息等提供给 loader,loader 将 payload 下载到可能受感染的设备上,比如宏病毒,js 下载者等。被感染的设备与 c2 服务器连接,并向特定受害者发起 ddos 攻击。

loader

主要功能是向感染设备上传(wget、tftp、echo 方式)对应架构的 payload 文件

headers/       头文件目录
binary.c 将bins目录下的文件读取到内存中,以echo方式上传payload文件时用到
connection.c 判断loader和感染设备telnet交互过程中的状态信息
main.c loader主函数
server.c 向感染设备发起telnet交互,上传payload文件
telnet_info.c 解析约定格式的telnet信息
util.c 一些常用的公共函数

1)通过待感染节点的 telnet 用户名和密码成功登录;

2)执行 /bin/busybox ps,根据返回结果 kill 掉某些特殊进程;

3)执行 /bin/busybox cat /proc/mounts,根据返回结果切换到可写目录;

4)执行 /bin/busybox cat /bin/echo,通过返回结果解析 /bin/echo 这个 ELF 文件的头部来判断体系架构,即其中的 e_machine 字段;

5)选择一种方式上传对应的 payload 文件,当然首先需要进行判断

6)执行 payload 并清理

payload

发起 DoS 攻击以及扫描其它可能受感染的设备,代码在 mirai/bot 目录,可简单划分为如下几个模块

  1. scanner:扫描其它可能受感染的设备,如果能满足 telnet 弱口令登录则将结果进行上报,恶意者主要借此扩张僵尸网络
  2. attack:解析下发的攻击命令并发动 DoS 攻击
  3. killer:此模块主要有两个作用,其一是关闭特定的端口并占用,另一是删除特定文件并 kill 对应进程,简单来说就是排除异己
  4. public:主要是一些常用的公共函数,供其它几个模块调用

table.c 中的 table_unlock_valtable_retrieve_val 和 table_lock_val 函数组合,即获取 table 中的数据,程序中用到的一些信息是硬编码后保存到 table 中的,如果获取就要用到这个组合,其中涉及到简单的异或加密和解密

/******table.c******
*处理硬编码在table中的数据
*/
//初始化table中的成员
void table_init(void);
//解密table中对应id的成员
void table_unlock_val(uint8_t id);
//加密table中对应id的成员
void table_lock_val(uint8_t id);
//取出table中对应id的成员
char *table_retrieve_val(int id, int *len);
//向table中添加成员
static void add_entry(uint8_t id, char *buf, int buf_len);
//和密钥key进行异或操作,即table中数据的加密或解密
static void toggle_obf(uint8_t id);

一个具体的例子如下所示。所以加密字符串可以寻找类似的 \x

//保存到table中的硬编码信息
add_entry(TABLE_EXEC_SUCCESS, "\x4E\x4B\x51\x56\x47\x4C\x4B\x4C\x45\x02\x56\x57\x4C\x12\x22", 15);

//调用table_unlock_val解密
//初始化key,其中table_key = 0xdeadbeef;
uint8_t k1 = table_key & 0xff, //0xef
k2 = (table_key >> 8) & 0xff, //0xbe
k3 = (table_key >> 16) & 0xff, //0xad
k4 = (table_key >> 24) & 0xff; //0xde
//循环异或
for (i = 0; i < val->val_len; i++)
{
val->val[i] ^= k1;
val->val[i] ^= k2;
val->val[i] ^= k3;
val->val[i] ^= k4;
}

/*解密后的信息:listening tun0
*这时调用table_retrieve_val就可以获取到所需信息
*最后调用table_lock_val加密,同table_unlock_val调用,利用的是两次异或后结果不变的性质
*不过考虑到异或的交换律和结合律,上述操作实际上也就相当于各字节异或一次0x22
*/

cnc 目录主要提供用户管理的接口、处理攻击请求并下发攻击命令

admin.go      处理管理员登录、创建新用户以及初始化攻击
api.go 向感染的bot节点发送命令
attack.go 处理用户的攻击请求
clientList.go 管理感染的bot节点
database.go 数据库管理,包括用户登录验证、新建用户、处理白名单、验证用户的攻击请求
main.go 程序入口,开启23端口和101端口的监听

tools

tools 目录主要提供了一些工具,相应的功能如下

enc.c         对数据进行异或加密处理
nogdb.c 通过修改elf文件头实现反gdb调试
scanListen.go 监听payload(bot)扫描后上报的telnet信息,并将结果交由loader处理
single_load.c 另一个loader实现
wget.c 实现了wget文件下载

enc.c 中 table_key = 0xdeadbeef 被硬编码到里面,不过可能不是所有样本都这样(?

加解密逻辑和 table.c 中的基本一样

int main(int argc, char **args)
{
**************if (argc != 3)
{
printf("Usage: %s <string | ip | uint32 | uint16 | uint8 | bool> <data>\n", args[0]);
return 0;
}
// ...**************
printf("XOR'ing %d bytes of data...\n", len);
data = x(data, len);
for (i = 0; i < len; i++)
printf("\\x%02X", ((unsigned char *)data)[i]);
printf("\n");
}

void *x(void *_buf, int len)
{
unsigned char *buf = (char *)_buf, *out = malloc(len);
int i;
uint8_t k1 = table_key & 0xff,
k2 = (table_key >> 8) & 0xff,
k3 = (table_key >> 16) & 0xff,
k4 = (table_key >> 24) & 0xff;

for (i = 0; i < len; i++)
{
char tmp = buf[i] ^ k1;

tmp ^= k2;
tmp ^= k3;
tmp ^= k4;

out[i] = tmp;
}

return out;
}

https://github.com/jgamblin/Mirai-Source-Code/blob/master/mirai/tools/enc.c

https://paper.seebug.org/142/#21-payload

Mirai 样本分析

MD5: 9dd6dd5bd577226323ba207c5e1127e2

joesandbox : https://www.joesandbox.com/analysis/683525?idtype=analysisid#iocs

为数不多的 ip 地址可以直接搜索到的样本

主要加密函数如下图所示,和源码的差不多

密钥和源码一样

应该还是可以先做针对通用的:已知密文的字符串特征(\x…), 密钥(0xdeadbeef), 然后解密之后再匹配 ip 地址或域名等。 针对更复杂的话,可能需要针对不同的样本实现方式再进一步分析。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK