技术讨论 | PHP本地文件包含漏洞GetShell(突破极限)
字数 1476 2025-08-15 21:30:26
PHP本地文件包含漏洞GetShell技术分析文档
漏洞概述
本文详细分析PHP本地文件包含(LFI)漏洞结合临时文件上传实现GetShell的技术原理和利用方法。该技术适用于存在LFI漏洞但无直接上传点或受open_basedir限制的环境。
漏洞利用条件
- 存在PHP文件包含漏洞
- 存在PHPINFO泄漏页面或其他debug信息泄漏(用于获取tmp_name值)
技术原理
临时文件上传机制
PHP在处理文件上传时,无论目标代码是否处理上传逻辑,都会将上传文件保存为临时文件。临时文件命名规则为php[6位随机字符],存储在系统临时目录中。
关键特性:
- 临时文件在请求处理完成后会自动删除
- 文件存在时间极短(毫秒级)
- 通过phpinfo()可以获取临时文件名
条件竞争利用
由于临时文件存在时间极短,需要通过条件竞争在文件被删除前包含执行。技术要点:
- 利用phpinfo页面返回大量数据延长响应时间
- 使用原生socket连接精确控制响应读取
- 在获取临时文件名后立即发起包含请求
漏洞复现环境
- 操作系统:Windows
- PHP版本:5.6
- 测试文件:
- phpinfo.php:
<?php phpinfo();?> - lfi.php:
<?php $a=$_GET['file']; include($a); ?>
- phpinfo.php:
利用步骤详解
1. 构造上传请求
上传请求需要满足:
- 包含文件上传区块
- 添加大量填充数据延长phpinfo响应时间
- 使用multipart/form-data格式
示例请求结构:
POST /phpinfo.php?a=[大量填充数据] HTTP/1.1
Content-Type: multipart/form-data; boundary=7dbff1ded0714
Content-Length: [长度]
--7dbff1ded0714
Content-Disposition: form-data; name="dummyname"; filename="test.txt"
Content-Type: text/plain
[恶意PHP代码]
--7dbff1ded0714--
2. 获取临时文件名
通过分析phpinfo响应,提取[tmp_name]字段值。由于响应数据量大,需要:
- 建立socket连接
- 分块读取响应(每次4096字节)
- 搜索
[tmp_name] =>字段
3. 发起包含请求
在获取临时文件名后,立即发起LFI请求:
GET /lfi.php?file=[临时文件路径] HTTP/1.1
4. 写入持久化Webshell
通过包含临时文件执行代码,写入持久化webshell:
<?php file_put_contents('aaa.php','<?php phpinfo();?>'); ?>
Python利用脚本分析
脚本核心功能:
- 设置大量填充数据延长响应
- 多线程并发提高竞争成功率
- 精确控制socket读取时机
关键参数:
host: 目标主机port: 目标端口(默认80)poolsz: 线程数(默认10)maxattempts: 最大尝试次数(默认1000)
实战应用场景
-
phpMyAdmin环境:
- 利用phpMyAdmin的文件包含漏洞
- 通过探针页面获取临时文件名
- 条件竞争GetShell
-
受限环境突破:
- 突破open_basedir限制
- 无直接上传点时作为替代方案
- 当传统LFI方法(日志包含等)不可用时
常见问题与解决方案
-
临时文件权限问题:
- MySQL写入/tmp的文件可能www用户无读取权限
- 解决方案:确保使用PHP上传机制生成临时文件
-
Windows环境适配:
- 临时文件名提取可能需要调整正则表达式
- 路径分隔符使用反斜杠
-
高版本PHP限制:
- PHP 7+可能有不同行为
- 需要测试临时文件生命周期是否变化
防御措施
- 禁用不必要的phpinfo等调试信息
- 设置严格的open_basedir
- 及时删除未使用的示例文件
- 限制文件包含参数的可控性
- 使用最新PHP版本并保持更新
参考资源
- LFI With PHPInfo Assistance (原始论文)
- vulhub PHP inclusion漏洞环境
- EDISEC漏洞挖掘技术文章
免责声明
本文仅用于技术研究与防御目的,严禁用于非法用途。使用者需自行承担相关法律责任。