### 简要描述: 20140709. ### 详细说明: 20140709的74cms 在plus/weixin.php中 因为默认的这个文件都会checkSignature 来检测token 但是来看看74cms的 根本就不需要token。 ``` $wechatObj = new wechatCallbackapiTest($dbhost,$dbuser,$dbpass,$dbname); if(isset($_REQUEST['echostr'])) $wechatObj->valid(); elseif(isset($_REQUEST['signature'])) { $wechatObj->responseMsg(); } ``` 来看看valid ``` public function valid() { $echoStr = $_GET["echostr"]; if($this->checkSignature()) { exit($echoStr); } } ``` check了。 ``` elseif(isset($_REQUEST['signature'])) { $wechatObj->responseMsg(); ``` 可是在这里 如果设置了这个 就直接进入了。所以 完全没验证token。。。 ``` public function responseMsg() { $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; if (!empty($postStr)) { $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $keyword = trim($postObj->Content); $keyword = iconv("utf-8","gb2312",$keyword); $time = time(); $event = trim($postObj->Event); if ($event === "subscribe") { $word=...
### 简要描述: 20140709. ### 详细说明: 20140709的74cms 在plus/weixin.php中 因为默认的这个文件都会checkSignature 来检测token 但是来看看74cms的 根本就不需要token。 ``` $wechatObj = new wechatCallbackapiTest($dbhost,$dbuser,$dbpass,$dbname); if(isset($_REQUEST['echostr'])) $wechatObj->valid(); elseif(isset($_REQUEST['signature'])) { $wechatObj->responseMsg(); } ``` 来看看valid ``` public function valid() { $echoStr = $_GET["echostr"]; if($this->checkSignature()) { exit($echoStr); } } ``` check了。 ``` elseif(isset($_REQUEST['signature'])) { $wechatObj->responseMsg(); ``` 可是在这里 如果设置了这个 就直接进入了。所以 完全没验证token。。。 ``` public function responseMsg() { $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; if (!empty($postStr)) { $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $keyword = trim($postObj->Content); $keyword = iconv("utf-8","gb2312",$keyword); $time = time(); $event = trim($postObj->Event); if ($event === "subscribe") { $word= "回复j返回紧急招聘,回复n返回最新招聘!您可以尝试输入职位名称如“会计”,系统将会返回您要找的信息,我们努力打造最人性化的服务平台,谢谢关注。"; $text="<xml> <ToUserName><![CDATA[".$fromUsername."]]></ToUserName> <FromUserName><![CDATA[".$toUsername."]]></FromUserName> <CreateTime>".$time."</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[".$word."]]></Content> </xml> "; exit($text); } ``` 0x01 任意文件读取 (这个无视接口是否开启) 因为在解析xml的时候是在判断接口是否开启之前 所以就算没开启也能读取。 ``` $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $keyword = trim($postObj->Content); $keyword = iconv("utf-8","gb2312",$keyword); ``` 在这里解析了传递过来的xml ``` if ($event === "subscribe") { $word= "回复j返回紧急招聘,回复n返回最新招聘!您可以尝试输入职位名称如“会计”,系统将会返回您要找的信息,我们努力打造最人性化的服务平台,谢谢关注。"; $text="<xml> <ToUserName><![CDATA[".$fromUsername."]]></ToUserName> <FromUserName><![CDATA[".$toUsername."]]></FromUserName> <CreateTime>".$time."</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[".$word."]]></Content> </xml> "; exit($text); } if (!empty($keyword)) { if($_CFG['sina_apiopen']=='0') { $word="网站微信接口已经关闭"; $text="<xml> <ToUserName><![CDATA[".$fromUsername."]]></ToUserName> <FromUserName><![CDATA[".$toUsername."]]></FromUserName> <CreateTime>".$time."</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[".$word."]]></Content> </xml> "; exit($text); ``` 解析过后 这里exit($text); 退出的时候会把内容输出过来。 所以。 构造一个xml 就能读取任意文件了。 [<img src="https://images.seebug.org/upload/201407/181247434d36038be700c10d5a758cd001685d4e.jpg" alt="7.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201407/181247434d36038be700c10d5a758cd001685d4e.jpg) ___ 上面那个任意文件读取不需要开启接口, 下面这个注入就需要开启接口了。 0x02 注入 ``` if($_CFG['sina_apiopen']=='0') { $word="网站微信接口已经关闭"; $text="<xml> <ToUserName><![CDATA[".$fromUsername."]]></ToUserName> <FromUserName><![CDATA[".$toUsername."]]></FromUserName> <CreateTime>".$time."</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[".$word."]]></Content> </xml> "; exit($text); } $limit=" LIMIT 6"; $orderbysql=" ORDER BY refreshtime DESC"; if($keyword=="n") { $jobstable=table('jobs_search_rtime'); } else if($keyword=="j") { $jobstable=table('jobs_search_rtime'); $wheresql=" where `emergency`=1 "; } else { $jobstable=table('jobs_search_key'); $wheresql.=" where likekey LIKE '%{$keyword}%' "; } $word=''; $list = $id = array(); $idresult = $this->query("SELECT id FROM {$jobstable} ".$wheresql.$orderbysql.$limit); while($row = $this->fetch_array($idresult)) ``` ($_CFG['sina_apiopen']=='0' 在这里由于判断了接口是否开启 关闭了则退出 所以注入的话得开启才行, 在这里 $wheresql.=" where likekey LIKE '%{$keyword}%' "; 来看看$keyword哪里来的。 ``` $keyword = trim($postObj->Content); $keyword = iconv("utf-8","gb2312",$keyword); ``` 可以看到是解析后来的 $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; $GLOBALS["HTTP_RAW_POST_DATA"]这个是不会被74cms的addslashes转义的 所以造成了注入。、 [<img src="https://images.seebug.org/upload/201407/18125504dd65884af9c5b1bd119f9cb3d2f2bcd6.jpg" alt="8.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201407/18125504dd65884af9c5b1bd119f9cb3d2f2bcd6.jpg) ### 漏洞证明: [<img src="https://images.seebug.org/upload/201407/181247434d36038be700c10d5a758cd001685d4e.jpg" alt="7.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201407/181247434d36038be700c10d5a758cd001685d4e.jpg) [<img src="https://images.seebug.org/upload/201407/18125504dd65884af9c5b1bd119f9cb3d2f2bcd6.jpg" alt="8.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201407/18125504dd65884af9c5b1bd119f9cb3d2f2bcd6.jpg)