搜索此博客

2016年12月13日星期二

Roundcube 1.2.2 远程命令执行漏洞 漏洞分析

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Roundcube 1.2.2 远程命令执行漏洞 漏洞分析  阅读原文»

Author: p0wd3r, LG (知道创宇404安全实验室) Date: 2016-12-08

0x00 漏洞概述


1.漏洞简介

著名的PHP代码审计工具 RIPS 于12月6日发布了一份针对 Roundcube扫描报告,报告中提到了一个远程命令执行漏洞,利用该漏洞攻击者可以在授权状态下执行任意代码。官方已发布升级公告

2.漏洞影响

触发漏洞需满足以下几个前提:

  1. Roundcube 使用 PHP 的 mail 来发送邮件,而不通过其他 SMTP Server
  2. PHP 的 mail 使用 sendmail 来发送邮件(默认)
  3. PHP 的 safe_mode 是关闭的(默认)
  4. 攻击者需要知道 Web 应用的绝对路径
  5. 攻击者可以登录到 Roundcube 并可以发送邮件

成功攻击后攻击者可远程执行任意代码。

3.影响版本

1.1.x < 1.1.7

1.2.x < 1.2.3

0x01 漏洞复现


1. 环境搭建

Dockerfile:

FROM analogic/poste.io  RUN apt-get update && apt-get install -y sendmail

然后执行:

docker build -t webmail-test .    mkdir /tmp/data    docker run -p 25:25 -p 127.0.0.1:8080:80 -p 443:443 -p 110:110 -p 143:143 -p 465:465 -p 587:587 -p 993:993 -p 995:995 -v /etc/localtime:/etc/localtime:ro -v /tmp/data:/data --name webmail --hostname xxx.xxx -t webmail-test    docker cp webmail:/opt/www/webmail/config/config.inc.php /tmp/config.inc.php    vim /tmp/config.inc.php  将 $config['smtp_server'] 置为空    docker cp /tmp/config.inc.php webmail:/opt/www/webmail/config/config.inc.php

然后访问http://127.0.0.1:8080按步骤安装即可.

2.漏洞分析

首先看program/steps/mail/sendmail.inc第95-114行:

// Get sender name and address...  $from = rcube_utils::get_input_value('_from', rcube_utils::INPUT_POST, true, $message_charset);  // ... from identity...  if (is_numeric($from)) {      ...  }  // ... if there is no identity record, this might be a custom from  else if ($from_string = rcmail_email_input_format($from)) {      if (preg_match('/(S+@S+)/', $from_string, $m))          $from = trim($m[1], '<>');      else          $from = null;  }

这里取$_POST中的_from赋值给$from,如果$from不是数字就交给rcmail_email_input_format处理,处理后如果返回非空则再过滤$from,使其满足正常 email 的形式。

我们看一下rcmail_email_input_format,在program/steps/mail/sendmail.inc第839-896行:

function rcmail_email_input_format($mailto, $count=false, $check=true)  {      global $RCMAIL, $EMAIL_FORMAT_ERROR, $RECIPIENT_COUNT;        // simplified email regexp, supporting quoted local part      $email_regexp = '(S+|("[^"]+"))@S+';        $delim   = trim($RCMAIL->config->get('recipients_separator', ','));      $regexp  = array("/[,;$delim]s*[rn]+/", '/[rn]+/', "/[,;$delim]s*$/m", '/;/', '/(S{1})(<'.$email_regexp.'>)/U');      $replace = array($delim.' ', ', ', '', $delim, ' ');        // replace new lines and strip ending ', ', make address input more valid      $mailto = trim(preg_replace($regexp, $replace, $mailto));      $items  = rcube_utils::explode_quoted_string($delim, $mailto);      $result = array();        foreach ($items as $item) {          $item = trim($item);          // address in brackets without name (do nothing)          if (preg_match('/^<'.$email_regexp.'>$/', $item)) {              ...          }          // address without brackets and without name (add brackets)          else if (preg_match('/^'.$email_regexp.'$/', $item)) {              ...          }          // address with name (handle name)          else if (preg_match('/<*'.$email_regexp.'>*$/', $item, $matches)) {              ...          }          else if (trim($item)) {              continue;          }          ...      }        ...        return implode(', ', $result);  }

foreach中的正则仅匹配正常的from格式,即xxx@xxx,如果匹配不到则continue,所以如果我们提交xxx@xxx -a -b这样的"空格 + 数据",函数最终并没有对其进行改变,返回的$result也就是空了,进而执行完函数后不会再对$from进行过滤。

接下来在program/steps/mail/sendmail.inc第528行:

$sent = $RCMAIL->deliver_message($MAIL_MIME, $from, $mailto, $smtp_error, $mailbody_file, $smtp_opts);

$from被传入了deliver_message中,在program/lib/Roundcube/rcube.php第1524-1678行:

public function deliver_message(&$message, $from, $mailto, &$error, &$body_file = null, $options = null)  {        // send thru SMTP server using custom SMTP library      if ($this->config->get('smtp_server')) {          ...      }      // send mail using PHP's mail() function      else {          ...          if (filter_var(ini_get('safe_mode'), FILTER_VALIDATE_BOOLEAN))              $sent = mail($to, $subject, $msg_body, $header_str);          else              $sent = mail($to, $subject, $msg_body, $header_str, "-f$from");          }      }      ...  }

可以看到当我们使用PHP的mail函数来发送邮件时$from会被拼接到mail的第五个参数中,这个参数的用处如下:

add-para

意思就是PHP的mail默认使用/usr/sbin/sendmail发送邮件(可在php.ini中设置),mail的第五个参数就是设置sendmail的额外参数。

sendmail有一个-X参数,该参数将邮件流量记录在指定文件中:logfile

所以到这里攻击思路如下:

  1. 构造邮件内容为想要执行的代码
  2. 点击发送时抓包更改_from
  3. sendmail将流量记录到 php 文件中

实际操作一下:

首先登录 Roundcube 并开始发送邮件:admin-dashboard

点击发送,截包修改:

original风险评价与运维安全沙龙邀请函――数字风险新时代  阅读原文»

随着数字经济时代的到来,传统的安全解决方案已经无法满足新的风险领域挑战。企业如何在全新的数字风险领域实现有效控制?如何应对不断变化的互联网威胁?内部面临的信息安全问题如何由传统的定期评估改进升级为自动化运营?

%e9%82%80%e8%af%b7%e5%87%bd1222-800

北京谷安天下科技有限公司、北京数字观星科技有限公司及中国电信云堤的风险管理专家将结合国际国内最佳实践与来宾分享业界前沿的应对思路及方法,期待您的到来!

会议时间:2016年12月22日 下午14:00-17:00

会议地点:深圳罗湖京基100 KKMALL蔡屋围一街[3D Coffice]2F(地铁1号罗宝线大剧院站)

会议人数:40-50人

庆典礼遇:现场签到来宾送"安全牛课堂"专属价值999元"文官""武官"二选一在线课程

会议安排

13:00-14:00 签到

14:00-14:30 网络安全评价服务的兴起-安全值 赵毅 谷安天下产品经理

14:35-15:05 数字时代的风险控制 张妤 谷安天下副总

15:10-15:25 茶歇

15:25-16:05 基于威胁情报数据的安全运营新模式 刘然 数字观星产品经理

16:10-16:40 借网络之力,护金融安全 张昕 中国电信集团安全专家

 


黑客技术官网地址:http://www.hackdig.com/

阅读更多内容

没有评论: