专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »安全 » 上传漏洞:DISCUZ2上传漏洞分析-上传漏洞变换利用 »正文

上传漏洞:DISCUZ2上传漏洞分析-上传漏洞变换利用

来源: 发布时间:星期六, 2009年9月12日 浏览:6次 评论:0
作者:小华 QQ:56111981    来自:www.hackbase.com

转自作者blog:http://xiaohuar.blogchina.com

文章已发表于黑客X档案12期

DISCUZ论坛以其漂亮界面完备功能受到很多站长青睐在PHP论坛中占有很大市场从各方面都有可以和动网论坛相媲美2.0虽然属于老版本但还是有大部分用户正在使用自从9月DISCUZ爆了个漏洞以来随后又相继出来了几个漏洞但这些漏洞要么影响很少要么利用起来很困难我写过个DISCUZ利用经常有人问我如何利用我无法回答为此我读了下DISCUZ源代码发现它上传存在问题经过测试在WIN2000下和Red Hat下都存在该问题不过部分UNIX系统不受影响文章是写如何发现上传漏洞给大家和作者点思路其中源请去网上下载免费版



   漏洞分析

我首先说DISCUZ2或者更高版本个BUG/common.php存在物理路径泄露漏洞require $discuz_root.'./config.php';

require $discuz_root.'.//global.php';

require $discuz_root.'.//global.php';

require $discuz_root.'.//db_'.$database.'.php';

这段代码中$discuz_root默认是等于"."就是当前目录意思如果在PHP.ini中没有设置INCLUDE选项那系统就会报告无法找到config.php系统认为common.php是被其他文件包含而包含它文件是在INCLUDE目录上层所以代码是这样写但是系统不可能阻止我们直接访问common.php所以如果我们在浏览器提交(我机子为例)



http://localhost/discuz//common.php



就会泄露物理路径  好切入正题开始分析上传漏洞如何形成以及如何利用



DISCUZ论坛上传/post.php下面attach_upload步解释执行过程涉及关键代码处我会详细介绍说明



    global $discuz_root, $attachsave, $attach, $attach_name, $attach_size, $attach_fname, $attachdir, $maxattachsize, $attachextensions;



//获得全局变量



(!function_exists('is_uploaded_file')) {



        (!is_uploaded_file($attach)) {



             false;



        }



    } (!($attach != 'none' && $attach && trim($attach_name))) {



         false;



    }



//以上判断$attach变量是不是个上传文件不是结束我们上传肯定是个文件



$attach_name = daddslashes($attach_name);







    ($attachextensions && @!eregi(substr(strrchr($attach_name, '.'), 1), $attachextensions)) {



        showmessage('post_attachment_ext_notallowed');



    }



//关键代码判断扩展名是否符合要求默认安装时$attachextentsions为空那么这个IF语句就跳过去了这是我们所希望但是般有点安全意识网站WebSite都会设置这个问题少后详细讨论





(!$attach_size || ($maxattachsize && $attach_size > $maxattachsize)) {



        showmessage('post_attachment_toobig');



    }



//判断文件大小构造下这句对我们没有效果跳过不管



    $filename = $attach_name;



    $extension = strtolower(substr(strrchr($filename, '.'), 1));





    ($attachsave) {



        switch($attachsave) {



             1: $attach_subdir = 'forumid_'.$GLOBALS['fid']; ;



             2: $attach_subdir = 'ext_'.$extension; ;



             3: $attach_subdir = 'month_'.date('ym'); ;



             4: $attach_subdir = 'day_'.date('ymd'); ;



        }



        (!is_dir($discuz_root.'./'.$attachdir.'/'.$attach_subdir)) {



            mkdir($discuz_root.'./'.$attachdir.'/'.$attach_subdir, 0777);



        }



        $attach_fname = $attach_subdir.'/';



    } {



        $attach_fname = '';



    }



//如何保存默认是放在论坛attachments目录下不过有论坛根据论坛ID号分类或者日期分类根据具体论坛而定不过对我们影响不大





$filename = substr($filename, 0, strlen($filename) - strlen($extension) - 1);



(preg_match("/[\x7f-\xff]+/s", $filename)) {



        $filename = str_replace('/', '', base64_encode(substr($filename, 0, 20)));



    }



//过滤非ASCII





    (in_.gif' />($extension, .gif' />('php', 'php3', 'jsp', 'asp', 'cgi', 'pl'))) {



        $extension = '_'.$extension;



    }



//关键代码判断扩展名是不是非法以防有人恶意上传WEBSHELL不过我们构造条件要饶过这条语句



$attach_fname .= random(4)."_$filename.$extension";



$attach_saved = false;



$source = stripslashes($discuz_root.'./'.$attachdir.'/'.$attach_fname);



//生成路径





剩下代码是上传文件就省略了要是能执行到这里和文件任何属性都已无关所以我也就不解释了(解释好累呵呵)





好我们开始反向追踪$source变量可以看到它是 3个变量组成:$discuz_root是定义好$attachdir也是定义好能控制是$attach_fname变量再追踪$attach_fname变量由4个随机个下划线和两个变量组成



$attach_fname .= random(4)."_$filename.$extension";



废话少说我把这个式子展开用最原始变量(我们可以构造变量)替换就变成了如下格式(别和我说没学过代数),随机串用abcd表示



$extension=strtolower(substr(strrchr($attach_name, '.'), 1));



$filename=substr($attach_name, 0, strlen($attach_name) - strlen($extension) - 1);



$attach_fname="abcd_$filename.$extentsion";



其中$attach_name是我们提交我们按正常思维提交个图片文件得到如下结果



$attach_name="test.jpg"



$extension="jpg"



$filename="test"



$attach_fname="abcd_test.jpg"





看到结果是如何生成了吧?我们按非正常思维就要得到SHELL了看如何利用漏洞





2 漏洞变换利用



通过上面分析大家已经知道如何运行我直接给出个得到WEBSHELL思路方法并分析是如何跳过检查其他利用思路方法大家可以仁者见仁智者见智



我们把$attach_name值设为"/../../test.php."(注意最后有个点)至于为什么$attach_name我们可以构造而且是任意构造这就需要点PHP脚本知识和HTTP协议基础篇幅有限不再介绍再有本文文章较长就不给数据包提交过程附有PERL源码大家可以查看文件名构造部分下面给出如何绕过验证分析关键代码



($attachextensions && @!eregi(substr(strrchr($attach_name, '.'), 1), $attachextensions)) {



        showmessage('post_attachment_ext_notallowed');



    }



很显然如果$attachextensions为空这句就无条件跳过如果设置了$attachextensions类似为"jpg,g,txt,zip,rar"形式那我们刚才构造就无效了系统会报错这种情况如何利用等会再说这里我们假设这句能跳过执行





  $extension = strtolower(substr(strrchr($filename, '.'), 1));



这里$filename值是我们提交为"/../../test.php.",执行这句后$extension就为空了



$filename = substr($filename, 0, strlen($filename) - strlen($extension) - 1);



同上执行完这句后$filename就等于"/../../test.php",注意最后没有点



    (in_.gif' />($extension, .gif' />('php', 'php3', 'jsp', 'asp', 'cgi', 'pl'))) {



        $extension = '_'.$extension;



    }



$extension为空所以这句跳过去了



到此$attach_fname="abcd_/../../test.php." (随机串用abcd代替)



我们假设$discuz_root="e:/www/discuz",那么



$source="e:/www/discuz/attachments/abcd_/../../test.php."



看到了吧经过我们构造后文件名就变成了上面样子保存到哪里不用再说了吧?



WINDOWS系统会忽略文件最后点号而LINUX系统虽然保留点号但依然阻挡不了我们获得SHELL这样我们就把自己SHELL传到了论坛根目录如果是LINUX系统在执行时要带上最后个点WINDOWSj就不必了,连接地址如下



http://localhost/discuz/test.php





到此如何绕过验证以及如何获得SHELL都写完了回到刚才疑问如果系统设置了$attachextensions如何办呢?假设值为"g,jpg,swf,txt,zip,rar",大部分系统都是这样



大家开始可能想不到如何利用我也是偶然想到这种思路方法虽然价值不大不过作为种经验我还是有必要和大家分享要发扬共享精神嘛有了上面分析基础我就不长篇赘述怕大家看着不耐烦我们把$attach_name值构造为"/../../images/default/logo.g",大家应该明白什么意思了吧?就是覆盖系统图片文件或者任何符合格式文件包括FLASH文件等有什么用呢?覆盖了logo图标确实没什么用不过搞恶作剧绰绰有余了假如你自己做个图片文件上面写着"该网站WebSite存在漏洞"等字样那个管理员肯定吓这让我想起来前个月国内几个安全网站WebSite进行了以改写别人网站WebSite主页为目攻击我不希望大家这样用这个漏洞损人不利己覆盖图片文件没有意义但覆盖SWF文件就有意义了我们很容易判断网站WebSiteSWF路径和文件名而且般网站WebSite或多或少有SWF文件我们覆盖了这些文件就可以做跨站脚本攻击可别小看XSS它比SQL注入功能弱不了多少可以得到用户COOKIE等敏感信息由于篇幅限制也不再赘述





漏洞利用小结:



1.版本必须是2.0(2.x.x可能也受影响)以下3.x以上那个文件名随机串是放在后面我想了很长时间都不知如何用如果有高手想出来可以起讨论



2.必须可以上传文件当然要先注册个用户不过大部分论坛受动网论坛上传漏洞影响都关闭了上传



3.DISCUZ论坛经过了很多人修改我读是最原始论坛源码难免有人在修改过程中修改了上传部分这样肯定会过滤"/,\,.."等敏感所以也不受影响



4.有商业论坛虽然显示"Power by DISCUZ2.0 COML"但实际上早就打了高版本补丁所以它实战不能算是2.0版本也不会受漏洞影响



5.在实际使用过程中要具体问题具体分析可以先上传几个普通图片分析通过分析正常图片路径可以判断出很多信息





3 漏洞防范



其实漏洞防范很简单DISCUZ3论坛已经就没这个漏洞了但也肯定不是万无真希望高人能想出利用思路方法



其实它完全可以效法动网论坛文件名指定扩展名指定文件名根据年月日和时间信息生成扩展名手工指定可以采用下面思路方法



先判断扩展名合法性然后



switch($ext)



{



"jpg":



$saveExt="jpg";;



"g":



$saveExt="g";//中间可以加;dfault:



exit("扩展名非法");



}






  • 篇文章: 记次渗透空间服务器艰难的旅

  • 篇文章: 从上传webshell到突破TCP/IP筛选到3389终端登陆
  • 0

    相关文章

    读者评论

    发表评论

    • 昵称:
    • 内容: