ctf show web入门159

本题主要考察了通过 .user.ini 配置文件进行文件包含,并结合 日志注入 实现远程代码执行的综合高阶渗透技巧。

  1. 核心提示

    题目页面明确提示:"后端校验要严密",这暗示前端可能没有做严格限制,或者单纯的前端绕过是不够的,必须通过后端逻辑漏洞来打通链路。

  2. 考察知识点

    .user.ini 配置文件劫持:在 PHP 环境中,.user.ini 可以用于动态修改 PHP 配置。通过利用 auto_prepend_file 或 auto_append_file 指令,可以让当前目录下的所有 PHP 页面在执行前或执行后自动包含一个指定文件。

Nginx 日志注入:当上传的文件内容受到严格过滤(或无法直接上传 PHP 恶意脚本)时,可以通过向服务器发送带有恶意 PHP 代码的 HTTP 请求(如伪造 User-Agent),将其写入服务器的访问日志(access.log)。

本地文件包含(LFI)扩展:将日志文件作为包含目标,配合被 .user.ini 自动加载的媒介文件,触发 PHP 解析日志中的木马代码,最终达成 RCE。

解题详细步骤

第一步:利用 .user.ini 配置文件实现文件自动包含

分析环境:由于后端只允许上传图片格式或有严格的内容检查,直接上传普通的 蚁剑/冰蝎 木马可能会被后端拦截。

构建配置文件:利用 Burp Suite 拦截请求,将上传的文件名修改为 .user.ini

写入指令:在文件正文中写入以下配置:

php 复制代码
auto_prepend_file=MM.png

这句话的作用是:只要访问该目录下的任意 PHP 文件(例如 upload.php 或 index.php),系统在执行该 PHP 文件前,都会先强制 include 包含同目录下的 MM.png。

第二步:上传包含混淆代码的媒介文件(MM.png)

为了配合 .user.ini,接下来需要上传刚才指定的 MM.png 文件。

构造包含代码:因为可能存在针对关键词(如 include、log 等)的后端过滤,需要对敏感字符串进行拼接绕过。

发送请求:通过 Burp Suite 拦截并发送内容如下的 MM.png:

php 复制代码
<?include '/var/l'.'og/nginx/access.l'.'og'?>

由于混淆拼接,该代码在被 PHP 执行时会还原为 include '/var/log/nginx/access.log'。这意味着,每当触发文件包含链时,最终都会去解析 Nginx 的访问日志。第三步:Nginx 访问日志注入(一句话木马写入)通过前两步,我们成功建立了一条通道:访问 PHP 页面 -> 自动包含 MM.png-> 包含并解析 access.log。现在,只需要把一句话木马送进日志文件即可

定位目标:使用浏览器或 HackBar 访问一个不存在的文件或正常页面(如 1.txt),关键在于操纵请求头。

注入 WebShell:将 HTTP 请求头中的 User-Agent 修改为 PHP 一句话木马:

php 复制代码
<?php eval($_POST[1]);?>

结果:Nginx 服务器会将本次请求记录到 /var/log/nginx/access.log 中,其中 User-Agent 的位置就变成了我们的木马代码。

第四步:触发 RCE 并获取 Flag

执行命令:利用 HackBar 向目标的 /upload/ 目录(或包含 .user.ini 的相关 PHP 路由)发送 POST 请求。

传递参数:

在 POST Body 中传入:1=system('tac .../flag.php');(使用 tac 反向读取或 cat 读取上级目录下的 flag 文件)。

为什么这里要将一句话木马改为<?include'/var/l'.'og/nginx/access.l'.'og'?>

为什么这样就可以触发rce

这一步其实是整道题最精妙的联合套路。

简单来说:因为后端把所有好走的"直路"都堵死了(比如不让你直接上传木马、或者过滤了敏感代码),所以我们只能绕个远路,把 Nginx 的日志文件当成我们的"备用木马箱"。

下面为你深度拆解这两个为什么:

  1. 为什么要改为 <?include '/var/l'.'og/nginx/access.l'.'og'?>?
    这里有两个核心原因:绕过检测 和 定向引流。

① 字符串拼接:绕过后端的关键字过滤

如果直接在代码里写 '/var/log/nginx/access.log',后端的安全过滤机制(比如正则表达式)一旦检测到 log、nginx、access 等敏感字眼,就会判定这是恶意攻击并直接拦截上传。

通过利用 PHP 的字符串拼接特性:

'/var/l'.'og/nginx/access.l'.'og'

在上传时,它只是几个无害的碎片字符串,成功绕过检测。而当 PHP 真正去执行这行代码时,会自动把它们拼接还原成完整的路径:/var/log/nginx/access.log。

② 包含日志:把日志文件变成"伪装的 PHP 脚本"

.user.ini 的作用是让页面自动包含 MM.png。但 MM.png 本身里面并没有木马核心代码(没有 eval),它里面只有上面这行 include 语句。

这句话的意思是:"请 PHP 顺便把 Nginx 的访问日志文件也读取并解析一下。"

这样,我们就成功把 PHP 的执行焦点,转移到了 Nginx 的日志文件(access.log)上。

  1. 为什么这样就可以触发 RCE(远程代码执行)?
    这涉及到了 PHP 中 include(文件包含)的底层逻辑:"认命不认命"。

在 PHP 中,只要被 include() 的文件里含有标准的 PHP 标签(如 <?php ... ?>),不管这个文件的后缀是 .log、.txt 还是 .jpg,PHP 都会强行把里面的内容当成 PHP 代码来解析并执行!

整个 RCE 的触发链条是这样的:

步骤 1 攻击者访问 1.txt 并将 User-Agent 改为 <?php eval($_POST1);?>

步骤 2 Nginx 忠实地把这个恶意的 User-Agent 写入到 /var/log/nginx/access.log 中

步骤 3 攻击者向服务器的 upload.php 发送 POST 请求 (带上恶意参数 1=system(...))

步骤 4 .user.ini 触发 ──> 自动加载 MM.png

步骤 5 MM.png 执行 ──> 强行 include 包含 access.log

最终 RCE PHP 解析 access.log,读到步骤 1 写入的 <?php eval($_POST1);?>,

并接收了步骤 3 传来的 system() 命令,最终在服务器上炸开,执行成功!

总结

直接上传木马文件(含有 eval)会被后端直接杀掉。所以我们利用 MM.png 做一个"内应",它的唯一工作就是利用 include 跨界去把 Nginx 日志 拉进 PHP 的解析器里。而真正的木马,早就通过修改 User-Agent 的方式偷偷混进日志里躺着了。两合一,木马成功执行!

为什么写在1.txt文件中的一句话木马会让upload文件中的命令执行

这个问题问到了整道题最核心的目录级别配置劫持文件包含原理

其实,并不是 1.txtupload 里面的命令执行,而是 .user.ini 像一个"强力胶水",把 upload 目录下的所有 PHP 文件、MM.png、以及写有木马的 1.txt(访问日志) 牢牢地绑在了一起。

为了彻底说明白,我们把这个过程拆解为两个最关键的疑问:


1. 为什么访问 upload 目录能触发木马?(.user.ini 的威力)

.user.ini 是 PHP 的一种目录局部配置文件。只要你在某个目录下(比如 /upload/ 目录)上传了一个 .user.ini,那么只要有人访问这个目录下的任何一个 PHP 文件(不管是 index.php 还是 upload.php),PHP 引擎都会强制执行 .user.ini 里的全局指令。

我们在 .user.ini 里写了:

ini 复制代码
auto_prepend_file=MM.png

这意味着:

  • 只要你请求 https://.../upload/upload.php
  • PHP 在执行 upload.php 里的代码之前 ,会自动、无条件地先在后台执行 include('MM.png');

2. 木马不是在 1.txt 里吗?怎么和 MM.png 扯上关系的?

这就是为什么要用 日志注入

  1. 木马的真正去处
    在第三步中,我们修改了 User-Agent 发送请求访问 1.txt。这时候,Nginx 服务器会把这次访问记录到它的标准访问日志 中(即 /var/log/nginx/access.log)。
    也就是说,此时 <?php eval($_POST[1]);?> 这句木马,已经变成文本,躺在 Nginx 的 access.log 文件里了
  2. MM.png 的内应作用
    我们在第二步中上传了 MM.png,内容是:
php 复制代码
<?include '/var/l'.'og/nginx/access.l'.'og'?>

它被拼接还原后,真正的意思就是:include '/var/log/nginx/access.log'


最终的骨牌效应:命令是如何执行的?

当你使用 HackBar,向 upload.php 发送 POST 请求,带上参数 1=system('tac ../flag.php'); 时,服务器后台发生了如下的连环反应:

  1. 第一步(配置触发) :PHP 收到请求,准备运行 upload.php。但它发现当前目录下有 .user.ini,于是转头**先去加载 MM.png**
  2. 第二步(文件包含) :PHP 开始解析 MM.png,读到了里面的指令------"去把 Nginx 的 access.log 包含进来"
  3. 第三步(木马复活) :PHP 开始读取 access.log。虽然它是日志文件,但由于 PHP 的 include 特性"只认标签不认后缀",PHP 一旦在日志里读到之前注入的 <?php eval($_POST[1]);?> 标签,就会立刻把它当作真正的 PHP 代码来执行!
  4. 第四步(命令炸开) :此时 eval() 函数激活,它成功接收到了你通过 POST 传过来的参数 1(即 system('tac ../flag.php');)。

结果 :操作系统执行了 tac ../flag.php,并将 flag 打印在了你的屏幕上。

总结

1.txt 只是一个用来触发 Nginx 记录日志的靶子 (通过访问它,把木马写进日志)。最终真正让命令执行的,是 .user.ini 强行加载了 MM.png,而 MM.png 又强行把带有木马的日志文件(access.log)喂给了 PHP 处理器

相关推荐
子兮曰12 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰12 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
一隅论数智12 小时前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
前端小万12 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝12 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋13 小时前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁13 小时前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
深圳老胡14 小时前
STM32F407 控制 L6470 步进电机驱动 —— 控制过程简介
笔记·stm32·单片机·嵌入式硬件·代码规范
Because_of_Her115 小时前
并查集-听课笔记
笔记·算法·并查集
彧azz15 小时前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试