好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

最近在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);]语句创建一个和测试时所用到的表同名的数据表,这样在进行校验的过程中数据库操作就会失败,从而达到绕过验证的目的。不过,在我进行本地实验的过程中,发现这种方法行不通,虽然可以绕过校验,但是,在提交新的数据库信息时会出现错误提示,如下图所示:

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

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

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

 

       修改其中module文件内容  

 

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

 

      上传并装到目标站点  

 

      成功执行内容  

 

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

查看更多关于Drupal7.xPHP代码执行漏洞分析 - 网站安全 - 自学的详细内容...

  阅读:57次