网站地图    收藏   

主页 > 后端 > 网站安全 >

Drupal7.xPHP代码执行漏洞分析 - 网站安全 - 自学

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

[导读] 最近在sebug上爆出Drupal7.x有PHP代码执行漏洞,但是又没人分析,所以只好自己下了源码搞下。从官网的安全研究员的博客里,了解了下漏洞的成因,感觉这个问题有点标题党了,这个漏洞...

最近在sebug上爆出Drupal7.x有PHP代码执行漏洞,但是又没人分析,所以只好自己下了源码搞下。从官网的安全研究员的博客里,了解了下漏洞的成因,感觉这个问题有点标题党了,这个漏洞只是一个重新安装的漏洞,至于PHP代码执行,还停留在幻想阶段。这个过程中得到的一个意外收获是,通过后台安装插件的地方有一个文件包含的问题,可以自己构造任意内容插件进行安装,来获得webshell,勉强算是代码执行吧(先把标题党的帽子甩掉)。


0×01 漏洞简述
Drupal 7.16之前的7.x版本中,出现攻击者可重新安装系统漏洞,利用这个问题攻击者可以修改系统连接的数据库为自己的数据库。Drupal厂商针对这个问题已经发布安全公告,安全公告编号为SA-CORE-2012-003。
Drupal系统安装插件模块,存在文件包含问题,攻击者可以利用这个问题,可以在拥有安装插件权限的用户的情况下,上传自己修改的恶意插件,进行安装执行。

0×02 漏洞分析


1. 重现安装问题

在Drupal 7.16版本之前的7.x版本的安装文件install.php中验证系统是否需要重新安装的逻辑出现问题,导致攻击者可尝试绕过验证进行重新安装。
    跟踪install.php执行过程,其大致流程为,导入安装核心文件install.core.inc,并执行其中的install_drupal函数,install_drupal函数关键代码如下:

01 function install_drupal($settings = array()) {
02   global $install_state;
03   // Initialize the installation state with the settings that were passed in,
04   // as well as a boolean indicating whether or not this is an interactive
05   // installation.
06   $interactive = empty($settings);
07   $install_state = $settings + array('interactive' =>$interactive) + install_state_defaults();
08   try {
09     // Begin the page request. This adds information about the current state of
10     // the Drupal installation to the passed-in array.
11 [color=#ff0000]    install_begin_request($install_state);[/color]
12     // Based on the installation state, run the remaining tasks for this page
13     // request, and collect any output.
14     $output = install_run_tasks($install_state);
15   }

    代码中红色的为判断是否需要安装的语句,其调用了install_begin_request函数,再继续跟踪这个函数,关键代码如下:

01 function install_begin_request(&$install_state) {
02   // ...
03   $install_state['settings_verified'] = install_verify_settings();
04   if ($install_state['settings_verified']) {
05     // Initialize the database system. Note that the connection
06     // won't be initialized until it is actually requested.
07     require_once DRUPAL_ROOT .'/includes/database/database.inc';
08  
09     // Verify the last completed task in the database, if there is one.
10 [color=#ff0000]    $task = install_verify_completed_task();[/color]
11   }
12   else {
13     $task = NULL;
14  
15     // …
16  
17 }

    其中红色代码是执行校验的部分,即install_verify_settings()函数在校验中起到了决定性的作用,来看该函数代码:

01 function install_verify_settings() {
02   global $databases;
03  
04   // Verify existing settings (if any).
05   if (!empty($databases) && install_verify_pdo()) {
06     $database = $databases['default']['default'];
07     drupal_static_reset('conf_path');
08     $settings_file = './' . conf_path(FALSE) .'/settings.php';
09 [color=#ff0000]    $errors = install_database_errors($database, $settings_file);[/color]
10     if (empty($errors)) {
11       return TRUE;
12     }
13   }
14   return FALSE;
15 }

    从代码中可以看出,这个函数进行判断只是依据数据库操作是否正常为依据,如果正常则不需重新安装,如果出错就可进行重新安装。
    install_verify_settings()函数中红色代码的功能是,执行一系列的数据库操作,来判断数据库是否正常。这系列数据库操作中,它会创建一个名为drupal_install_test的表,并尝试对其进行insert,update,delete等操作。
    综上所述,想要绕过验证的话,可以通过install_verify_settings()执行过程中,让数据库操作出错就可以了。Drupal官方安全小组的一个研究人员在博客中提出了一种绕过的方法:使用“CREATE TABLE drupal_install_test (id int NULL);”语句创建一个和测试时所用到的表同名的数据表,这样在进行校验的过程中数据库操作就会失败,从而达到绕过验证的目的。不过,在我进行本地实验的过程中,发现这种方法行不通,虽然可以绕过校验,但是,在提交新的数据库信息时会出现错误提示,如下图所示:
1.png

   会提示建立临时表出现冲突,这个问题,我是百思不得其解,跟踪表单的代码过程中,可以确认运行时的数据库信息已经更新为新的数据库信息了。但是,这个临时表居然还会在原来的数据库中建立。这个问题暂时没有想到答案,以后有时间再来看下。

    我自己重现这个漏洞,使用的方法是,将原有的数据库删除,然后便可很顺利的重现安装系统。这个方法能成功,而上面我所提到的方法却出现错误,感觉很怪异,不知哪里有问题。
2. 文件包含问题

在\includes\bootstrap.inc文件中的drupal_load函数,会将要执行的模块代码包含进webserver进程,drupal_load代码如下:

 
01 function drupal_load($type, $name) {
02   // Once a file is included this can't be reversed during a request so do not
03   // use drupal_static() here.
04   static $files = array();
05  
06   if (isset($files[$type][$name])) {
07     return TRUE;
08   }
09  
10   $filename = drupal_get_filename($type, $name);
11  
12   if ($filename) {
13     include_once DRUPAL_ROOT . '/' . $filename;
14     $files[$type][$name] = TRUE;
15  
16     return TRUE;
17   }
18  
19   return FALSE;
20 }

    红色代码为问题代码,Drupal应该是将这部分作为一种特性来开发的,但是其模块安装的方式,可以允许用户上传安装内容。这就导致了,用户可以控制模块加载内容,来执行自己的php代码。
    我自己重现这个问题使用的方法很简单,只需要从官方网站随便下载一个符合相应版本的module,然后本地解压,修改其中后缀为module的文件内容为自己想要执行的php代码,最后重新打包上传到目标站点进行安装即可。安装完毕后,只要我们访问这个模块便可以执行我们的代码了。
0×03 漏洞重现

1. 重现安装问题

 2.png

 

2. 文件包含问题

从官方网站随便下载的一个叫wysiwyg的插件
 3.png

 

       修改其中module文件内容
 4.png

 

      将修改过的文件夹重新打包
 5.png

 

      上传并装到目标站点
 6.png

 

      成功执行内容
 7.png

 

0×04 漏洞总结

1. 重新安装问题需要获得数据库的操作权(不一定是root),方可实现。如获得数据库管理员用户名和密码,且数据库设置为可以对外连接;或者程序某个地方存在注入漏洞。

2. 文件包含问题,需要有后台管理员权限,方可实现。可以结合其他漏洞,例如本篇文章中提到的重新安装问题。

3. 这两个问题的危害性和影响范围比较大,drupal在国内外都是比较流行的cms系统,用户很多,如果出现数据库连接信息泄露或者SQL注入这样的问题,将会   直接导致攻击者可以获得webshell。

4. 在跟踪这两个漏洞的过程中,感觉这套cms比较有趣的地方是,它只有有限的几个php文件,大部分的代码文件都是以inc作为后缀的,在执行的过程中只要将内容包含进php文件执行就可以了。
0×05 防护建议

1. 重现安装问题,Drupal官方已经针对这个问题进行了修补,可以到官网下载最新的7.16版本,下载地址:http://drupal.org/download

2. 文件包含问题,没有太好的解决办法,个人建议,将安装插件这一模块禁用,如果需要安装插件,可以本地的拷贝要安装插件文件夹到安装路径中,也可以实现插件的安装。

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

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

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

添加评论