Dedecms include\dialog\select_soft_post.php Upload Any Files To The Specified Directory Via Variable Not Initial Flaw Bypass Extension Defence

目录

1. 漏洞描述
2. 漏洞触发条件
3. 漏洞影响范围
4. 漏洞代码分析
5. 防御方法
6. 攻防思考

 

1. 漏洞描述

综合来说,这个漏洞的根源是"register_globals = on",在这个漏洞的前提下,攻击者可以发动这样的攻击向量

1. 当前网站的"register_globals = on"已开启
2. 在代码中没有显式声明、初始化的变量
3. 在用户提交的HTML表单中提交了相同名字的字段
4. 在以上的前提下,黑客可以任意控制代码中变量的值

大体来说,黑客可以有两种利用、及入侵方式

1. 通过注入、覆盖变量$cfg_basedir,导致可以饶过身份认证和系统变量初始化文件,导致可以上传任意文件到指定目录
2. 通过注入、覆盖变量$cfg_not_allowall、$newname等字段,绕过文件扩展名检查防御代码,向目标文件夹直接上传WEBSHELL

这两种攻击向量的最终目的都是向服务端上传WEBSHELL(.PHP、.ASP、.htaccess)等文件

Relevant Link:

http://huaidan.org/archives/3386.html
http://sebug.net/vuldb/ssvid-12518
http://4byte.cn/learning/51122.html
https://code.google.com/p/webfiles/source/browse/files/localhost/htdocs/cxtx/include/dialog/select_soft_post.php?spec=svn40&r=17

 
2. 漏洞触发条件

1. register_globals = on: 网站本身的安全设置
2. 攻击者可以通过自定义表单为相关的变量赋值: 伪造HTTP数据包


3. 漏洞影响范围

1. Dedecms 5.5
2. DEDECMS v5.5 Final 


4. 漏洞代码分析

/include/dialog/select_soft_post.php

Relevant Link:

http://www.verydemo.com/demo_c116_i56826.html


5. 防御方法

0x1: 升级到最新的DEDECMS版本

0x2: Patch Code

我们知道,这个漏洞的根源是因为PHP变量覆盖导致的恶意文件上传,没法直接针对性的防御,要进行代码级的防御,可以从堵住入侵GETSHELL的最终目的这个角度入手

1. 在代码流的相对末尾位置布置文件名检测
2. 采取正则匹配文件名中是否有".php、.asp"等特征,来达到防止WEBSHELL上传的目的

/include/dialog/select_soft_post.php
defence code

....
if (preg_match('#\.(php|pl|cgi|asp|aspx|jsp|php5|php4|php3|shtm|shtml)$#i', trim($filename))) 
{
    ShowMsg("你指定的文件名被系统禁止!",'javascript:;');
    exit();
}
$fullfilename = $cfg_basedir.$activepath.'/'.$filename;
$fullfileurl = $activepath.'/'.$filename;
....

这个修复防御代码在Linux上运行没有问题,但是对于运行在Windows操作系统上的WEB系统,存在一个绕过的风险,这和windows对文件名的命名规约有关系

1. 以下字符不能表示文件名
    1) <
    2) >
    3) /
    4) \
    5) |
    6) :
    7) "
    8) *
    9) ?
    10) 、 
2. 允许文件或者文件夹名称不得超过255个字符 
3. 文件名除了开头之外任何地方都可以使用空格
3. 文件结尾不能以下列字符
    1) .

黑客可以通过上传文件名为"xxx.php."这种类型的文件名,WEB系统向磁盘上上写入文件之后,windows操作系统会自动删除结尾的".",这导致了WEB系统的防御逻辑和操作系统的文件名规约不一致,导致绕过的场景发生

..
if (preg_match('#\.(php|pl|cgi|asp|aspx|jsp|php5|php4|php3|shtm|shtml)[^a-zA-Z0-9]+$#i', trim($filename))) 
{
    ShowMsg("你指定的文件名被系统禁止!",'javascript:;');
    exit();
}
$fullfilename = $cfg_basedir.$activepath.'/'.$filename;
$fullfileurl = $activepath.'/'.$filename;
..


6. 攻防思考

0x1: 官方修复方案

文件上传属于WEB系统通用的功能,最佳的防御实践是将防御代码做成通用的代码模块,放置在WEB系统的关键节点位置,使用面向对象OO的思想对所有的文件上传进行防御

DEDECMS本身已经做了这方面的工作了

1. include/common.inc.php
//检查和注册外部提交的变量
function CheckRequest(&$val) 
{
    if (is_array($val)) 
    {
        foreach ($val as $_k=>$_v) 
        {
            CheckRequest($_k);
            CheckRequest($val[$_k]);
        }
    } 
    else
    {
        if( strlen($val)>0 && preg_match('#^(cfg_|GLOBALS)#',$val) )
        {
            exit('Request var not allow!');
        }
    }
}


2. /include/uploadsafe.inc.php
//为了防止用户通过注入的可能性改动了数据库
//这里强制限定的某些文件类型禁止上传
$cfg_not_allowall = "php|pl|cgi|asp|aspx|jsp|php3|shtm|shtml";
...
if(!empty(${$_key.'_name'}) && (eregi("\.(".$cfg_not_allowall.")$",${$_key.'_name'}) || !ereg("\.",${$_key.'_name'})) )
{
    if(!defined('DEDEADMIN'))
    {
        exit('Upload filetype not allow !');
    }
}

 

Copyright (c) 2014 LittleHann All rights reserved

 

posted @ 2014-12-15 20:31  郑瀚Andrew  阅读(2386)  评论(0编辑  收藏  举报