神刀安全网

漏洞标题: 天融信TopADS某处命令执行及SQL注入(无需登录)

漏洞详情

披露状态:

2016-02-18: 细节已通知厂商并且等待厂商处理中
2016-02-18: 厂商已经确认,细节仅向厂商公开
2016-02-21: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2016-04-13: 细节向核心白帽子及相关领域专家公开
2016-04-23: 细节向普通白帽子公开
2016-05-03: 细节向实习白帽子公开
2016-05-18: 细节向公众公开

简要描述:

天融信TopADS某处命令执行及SQL注入(无需登录)

详细说明:

天融信TopADS某处命令执行及SQL注入(无需登录)

先来看看漏洞产生的文件:/usr/local/apache2/htdocs/modules/ads/ads_report_create_html.php

code 区域
<?php
if (isset($_SESSION['username'])) {
$root = $_SESSION['username'];
} else {
$root = "superman";
}
date_default_timezone_set('Asia/Shanghai');
$construct_time = date('Y-m-d H:i:s',time());
$data = array();
$data[0] = 'ADS事件分析报表';
$data[1] = '定制报表';
$data[2] = $root;
if ($_POST['zname'] == "") {
$data[3] = "所有防护对象";
} else {
$data[3] = $_POST['zname'];
}
if ($_POST['grpname'] == "") {
$data[4] = "所有二级防护对象";
} else {
$data[4] = $_POST['grpname'];
}
if ($_POST['dst_addr'] == "") {
$data[5] = "所有目的地址";
} else {
$data[5] = $_POST['dst_addr'];
}
switch ($_POST['rt']) {
case 'day':
$data[6] = date("Y-m-d H:i:s",strtotime("-1 day"));
$data[7] = $construct_time;
# code...
break;
case 'week':
$data[6] = date("Y-m-d H:i:s",strtotime("-1 week"));
$data[7] = $construct_time;
# code...
break;
case 'month':
$data[6] = date("Y-m-d H:i:s",strtotime("-1 month"));
$data[7] = $construct_time;
# code...
break;
case 'user_defined':
$data[6] = $_POST['time_start'];
$data[7] = $_POST['time_end'];
}
$data[8] = $construct_time;
$chart_title = array("全局流量监控", "攻击流量趋势", "IP攻击次数TopN", "防护对象流量TopN", "IP流量TopN", "防护对象攻击次数TopN", "攻击类型占比", "全局流量分布", "攻击流量占比", "TCP流量统计", "HTTP流量统计", "DNS流量统计", "IP分片流量统计", "IP流量统计", "攻击总字节数统计");
//$chart_direction = array(" 全局流量监控数据分析:", " 攻击流量趋势数据分析:", " IP攻击次数TopN数据分析:", " 防护对象流量TopN数据分析:", " IP流量TopN数据分析:", " 防护对象攻击次数TopN数据分析:", " 攻击类型占比数据分析:", " 全局流量分布数据分析:", " 攻击流量占比数据分析", " TCP流量统计数据分析:", " HTTP流量统计数据分析:", " DNS流量统计数据分析:", " IP分片流量统计数据分析:", " IP流量统计数据分析:", " 攻击总字节数统计数据分析:");
$img = "";
for ($i = 0; $i<count($_POST['chart']); $i++) {
if ($_POST['chart'][$i] == 15) {
include_once "Mysql.class.php";
$dbconfig = array (
'dbhost' => 'localhost',
'dbname' => 'TopADS',
'dbuser' => 'root',
'dbpassword' => 'topsec*talent',
'charset' => 'utf8',
'pconnect'=> false
);
$db = new mysql($dbconfig);
$time_now = date("Y-m-d H:i:s");
$time_last_day = date("Y-m-d H:i:s",strtotime("-1 day"));
$time_last_week = date("Y-m-d H:i:s",strtotime("-1 week"));
$time_last_month = date("Y-m-d H:i:s",strtotime("-1 month"));
if ($_POST['rt'] == "day") {
$_POST['time_start'] = $time_last_day;
$_POST['time_end'] = $time_now;
} else if($_POST['rt'] == "week") {
$_POST['time_start'] = $time_last_week;
$_POST['time_end'] = $time_now;
} else if($_POST['rt'] == "month") {
$_POST['time_start'] = $time_last_month;
$_POST['time_end'] = $time_now;
}
function make_where($sql_conf) {
$sql_where = "";
foreach ($sql_conf as $key => $value) {
if ('' == $value || $key == 'rt' || $key == 'filename' || $key == 'chart' || $key == 'report_logo' || $key == 'report_title' || $key == 'report_top' || $key == 'report_content') {
continue;
}
if ($key == 'time_start') {
$sql_where .= "AND cur_t >= '$sql_conf[$key]' ";
} else if ($key == 'time_end') {
$sql_where .= "AND cur_t <= '$sql_conf[$key]' ";
} else {
$sql_where .= "AND $key = '$sql_conf[$key]' ";
}
}
$sql_where = substr($sql_where, 3);
return $sql_where;
}
$sql_where = make_where($_POST);
$sql = "SELECT FORMAT(sum(atk_bytes)/1024/1024*60, 3) as atk_bytes, FORMAT(sum(atk_pkts)/1024/1024*60, 3) as atk_pkts FROM atk_log WHERE $sql_where";
$data_sql = $db->select($sql);
$img .= "<div style='text-align:center;'>
<p>攻击总字节数统计:</p>
<table width='100%' height='100%' border='0' cellspacing='0' cellpadding='0'>
<tr>
<td align='center' valign='middle'>
<table width='50%' border='1' align='center' cellpadding='0' cellspacing='0'>
<tr><td width='30%'>攻击总包数</td><td>".$data_sql[0]['atk_bytes']."MB</td></tr>
<tr><td width='30%'>攻击总字节数</td><td>".$data_sql[0]['atk_pkts']."Mp</td></tr>
</table>
</td>
</tr>
</table>
</div>";
continue;
}
$img .= "<div style='text-align:center;'><p>".$chart_title[$_POST['chart'][$i]-1].":<p><img src='exportpage.html".$_POST['chart'][$i].".jpg' /></div>";
}
$html_header = "
<!DOCTYPE html>
<html>
<head>
<title>ADS事件分析报表</title>
<meta charset='utf-8' />
</head>
<body>
<div style='text-align:center;padding-top:100px'>
<h1>ADS事件分析报表</h1>
<h4 style='padding-left:400px; padding-right:400px;text-align:left'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;欢迎使用天融信异常流量管理与抗拒绝服务系统, 系统主要针对DDos攻击进行安全防范与
安全处理。本报表包含对指定网络范围网络流量的安全情况的监管和信息统计,从本报表的
数据中可以了解到网络流量的安全情况,做好防御措施,保障资产安全。报表内容由系统管
理人员定制,系统自动生成。
</h4>
<div style='text-align:center'>
<table width='100%' height='100%' border='0' cellspacing='0' cellpadding='0'>
<tr><td align='center' valign='middle'>
<table width='50%' border='1' align='center' cellpadding='0' cellspacing='0'>
<tr><td width='30%'>文档类型</td><td>ADS事件分析报表</td></tr>
<tr><td>报表类型</td><td>".$data[0]."</td></tr>
<tr><td>类型</td><td>".$data[1]."</td></tr>
<tr><td>定制人员</td><td>".$data[2]."</td></tr>
<tr><td>防护对象</td><td>".$data[3]."</td></tr>
<tr><td>二级防护对象</td><td>".$data[4]."</td></tr>
<tr><td>目的地址</td><td>".$data[5]."</td></tr>
<tr><td>报表起始时间</td><td>".$data[6]."</td></tr>
<tr><td>报表结束时间</td><td>".$data[7]."</td></tr>
<tr><td>报表创建时间</td><td>".$data[8]."</td></tr>
</table>
</td>
</tr>
</table>
</div>
</div>
".$img."
</body>
</html>";
$fp = fopen($_POST['filename'].".html", "w");
fwrite($fp, $html_header);
fclose($fp);
system("cd ".$_SERVER['DOCUMENT_ROOT']."/modules/ads && rm -f exportpage.html && tar -cf ../../cachedata/reports/".$_POST['filename'].".zip *.jpg *.html --ignore-failed-read && rm -f *.html *.jpg *.bmp");
?>

首先这里没有验证是否登录,导致无需登录即可进行相关操作

命令执行

很明显,最后一行:

code 区域
system("cd ".$_SERVER['DOCUMENT_ROOT']."/modules/ads && rm -f exportpage.html && tar -cf ../../cachedata/reports/".$_POST['filename'].".zip *.jpg *.html --ignore-failed-read && rm -f *.html *.jpg *.bmp");

$_POST['filename']直接拼接到命令然后进入system函数执行,有没有很黄很暴力啊!!!

SQL注入

看下面这段代码

code 区域
for ($i = 0; $i<count($_POST['chart']); $i++) {
if ($_POST['chart'][$i] == 15) {
include_once "Mysql.class.php";
$dbconfig = array (
'dbhost' => '******',
'dbname' => '******',
'dbuser' => '******',
'dbpassword' => '******',
'charset' => '******',
'pconnect'=> false
);
$db = new mysql($dbconfig);
$time_now = date("Y-m-d H:i:s");
$time_last_day = date("Y-m-d H:i:s",strtotime("-1 day"));
$time_last_week = date("Y-m-d H:i:s",strtotime("-1 week"));
$time_last_month = date("Y-m-d H:i:s",strtotime("-1 month"));
if ($_POST['rt'] == "day") {
$_POST['time_start'] = $time_last_day;
$_POST['time_end'] = $time_now;
} else if($_POST['rt'] == "week") {
$_POST['time_start'] = $time_last_week;
$_POST['time_end'] = $time_now;
} else if($_POST['rt'] == "month") {
$_POST['time_start'] = $time_last_month;
$_POST['time_end'] = $time_now;
}
function make_where($sql_conf) {
$sql_where = "";
foreach ($sql_conf as $key => $value) {
if ('' == $value || $key == 'rt' || $key == 'filename' || $key == 'chart' || $key == 'report_logo' || $key == 'report_title' || $key == 'report_top' || $key == 'report_content') {
continue;
}
if ($key == 'time_start') {
$sql_where .= "AND cur_t >= '$sql_conf[$key]' ";
} else if ($key == 'time_end') {
$sql_where .= "AND cur_t <= '$sql_conf[$key]' ";
} else {
$sql_where .= "AND $key = '$sql_conf[$key]' ";
}
}
$sql_where = substr($sql_where, 3);
return $sql_where;
}
$sql_where = make_where($_POST);
$sql = "SELECT FORMAT(sum(atk_bytes)/1024/1024*60, 3) as atk_bytes, FORMAT(sum(atk_pkts)/1024/1024*60, 3) as atk_pkts FROM atk_log WHERE $sql_where";
$data_sql = $db->select($sql);

当$_POST['chart'][$i] == 15时,进行数据库操作

在下面的make_where函数中,构造where条件语句,在此函数中的最后一个else条件中

$sql_where .= "AND $key = '$sql_conf[$key]' ";

直接拼接了key和value,key和value都是直接从POST中传入的

最后$sql_where被拼接在$sql语句中,进入了$db->select($sql);

进入数据库会也没有任何处理,最后导致sql注入

漏洞证明:

命令执行

下面以三个不同案例为证明,均无需登录即可触发漏洞

漏洞标题:  天融信TopADS某处命令执行及SQL注入(无需登录)

漏洞标题:  天融信TopADS某处命令执行及SQL注入(无需登录)

漏洞标题:  天融信TopADS某处命令执行及SQL注入(无需登录)

SQL注入

这里的注入没有回显,只能进行盲注了

注意这里的chart[i]=15,必须是15才能进入sql注入的逻辑

这里进行了一些过滤,但是不妨碍注入

漏洞标题:  天融信TopADS某处命令执行及SQL注入(无需登录)

修复方案:

版权声明:转载请注明来源 xfkxfk@乌云

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 漏洞标题: 天融信TopADS某处命令执行及SQL注入(无需登录)

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址