发布于1小时前1小时 背景与分析边界本文记录一次授权内网排查中的 Windows 远控木马分析过程。终端告警显示,一个伪装成同步组件的 PE 文件在用户登录后启动,并周期性访问外网。分析目标不是运行或复现远控功能,而是确认样本行为、提取配置、还原 C2 通信特征,并给出处置和日志补强方案。以下域名、地址和哈希均为脱敏示例。样本应放在隔离虚拟机中分析,关闭共享剪贴板、共享目录和宿主机网络直通,动态分析流量只接入 FakeNet-NG 或 INetSim。一、现场现象与问题定位受影响主机为 Windows 10,EDR 首先记录到以下异常链路:用户登录后出现进程:C:\Users\Public\Libraries\syncsvc.exe父进程为 taskeng.exe,说明其可能由计划任务启动syncsvc.exe 创建挂起状态的系统进程,随后出现跨进程内存写入被操作进程周期性访问 update-cdn.example.test:443主机上出现名为 Microsoft\Windows\Maintenance\SyncTelemetry 的计划任务现场处置时不要直接双击样本,也不建议第一时间关机。对于存在进程注入的主机,应先隔离网络并保留内存、进程列表、计划任务、注册表和网络连接等证据。mkdir C:\IR copy C:\Users\Public\Libraries\syncsvc.exe C:\IR\syncsvc.bin certutil -hashfile C:\IR\syncsvc.bin SHA256 sigcheck64.exe -accepteula -h -i -m C:\IR\syncsvc.bin schtasks /query /fo LIST /v > C:\IR\schtasks.txt reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run /s > C:\IR\run-hkcu.txt reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run /s > C:\IR\run-hklm.txt netstat -ano > C:\IR\netstat.txt tasklist /v > C:\IR\tasklist.txt wevtutil epl Microsoft-Windows-TaskScheduler/Operational C:\IR\TaskScheduler.evtx本例样本 SHA-256 记为 7c0f...9e21。签名检查显示文件无有效 Authenticode 签名,但版本资源伪造为 Microsoft Sync Service。版本信息不能作为可信依据,应结合签名链、文件来源和行为判断。二、静态逆向:识别加载器和配置区先使用 Detect It Easy、PE-bear、FLOSS 和 capa 做低成本筛查。该样本是 64 位 PE,导入表较小,但能看到 VirtualAlloc、VirtualProtect、CreateProcessW、WriteProcessMemory、GetThreadContext、SetThreadContext、ResumeThread 和 WinHttpOpen 等 API。这个组合通常意味着样本同时具备内存解密、进程操作和 HTTP 通信能力。diec syncsvc.bin floss.exe syncsvc.bin > floss.txt capa.exe -vv syncsvc.bin > capa.txt objdump -x syncsvc.bin > pe-headers.txtPE 节区检查发现:.text 节熵约 6.3,仍能正常反汇编,不像整体加壳.rdata 中存在固定标记 CFG1,后跟长度、单字节密钥和配置密文TLS Directory 不为空,存在早于入口点执行的 TLS Callback编译时间戳与数字签名时间不一致,且时间戳明显早于所使用的 SDK 版本在 Ghidra 中从 CFG1 的交叉引用向上追踪,可以看到初始化函数先读取两字节小端长度,再读取一字节 XOR 密钥,解密后的内容为 UTF-8 JSON。这里的单字节 XOR 只用于隐藏静态字符串,不提供真正的密码学保护。可用以下离线脚本提取配置。脚本只读取文件,不加载 PE,也不会执行样本代码:import json import pathlib import struct import sys raw = pathlib.Path(sys.argv[1]).read_bytes() marker = b"CFG1" pos = raw.find(marker) if pos < 0: raise SystemExit("CFG1 marker not found") base = pos + len(marker) length = struct.unpack_from("<H", raw, base)[0] key = raw[base + 2] enc = raw[base + 3:base + 3 + length] if len(enc) != length: raise SystemExit("truncated configuration") dec = bytes(value ^ key for value in enc) config = json.loads(dec.decode("utf-8")) print(json.dumps(config, ensure_ascii=False, indent=2))执行方式:python extract_cfg.py syncsvc.bin提取结果包含以下字段:hosts:update-cdn.example.test、198.51.100.27port:443path:/api/v2/syncsleep:180jitter:30campaign:FIN-2025-04mutex:Global\SyncTelemetry_7F31需要注意,配置中的 IP、域名和路径只是线索。部分木马会保留已废弃节点,封禁前应结合 DNS、代理日志和实际网络行为确认。三、入口点、持久化与进程注入分析样本真正的初始化逻辑位于 TLS Callback。回调函数先检查互斥体,随后进行简单环境判断,包括处理器数量、物理内存大小和近期用户输入时间。入口点本身只负责创建工作线程,用来干扰只跟踪 AddressOfEntryPoint 的分析流程。持久化函数调用 Task Scheduler COM 接口创建登录触发任务。任务执行路径不是裸文件名,而是:"C:\Users\Public\Libraries\syncsvc.exe" --background对应的现场核查命令:schtasks /query /tn "\Microsoft\Windows\Maintenance\SyncTelemetry" /xml Get-ScheduledTask -TaskPath "\Microsoft\Windows\Maintenance\" | Where-Object {$_.TaskName -eq "SyncTelemetry"} | Format-List *注入部分可从 API 调用链确认:CreateProcessW 以 CREATE_SUSPENDED 创建目标进程VirtualAllocEx 在远程进程申请可写内存WriteProcessMemory 写入解密后的载荷GetThreadContext 和 SetThreadContext 修改线程上下文ResumeThread 恢复目标线程这类行为与进程空洞或线程上下文劫持相近。不能只依据单个 API 判定恶意,因为调试器和安全软件也可能调用这些接口;关键是父子进程关系、签名、目标路径、内存权限变化和后续网络连接是否形成完整证据链。四、动态验证:不直连真实 C2动态分析使用快照虚拟机,网络设置为仅主机模式,由 FakeNet-NG 模拟 DNS、HTTP 和 TLS 服务。不要通过修改 hosts 后直接映射到公网分析机,以免样本利用其他协议绕过。fakenet.exe -c configs\default.ini procmon.exe /BackingFile C:\Analysis\syncsvc.pml x64dbg.exe C:\Analysis\syncsvc.binProcmon 建议设置以下过滤条件:Process Name is syncsvc.exeOperation is RegSetValue、CreateFile、WriteFile 或 Process CreatePath contains TaskCache、System32\Tasks 或 Users\Publicx64dbg 中可在 CreateProcessW、WriteProcessMemory、SetThreadContext、WinHttpConnect 和 WinHttpSendRequest 上设置断点。命中 WinHttpSendRequest 时,应记录请求句柄对应的主机、路径、请求头和缓冲区长度,不要仅搜索明文域名,因为配置可能在运行时才解密。本例木马使用 WinHTTP 发出 HTTPS 请求,请求路径固定为 /api/v2/sync,并带有以下特征:User-Agent 伪装为系统更新组件,但版本号与主机操作系统不匹配自定义头 X-Client-ID,值为主机 GUID 截断后的十六进制字符串心跳间隔约 180 秒,存在正负 30% 抖动POST 请求体前四字节固定为 53 59 4e 43,即 ASCII 的 SYNCTLS 加密场景下,网络侧未必能看到 URI 和自定义头。此时应关联代理解密日志、终端 WinHTTP 事件、DNS 查询和进程网络事件。仅封禁 URI 对未解密流量没有效果。五、内存与日志交叉验证如果 EDR 显示系统进程存在异常外联,应采集内存后再结束进程。使用 Volatility 3 可以检查进程树、网络连接、可疑 VAD 和注入区域:python vol.py -f memory.raw windows.pslist python vol.py -f memory.raw windows.pstree python vol.py -f memory.raw windows.netscan python vol.py -f memory.raw windows.malfind --dump python vol.py -f memory.raw windows.vadinfo --pid 4120重点关注以下现象:映像路径与进程名不一致,或父进程关系不合理私有内存区域同时具备可写和可执行权限内存中的 PE 头不存在于对应磁盘映像网络连接归属于被注入进程,而不是原始 syncsvc.exe线程起始地址落在 Private VAD,而不是已加载模块Windows 日志侧建议关联以下事件:安全日志 4698、4702:计划任务创建或更新TaskScheduler Operational 106、140、200:任务注册和执行Sysmon 1:进程创建及完整命令行Sysmon 3:进程网络连接Sysmon 8:CreateRemoteThread;本例未必触发,因为样本采用线程上下文修改Sysmon 10:Process Access,可发现对目标进程申请高权限句柄Sysmon 13:注册表值修改Sysmon 22:DNS 查询Sysmon 不能完整记录 WriteProcessMemory 的内容,因此 Event ID 10 的 SourceImage、TargetImage、GrantedAccess 和 CallTrace 很关键。建议避免全量记录所有进程访问,否则日志噪声和磁盘压力会很高,可优先记录非系统路径程序访问浏览器、lsass.exe、explorer.exe 和常见系统宿主进程的行为。六、样本级检测规则可以基于配置标记、互斥体和特征路径编写 YARA 规则。规则应至少组合两个相对稳定的特征,避免只依赖单个域名或文件名。rule Win64_SyncTelemetry_RAT_Loader { meta: description = "Detects the analyzed SyncTelemetry RAT loader" scope = "file" strings: $cfg = { 43 46 47 31 } $mutex = "Global\\SyncTelemetry_7F31" ascii wide $uri = "/api/v2/sync" ascii wide $task = "\\Microsoft\\Windows\\Maintenance\\SyncTelemetry" ascii wide $arg = "--background" ascii wide condition: uint16(0) == 0x5A4D and filesize < 5MB and $cfg and 2 of ($mutex, $uri, $task, $arg) }部署前应使用正常软件库做误报测试。CFG1 这类短标记可能出现在无关程序中,所以不能单独作为封禁条件。若样本更新后只替换域名,互斥体、配置结构和任务路径通常比网络 IOC 更耐用。七、处置与修复建议先通过 EDR 或交换机隔离受影响主机,保留管理通道,避免木马继续接收指令。采集内存、样本、计划任务 XML、事件日志、Prefetch、Amcache、Shimcache、SRUM、DNS 缓存和代理日志。在证据保全后删除恶意计划任务和落地文件,同时检查相同用户配置文件及公共目录是否存在副本。若确认发生进程注入或远程命令执行,优先重装或从可信镜像恢复,不建议仅删除文件后继续使用。轮换该主机上登录过的域账号、本地管理员账号、浏览器会话、API Token 和已挂载共享凭据。检索全网相同哈希、互斥体、任务名称、命令行参数、DNS 请求和固定心跳周期。限制普通用户从 Users\Public、AppData 和临时目录执行未签名程序,可结合 AppLocker 或 WDAC 分阶段实施。对服务器和办公终端建立出站访问控制,非必要程序不应直接访问互联网;代理侧保留主机、用户、进程和目的域名的关联字段。清理计划任务时应在取证完成后执行:schtasks /delete /tn "\Microsoft\Windows\Maintenance\SyncTelemetry" /f Remove-Item "C:\Users\Public\Libraries\syncsvc.exe" -Force Get-FileHash "C:\Users\Public\Libraries\syncsvc.exe" -Algorithm SHA256最后一条哈希命令应在删除前执行,实际流程中应先复制留证、计算哈希并记录文件时间,再进行清理。总结远控木马排查不能停留在“发现可疑外联后删除文件”。比较可靠的方法是把静态逆向、动态行为、内存证据和日志关联起来:通过 PE 结构和交叉引用定位配置,通过隔离环境验证持久化与注入链路,再使用终端和网络日志评估影响范围。修复阶段既要清除样本,也要处理被窃取凭据、持久化项、出站控制和日志缺口。对于已经发生内存注入和远程指令执行的终端,可信重建通常比单点清理更稳妥。 逆向分析、样本行为与调试流程示意 网络请求、日志与边界流量分析示意
7分钟前7分钟 这类样本建议把“静态配置、运行时链路、持久化落点”做成交叉验证,避免仅凭 strings 里的域名就下结论。尤其是配置区经常存在单字节 XOR、Base64 后再压缩,或者运行时拼接 C2 的情况。 先固定样本信息并保留原始证据,分析环境使用快照和 Host-only 网络,不要让样本直接访问公网: Get-FileHash .\sample.exe -Algorithm SHA256 Get-AuthenticodeSignature .\sample.exe | Format-List sigcheck64.exe -a -h -i .\sample.exe diec.exe .\sample.exe floss.exe -n 6 .\sample.exe > floss.txt capa.exe .\sample.exe 配置提取时可优先从网络 API 的交叉引用反推,而不是盲搜字符串。重点看 WinHttpConnect、WinHttpOpenRequest、InternetConnect、getaddrinfo、connect 周围的数据流,以及资源段、较高熵的自定义节和全局初始化函数。若发现解密循环,最好只复现解码函数,并同时记录偏移、密钥和字段边界,便于后续批量验证。 C2 链路建议在 FakeNet-NG 或 INetSim 下复现,同时抓取 ETW/Sysmon 和 PCAP。这样能区分硬编码域名、备用 IP、DGA、DNS TXT 配置以及 HTTP Host 与实际目的地址不一致等情况。常用过滤可以先从这些入手: # Wireshark dns || http.request || tls.handshake.extensions_server_name # 当前连接及对应进程 Get-NetTCPConnection | Sort-Object State,RemoteAddress | Format-Table LocalAddress,LocalPort,RemoteAddress,RemotePort,State,OwningProcess Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,ExecutablePath,CommandLine 如果是 HTTPS,不要只记录域名和 JA3。还应保留连接周期、DNS 响应、SNI、证书指纹、URI 结构、User-Agent、请求体长度和回连间隔。JA3 很容易因系统 TLS 栈或版本变化产生偏差,而“固定间隔并带少量抖动”的行为特征通常更稳定。 持久化排查除了 Run 键,还要覆盖 32/64 位注册表视图、计划任务 XML、服务、WMI 永久事件订阅和启动目录: reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /s reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /s reg query "HKLM\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run" /s schtasks /query /fo LIST /v sc.exe query type= service state= all Get-CimInstance -Namespace root/subscription -Class __EventFilter Get-CimInstance -Namespace root/subscription -Class CommandLineEventConsumer Get-CimInstance -Namespace root/subscription -Class __FilterToConsumerBinding Get-ChildItem "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup" -Force Get-ChildItem "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp" -Force 排查时要关注的不只是条目名称,还包括引用文件是否位于 AppData、ProgramData、Temp,命令行是否使用 rundll32、regsvr32、mshta、powershell -enc,以及任务触发器是否为登录、空闲或短周期重复执行。服务项还应核对 ImagePath 是否带有未加引号路径或异常参数。 最后建议按时间线归并结果:进程创建 → 文件落地 → 持久化写入 → DNS/连接 → 二阶段载荷。Sysmon 中至少关联 Event ID 1、3、11、12/13、22;单独看到一个注册表键或域名不足以证明完整感染链。清理前先导出任务 XML、注册表项和落地文件哈希,完成隔离后再删除持久化,避免条目被存活进程重新写回。
创建帐户或登录后发表意见