Pochi giorni fa è stata pubblicata la nuova versione di XSS cheat sheet aggiornata al 14 gennaio 2020. In questa nuova versione ho partecipato inserendo un'intera e nuova sezione dedicata a "WAF Bypass" sfruttando JavaScript global object.

nuova sezione dedicata a bypass via JavaScript global object
credits

Per chi non lo conoscesse, Cross-site scripting (XSS) cheat sheet di PortSwigger contiene numerosi payload per sfruttare vulnerabilità XSS (sia stored che reflected e sia che si tratti di server side o DOM based) ma soprattuto per evadere filtri o regole di web application firewall. Ogni vettore di attacco ha il suo relativo PoC, oltre che alla descrizione e un esempio di sintassi URL-decoded.

Parte dei payload che ho inserito nella nuova sezione del XSS cheat sheet lo avevo già pubblicato sul nostro canale YouTube e su un articolo su secjuice Bypass XSS filters using JavaScript global variables. Ciò che manca, e che descriverò in questo articolo, sono alcune tecniche basate principalmente su diverse tipologie di character encoding e sulla proprietà source di RegExp .

Come abbiamo visto nel video, quando parliamo di bypass di regole di un application firewall, la maggior parte dei casi sono tecniche che rientrano in 4 principali categorie: string concatenation, character encoding, escape sequence e comments. Relativamente al character encoding, JavaScript (come altri linguaggi) permette di utilizzare sequenze di escape per rappresentare sepcifici caratteri. Ad esempio sotto forma di octal escape sequences. Qualsiasi carattere con codice inferiore a 256 (extended ASCII range) può essere rappresentato tramite sequenza di escape come \nnn. Stesso discorso vale per sequenze di escape esadecimale (\xnn)

Ad esempio, il simbolo di copyright '©' (character code 169), che in base-8 è 251 e in base-16 è A9. Questo significa che in JavaScript potrò rappresentare il simbolo di copyright con le seguentu sequenze di escape:

  • \251 (octal)
  • \xa9 (hex)

Tutto ciò ci permette di bypassare facilmente filtri basati su black-list di parole. Può sembrare strano, ma alcuni application firewall implementano regole per mitigare XSS che si basano esclusivamente su blacklist di stringhe come "document" o "document.cookie". In questo caso potremmo bypassare i filtri selezionando l'oggetto document dal global object window e selezionare l'oggetto cookie dal relativo window[document] senza aver bisogno di inviare le stringhe "document" e "cookie" all'interno dell'input.

Octal escape:

document = \144\157\143\165\155\145\156\164
cookie = \143\157\157\153\151\145

window['\144\157\143\165\155\145\156\164']['\143\157\157\153\151\145']

Hex escape:

document = \x64\x6f\x63\x75\x6d\x65\x6e\x74
cookie = \x63\x6f\x6f\x6b\x69\x65

window['\x64\x6f\x63\x75\x6d\x65\x6e\x74']['\x63\x6f\x6f\x6b\x69\x65']

Stesso discorso, ma con diversa sintassi, per quanto riguarda unicode escape sequence che prevedono una sequenza come \u{5-hex}.

Unicode escpae

document = \u{64}\u{6f}\u{63}\u{75}\u{6d}\u{65}\u{6e}\u{74}
cookie = '\u{63}\u{6f}\u{6f}\u{6b}\u{69}\u{65}'

window['\u{64}\u{6f}\u{63}\u{75}\u{6d}\u{65}\u{6e}\u{74}']['\u{63}\u{6f}\u{6f}\u{6b}\u{69}\u{65}']

RegExp.prototype.source

La propietà source di un oggetto RegExp restituisce una stringa contenente il testo sorgente delle regular expression (esclusi i delimiter /).

The source property returns a String containing the source text of the regexp object, and it doesn't contain the two forward slashes on both sides and any flags. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source

Posso sfruttare questa proprietà per specificare stringhe di testo senza utilizzare caratteri double e single quote all'interno dell'input che potrebbero essere bloccati o sanitizzati dall'applicazione o da un application firewall. Per seguire gli esempi precedenti:

Reference

Commenti

XSS cheat sheet di PortSwigger from r/Rev3rse_Security