2016年12月6日(当地时间),blog.ripstech.com网站发布了一条关于Roundcube远程命令执行漏洞的消息。在Roundcube1.2.2及其以前的版本中,deliver_message()函数在调用PHP内建函数mail()时的第5个参数可由用户控制且未经恰当过滤,mail()函数被调用后会使得PHP执行sendmail程序,而未经过滤的第5个参数允许对sendmail程序进行配置,从而使得sendmail程序将邮件流量保存在文件中,攻击者可以利用这个机制通过发送邮件将恶意PHP文件写入webroot目录。
相关链接地址如下:https://blog.ripstech.com/2016/roundcube-command-execution-via-email/
漏洞危害
成功利用漏洞后,可以导致远程命令执行。
什么是Roundcube?
Roundcube Webmail是一个基于浏览器,支持多国语言的IMAP客户端,操作界面看起像一个桌面应用程序。它提供一个e-mail客户端应该具备的所有功能包括MIME支持,地址薄,文件夹操作,信息搜索和拼写检查等。(引用自《百度百科》)
受影响的版本
- Roundcube version 1.1.x < 1.1.7
- Roundcube version 1.2.x < 1.2.3
不受影响的版本
- Roundcube version 1.1.x = 1.1.7
- Roundcube version 1.2.x = 1.2.3
漏洞成因
该漏洞的成因是,函数deliver_message()在调用mail()函数时所传入的第5个参数未经恰当过滤,导致攻击者可以对sendmail程序进行配置从而保存邮件流量到文件中,进而使攻击者有机会将恶意PHP文件写入服务器的webroot目录中。触发漏洞的代码如下所示:
program/steps/mail/sendmail.inc
$from = rcube_utils::get_input_value(’_from’, rcube_utils::INPUT_POST, true, $message_charset); ⋮ $sent = $RCMAIL->deliver_message($MAIL_MIME, $from, $mailto,$smtp_error, $mailbody_file, $smtp_opts);
上述代码从POST参数中获取“_from”的值,并且将其作为第二个参数传入deliver_message()函数。
program/lib/Roundcube/rcube.php
public function deliver_message(&$message, $from, $mailto, &$error, &$body_file = null, $options = null) { ⋮ 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”);
而上述代码会把未经恰当过滤的参数传入mail()函数。
过滤失败的原因如下:
program/steps/mail/sendmail.inc
else if ($from_string = rcmail_email_input_format($from)) { if (preg_match(‘/(\S+@\S+)/‘, $from_string, $m)) $from = trim($m1, ‘<>‘); else $from = null; }
虽然上述代码对用户控制的参数进行了正则表达式匹配,对用户输入采取了过滤措施;然而该过滤措施只在rcmail_email_input_format()函数返回TRUE时才会被执行。下面看一下rcmail_email_input_format()函数的具体实现:
program/steps/mail/sendmail.inc
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+‘; ⋮ // 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)) { $item = rcube_utils::idn_to_ascii(trim($item, ‘<>‘)); $result[] = $item; } ⋮ else if (trim($item)) { continue; } ⋮ } if ($count) { $RECIPIENT_COUNT += count($result); } return implode(‘, ‘, $result); }
上述代码中的“if (preg_match(‘/^<‘.$email_regexp.‘>$/’, $item))”可以被攻击者有意构造的数据匹配失败,从而导致变量$result为空,这在if条件判断中相当于FALSE,从而导致前面提到的过滤被绕过,最终导致漏洞的发生。
规避方案
官方已经发布了针对该漏洞的版本更新,建议用户升级到不受影响的最新版本,下载页面如下:
https://roundcube.net/download/
声 明
本安全公告仅用来描述可能存在的安全问题,绿盟科技不为此安全公告提供任何保证或承诺。由于传播、利用此安全公告所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,绿盟科技以及安全公告作者不为此承担任何责任。绿盟科技拥有对此安全公告的修改和解释权。如欲转载或传播此安全公告,必须保证此安全公告的完整性,包括版权声明等全部内容。未经绿盟科技允许,不得任意修改或者增减此安全公告内容,不得以任何方式将其用于商业目的。
关于绿盟科技
北京神州绿盟信息安全科技股份有限公司(简称绿盟科技)成立于2000年4月,总部位于北京。在国内外设有30多个分支机构,为政府、运营商、金融、能源、互联网以及教育、医疗等行业用户,提供具有核心竞争力的安全产品及解决方案,帮助客户实现业务的安全顺畅运行。
基于多年的安全攻防研究,绿盟科技在网络及终端安全、互联网基础安全、合规及安全管理等领域,为客户提供入侵检测/防护、抗拒绝服务攻击、远程安全评估以及Web安全防护等产品以及专业安全服务。
北京神州绿盟信息安全科技股份有限公司于2014年1月29日起在深圳证券交易所创业板上市交易,股票简称:绿盟科技,股票代码:300369。
如果您需要了解更多内容,可以
加入QQ群:486207500、570982169
直接询问:010-68438880-8669