WordPress<=4.6_RCE分析
0x01 概述
CVE-2016-10033
主要原因wordpress使用phpmailer组件进行重置密码邮件的发送(所以漏洞存在于所有使用phpmailer组件的cms),漏洞其实是存在于phpmailer,加上wordpress的过滤不严。
漏洞文件:wordpress/wp-includes/class.phpmailer.php and wordpress/wp-includes/pluggable.php
0x02 代码分析
1 | /**来自wordpress/wp-includes/class.phpmailer.php |
既然知道是因为发送邮件引发的rce,那么我们就直接看邮件部分,由最后一句可知,利用系统命令发送邮件,我直接就想到了命令注入。那我们来看参数的获取。
1 | //这一段来自wordpress/wp-includes/pluggable.php |
当调用WordPress wp_mail()函数发送电子邮件时(例如,在用户注册,忘记密码等情况下),WordPress会根据SERVER_NAME服务器标头设置电子邮件域,即$sitename=SERVER_NAME。
发件人地址的格式如下:$ from_email =’wordpress@’.$ sitename;
然后将其简单检测并传递给易受攻击的PHPMailer的setFrom()函数。然后再看看SERVER_NAME这个参数哪里来的.
1 | /**来自wordpress/wp-includes/class.phpmailer.php |
serverHostname函数用于获取SERVER_NAME(主机名),就是请求报文中的HOST,可以看出除了几个判断,明显没有做任何的过滤,所以这里存在命令注入是必然的,但是另一个问题出现了,参数是从HOST头获取的这里不能使用特殊字符,所以直接的命令执行行不通。
0x03 Poc实现
所以既然存在命令注入,如何利用就是我们需要考虑的问题了。既然最后是利用系统命令执行,那我们就来看看,能怎么操盘。sendmail 提供了-O和-X参数,-X参数用于写入日志文件, 可以使用-O QueueDirectory=/tmp/ -X /tmp/test.php命令组合,它会将发送的邮件保存到/tmp/test.php中.但是实际上还需要解决一些问题,且sendmail比我们想象的更加强大.
- wordpress方面以及PHPMailer库方面都会防止攻击者注入空字符(空格或TAB)到sendmail命令中。并且,添加括号引入向sendmail中注入参数的方法已经行不通了.
- 比如我们想要调用/bin/touch的时候也会出问题,因为host字段中如果出现/,服务器会拒绝我们的请求。
但是在ubuntu/debain系统中,已经使用exim4替代了sendmail的功能,现在sendmail文件就是一个链向exim4的链接文件,而exim4又多了-be参数用于读取部分变量的数据,exim4还提供函数来执行一些命令,如字符串截取函数$substr、系统命令调用函数$run。说到字符串截取,应该想到了,曾经使用字符串截取实现无空格的命令执行.说到系统命令调用,就应该命令执行了。字符串截取+命令执行=计划通
于是
- ${substr{0}{1}{$spool_directory}} =/
- ${substr{10}{1}{$tod_log}}=space
- target(any -froot@localhost -be ${command}} null) //payload
tip:command不能出现特殊字符。