如何寻找WEB程序漏洞及如何利用和防范

作者:小华 QQ:56111981

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

文章已发表于黑客X档案12期 转载请注明

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

一 漏洞分析

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

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

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

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

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

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

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

DISCUZ论坛的上传函数是include/post.php下面的attach_upload。我一步一步解释程序的执行过程,涉及关键代码处我会详细说明。

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

//获得全局变量

if(!function_exists(is_uploaded_file)) {

if(!is_uploaded_file($attach)) {

return false;

}

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

return false;

}

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

$attach_name = daddslashes($attach_name);

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

showmessage(post_attachment_ext_notallowed);

}

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

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

showmessage(post_attachment_toobig);

}

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

$filename = $attach_name;

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

if($attachsave) {

switch($attachsave) {

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

case 2: $attach_subdir = ext_.$extension; break;

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

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

}

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

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

}

$attach_fname = $attach_subdir./;

} else {

$attach_fname = ;

}

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

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

if(preg_match(“/[x7f-xff]+/s”, $filename)) {

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

}

//过滤非ASCII字符

if(in_array($extension, array(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变量,可以看到它是三个变量组成:$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了,看如何利用漏洞。

二 漏洞变换利用

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

我们把$attach

回味起来却有久久不会退去的余香。

如何寻找WEB程序漏洞及如何利用和防范

相关文章:

你感兴趣的文章:

标签云: