来源:http://wooyun.jozxing.cc/static/bugs/wooyun-2014-071516.html

漏洞出现在/include/editpost.inc.php。

			if($thread['special'] == 1 && ($alloweditpoll || $isorigauthor) && !empty($polls)) {
				$pollarray = '';
				$pollarray['options'] = $polloption;
				if($pollarray['options']) {
					if(count($pollarray['options']) > $maxpolloptions) {
						showmessage('post_poll_option_toomany');
					}
					foreach($pollarray['options'] as $key => $value) {
						if(!trim($value)) {
							$db->query("DELETE FROM {$tablepre}polloptions WHERE polloptionid='$key' AND tid='$tid'");
							unset($pollarray['options'][$key]);
						}
					}

  

可以看到代码中有个foreach循序:foreach($pollarray['options'] as $key => $value)

接着看到下面的sql语句:$db->query("DELETE FROM {$tablepre}polloptions WHERE polloptionid='$key' AND tid='$tid'");

把$key放在sql语句中进行查询,我们来看看dz的gpc过滤方法。

文件在/include/common.inc.php。如果开启gpc就用如下语句

foreach(array('_COOKIE', '_POST', '_GET') as $_request) {
	foreach($$_request as $_key => $_value) {
		$_key{0} != '_' && $$_key = daddslashes($_value);
	}

  

只对value的值过滤:daddslashes($_value),跟进函数,

function daddslashes($string, $force = 0) {
	!defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
	if(!MAGIC_QUOTES_GPC || $force) {
		if(is_array($string)) {
			foreach($string as $key => $val) {
				$string[$key] = daddslashes($val, $force);
			}
		} else {
			$string = addslashes($string);
		}
	}
	return $string;
}

  

只对value过滤了,如果没开启gpc也调用他。

这里还有个要注意的点:

foreach(array('_COOKIE', '_POST', '_GET') as $_request) {
	foreach($$_request as $_key => $_value) {
		$_key{0} != '_' && $$_key = daddslashes($_value);
	}

  

对于这段代码,从cookie到post再到GET循环,从cookie开始的,php对于参数会解析新值覆盖旧值,也就是你POST过去一个参数,如果在GET参数中再次出现,那么就会选取GET的值,而覆盖掉POST的值

 

引用:

由于discuz7.2的过滤代码没对$key进行过滤,所以我们可以直接在$key中输入单引号,进而达到注入的目的。

在执行循环之前有一个条件 

if($thread['special'] == 1 && ($alloweditpoll || $isorigauthor) && !empty($polls))
这里($alloweditpoll || $isorigauthor) $isorigauthor判断是不是你是作者 如果你编辑的是你的文章的话 肯定是true。 $polls 这个直接就可以控制。
$thread['special'] == 1 之前我一直在纠结这个是啥东西。。
后面看了看发文章的时候的代码 这个$thread['special'] == 1代表的就是发布的是投票。
那如果我们自己发布一个投票 然后再编辑 就可以进入这里了。

 

还有一个就是value的值要为空或者0,因为有个if判断

						if(!trim($value)) {
							$db->query("DELETE FROM {$tablepre}polloptions WHERE polloptionid='$key' AND tid='$tid'");
							unset($pollarray['options'][$key]);
						}

  

最后只要在url中添加 poc:  polloption[' and updatexml(1,concat(0x7e,(select @@version),0x7e),1)#]=0

 

 

收获的地方就是,1.检查cms过滤时看有没有对key和value同时进行过滤。2.EGPCS 对于这些请求,解析的顺序是从左往右,数组也是,还有就是后解析的新值会覆盖旧值。

 

posted on 2017-06-02 09:13  羊小弟  阅读(719)  评论(0编辑  收藏  举报