# Misc JS Tricks & Relevant Info
Impara l'hacking di AWS da zero a esperto con htARTE (HackTricks AWS Red Team Expert)! * Lavori in una **azienda di sicurezza informatica**? Vuoi vedere la tua **azienda pubblicizzata in HackTricks**? O vuoi avere accesso all'**ultima versione di PEASS o scaricare HackTricks in PDF**? Controlla i [**PACCHETTI DI ABBONAMENTO**](https://github.com/sponsors/carlospolop)! * Scopri [**La Famiglia PEASS**](https://opensea.io/collection/the-peass-family), la nostra collezione di esclusive [**NFT**](https://opensea.io/collection/the-peass-family) * Ottieni il [**merchandising ufficiale di PEASS & HackTricks**](https://peass.creator-spring.com) * **Unisciti al** [**💬**](https://emojipedia.org/speech-balloon/) [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo Telegram**](https://t.me/peass) o **seguimi** su **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Condividi i tuoi trucchi di hacking inviando PR al** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **e al** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
## Fuzzing di Javascript ### Caratteri di commento JS validi ```javascript //This is a 1 line comment /* This is a multiline comment*/ #!This is a 1 line comment, but "#!" must to be at the beggining of the line -->This is a 1 line comment, but "-->" must to be at the beggining of the line for (let j = 0; j < 128; j++) { for (let k = 0; k < 128; k++) { for (let l = 0; l < 128; l++) { if (j == 34 || k ==34 || l ==34) continue; if (j == 0x0a || k ==0x0a || l ==0x0a) continue; if (j == 0x0d || k ==0x0d || l ==0x0d) continue; if (j == 0x3c || k ==0x3c || l ==0x3c) continue; if ( (j == 47 && k == 47) ||(k == 47 && l == 47) ) continue; try { var cmd = String.fromCharCode(j) + String.fromCharCode(k) + String.fromCharCode(l) + 'a.orange.ctf"'; eval(cmd); } catch(e) { var err = e.toString().split('\n')[0].split(':')[0]; if (err === 'SyntaxError' || err === "ReferenceError") continue err = e.toString().split('\n')[0] } console.log(err,cmd); } } } //From: https://balsn.tw/ctf_writeup/20191012-hitconctfquals/#bounty-pl33z // From: Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 43). Kindle Edition. log=[]; for(let i=0;i<=0xff;i++){ for(let j=0;j<=0xfff;j++){ try { eval(`${String.fromCodePoint(i,j)}%$£234$`) log.push([i,j]) }catch(e){} } } console.log(log)//[35,33],[47,47] ``` ### Caratteri di nuova riga JS validi In JavaScript, ci sono diversi caratteri che possono essere utilizzati per rappresentare una nuova riga. Questi caratteri possono essere utilizzati in vari contesti, come all'interno di stringhe o commenti, per creare una nuova riga di codice. Ecco alcuni dei caratteri di nuova riga JS validi: * : rappresenta una nuova riga. * : rappresenta un ritorno a capo. * `\u2028`: rappresenta un separatore di linea Unicode. * `\u2029`: rappresenta un separatore di paragrafo Unicode. È importante notare che questi caratteri possono essere utilizzati in combinazione con altri caratteri per creare sequenze di escape o per ottenere determinati effetti nel codice JavaScript. Ad esempio, può essere utilizzato per creare una nuova riga all'interno di una stringa, come nel seguente esempio: ```javascript var message = "Ciao\nmondo!"; console.log(message); ``` Questo codice produrrà l'output: ``` Ciao mondo! ``` In questo esempio, la sequenza di escape viene interpretata come una nuova riga, consentendo di separare le parole "Ciao" e "mondo!" su due righe separate. ```javascript //Javascript interpret as new line these chars: String.fromCharCode(10) //0x0a String.fromCharCode(13) //0x0d String.fromCharCode(8232) //0xe2 0x80 0xa8 String.fromCharCode(8233) //0xe2 0x80 0xa8 for (let j = 0; j < 65536; j++) { try { var cmd = '"aaaaa";'+String.fromCharCode(j) + '-->a.orange.ctf"'; eval(cmd); } catch(e) { var err = e.toString().split('\n')[0].split(':')[0]; if (err === 'SyntaxError' || err === "ReferenceError") continue; err = e.toString().split('\n')[0] } console.log(`[${err}]`,j,cmd); } //From: https://balsn.tw/ctf_writeup/20191012-hitconctfquals/#bounty-pl33z ``` ### Spazi JS validi nella chiamata di una funzione Sometimes, when trying to bypass filters or WAFs that block certain characters or keywords, it can be useful to use valid JavaScript spaces in function calls. These spaces are not recognized as special characters by the JavaScript interpreter, allowing us to execute our desired code. In JavaScript, there are several types of spaces that can be used: * **Regular space**: This is the standard space character that we use for separating words. It can be represented by the ASCII code `32` or the escape sequence `\x20`. * **No-break space**: This is a non-breaking space that prevents line breaks between words. It can be represented by the ASCII code `160` or the escape sequence `\xa0`. * **Zero-width space**: This is an invisible space that does not take up any visual space. It can be represented by the escape sequence `\u200b`. By using these valid JavaScript spaces in function calls, we can obfuscate our code and make it more difficult for filters or WAFs to detect and block our malicious payloads. Here is an example of how we can use valid JavaScript spaces in a function call: ```javascript alert\u200b('Hello\u200bWorld'); ``` In this example, we are using the zero-width space `\u200b` to separate the function name `alert` and the string `'HelloWorld'`. This code will execute the `alert` function and display the message "Hello World" in the browser. Remember to always test your payloads and ensure that they are working as expected before using them in real-world scenarios. ```javascript // Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (pp. 40-41). Kindle Edition. // Check chars that can be put in between in func name and the () function x(){} log=[]; for(let i=0;i<=0x10ffff;i++){ try { eval(`x${String.fromCodePoint(i)}()`) log.push(i) }catch(e){} } console.log(log)v//9,10,11,12,13,32,160,5760,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,813 232,8233,8239,8287,12288,65279 ``` ### **Caratteri validi per generare stringhe** ```html

Here is a list of valid characters that can be used to generate strings:

``` ```html

Ecco una lista di caratteri validi che possono essere utilizzati per generare stringhe:

``` ```javascript // Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (pp. 41-42). Kindle Edition. // Check which pairs of chars can make something be a valid string log=[]; for(let i=0;i<=0x10ffff;i++){ try { eval(`${String.fromCodePoint(i)}%$£234${String.fromCodePoint(i)}`) log.push(i) }catch(e){} } console.log(log) //34,39,47,96 //single quote, quotes, backticks & // (regex) ``` ### **Surrogate Pairs BF** Questa tecnica non sarà molto utile per XSS, ma potrebbe essere utile per eludere le protezioni WAF. Questo codice Python riceve in input 2 byte e cerca una coppia di surrogati che ha il primo byte come gli ultimi byte della coppia di surrogati alti e l'ultimo byte come l'ultimo byte della coppia di surrogati bassi. ```python def unicode(findHex): for i in range(0,0xFFFFF): H = hex(int(((i - 0x10000) / 0x400) + 0xD800)) h = chr(int(H[-2:],16)) L = hex(int(((i - 0x10000) % 0x400 + 0xDC00))) l = chr(int(L[-2:],16)) if(h == findHex[0]) and (l == findHex[1]): print(H.replace("0x","\\u")+L.replace("0x","\\u")) ``` Ulteriori informazioni: * [https://github.com/dreadlocked/ctf-writeups/blob/master/nn8ed/README.md](https://github.com/dreadlocked/ctf-writeups/blob/master/nn8ed/README.md) * [https://mathiasbynens.be/notes/javascript-unicode](https://mathiasbynens.be/notes/javascript-unicode) [https://mathiasbynens.be/notes/javascript-encoding](https://mathiasbynens.be/notes/javascript-encoding) ### Fuzzing del protocollo `javascript{}:` ```javascript // Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 34). Kindle Edition. log=[]; let anchor = document.createElement('a'); for(let i=0;i<=0x10ffff;i++){ anchor.href = `javascript${String.fromCodePoint(i)}:`; if(anchor.protocol === 'javascript:') { log.push(i); } } console.log(log)//9,10,13,58 // Note that you could BF also other possitions of the use of multiple chars // Test one option let anchor = document.createElement('a'); anchor.href = `javascript${String.fromCodePoint(58)}:alert(1337)`; anchor.append('Click me') document.body.append(anchor) // Another way to test Test ``` ### URL Fuzzing URL Fuzzing è una tecnica utilizzata per individuare vulnerabilità nelle applicazioni web. Consiste nell'inserire dati di input non validi o imprevisti all'interno degli URL per testare la risposta dell'applicazione. Questo può includere l'inserimento di caratteri speciali, sequenze di escape, parametri aggiuntivi o modifiche nella struttura dell'URL. L'obiettivo è identificare eventuali errori o comportamenti anomali che potrebbero essere sfruttati per eseguire attacchi come l'iniezione di codice o il bypass di controlli di sicurezza. ```javascript // Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (pp. 36-37). Kindle Edition. // Before the protocol a=document.createElement('a'); log=[]; for(let i=0;i<=0x10ffff;i++){ a.href = `${String.fromCodePoint(i)}https://hacktricks.xyz`; if(a.hostname === 'hacktricks.xyz'){ log.push(i); } } console.log(log) //0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 // Between the slashes a=document.createElement('a'); log=[]; for(let i=0;i<=0x10ffff;i++){ a.href = `/${String.fromCodePoint(i)}/hacktricks.xyz`; if(a.hostname === 'hacktricks.xyz'){ log.push(i); } } console.log(log) //9,10,13,47,92 ``` ### Fuzzing HTML Il fuzzing HTML è una tecnica utilizzata per individuare vulnerabilità di cross-site scripting (XSS) in un'applicazione web. Consiste nell'inserire dati di input non validi o imprevisti nei campi di input dell'applicazione per verificare se l'applicazione è in grado di gestirli correttamente. Il fuzzing HTML può essere eseguito in diversi modi, ad esempio: * Inserendo caratteri speciali come "<", ">", "&" nei campi di input per verificare se l'applicazione esegue una corretta sanitizzazione dei dati. * Inserendo tag HTML o attributi non validi nei campi di input per verificare se l'applicazione li interpreta correttamente. * Inserendo script JavaScript nei campi di input per verificare se l'applicazione esegue una corretta sanitizzazione dei dati e previene l'esecuzione di codice dannoso. Durante il fuzzing HTML, è importante monitorare le risposte dell'applicazione per individuare eventuali errori o comportamenti anomali. Inoltre, è consigliabile utilizzare strumenti di fuzzing automatizzati per accelerare il processo di individuazione delle vulnerabilità. Una volta individuata una potenziale vulnerabilità di XSS, è necessario testarla ulteriormente per confermare la sua presenza e determinare il suo impatto. Ciò può essere fatto inserendo script JavaScript di prova per verificare se è possibile eseguire codice arbitrario nell'applicazione. In conclusione, il fuzzing HTML è una tecnica efficace per individuare vulnerabilità di XSS in un'applicazione web. È importante eseguirlo in modo accurato e sistematico per garantire la sicurezza dell'applicazione. ```javascript // Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 38). Kindle Edition. // Fuzzing chars that can close an HTML comment let log=[]; let div = document.createElement('div'); for(let i=0;i<=0x10ffff;i++){ div.innerHTML=``; if(div.querySelector('span')){ log.push(i); } } console.log(log)//33,45,62 ``` ## **Analisi degli attributi** Lo strumento **Hackability inspector** di Portswigger aiuta ad **analizzare** gli **attributi** di un oggetto javascript. Controlla: [https://portswigger-labs.net/hackability/inspector/?input=x.contentWindow\&html=%3Ciframe%20src=//subdomain1.portswigger-labs.net%20id=x%3E](https://portswigger-labs.net/hackability/inspector/?input=x.contentWindow\&html=%3Ciframe%20src=//subdomain1.portswigger-labs.net%20id=x%3E) ## **File .map js** * Trucco per scaricare file .map js: [https://medium.com/@bitthebyte/javascript-for-bug-bounty-hunters-part-2-f82164917e7](https://medium.com/@bitthebyte/javascript-for-bug-bounty-hunters-part-2-f82164917e7) * Puoi utilizzare questo strumento per analizzare questi file [https://github.com/paazmaya/shuji](https://github.com/paazmaya/shuji) ## Assegnazione "--" L'operatore di decremento `--` è anche un'assegnazione. Questo operatore prende un valore e poi lo decrementa di uno. Se quel valore non è un numero, verrà impostato su `NaN`. Questo può essere utilizzato per **rimuovere il contenuto delle variabili dall'ambiente**. ![](<../../.gitbook/assets/image (553).png>) ![](<../../.gitbook/assets/image (554).png>) ## Trucchi delle funzioni ### .call e .apply Il metodo **`.call`** di una funzione viene utilizzato per **eseguire la funzione**.\ Il **primo argomento** che si aspetta di default è il **valore di `this`** e se **niente** viene fornito, **`window`** sarà quel valore (a meno che non venga utilizzato **`strict mode`**). ```javascript function test_call(){ console.log(this.value); //baz } new_this={value:"hey!"} test_call.call(new_this); // To pass more arguments, just pass then inside .call() function test_call() { console.log(arguments[0]); //"arg1" console.log(arguments[1]); //"arg2" console.log(this); //[object Window] } test_call.call(null, "arg1", "arg2") // If you use the "use strict" directive "this" will be null instead of window: function test_call() { "use strict"; console.log(this); //null } test_call.call(null) //The apply function is pretty much exactly the same as the call function with one important difference, you can supply an array of arguments in the second argument: function test_apply() { console.log(arguments[0]); //"arg1" console.log(arguments[1]); //"arg2" console.log(this); //[object Window] } test_apply.apply(null, ["arg1", "arg2"]) ``` ### Funzioni freccia Le funzioni freccia ti permettono di generare funzioni in una singola riga più facilmente (se le comprendi) ```javascript // Traditional function (a){ return a + 1; } // Arrow forms a => a + 100; a => {a + 100}; // Traditional function (a, b){ return a + b + 1; } // Arrow (a, b) => a + b + 100; // Tradictional no args let a = 4; let b = 2; function (){ return a + b + 1; } // Arrow let a = 4; let b = 2; () => a + b + 1; ``` Quindi, la maggior parte delle funzioni precedenti sono in realtà inutili perché non le stiamo salvando da nessuna parte per poterle richiamare. Ad esempio, creiamo la funzione `plusone`: ```javascript // Traductional function plusone (a){ return a + 1; } //Arrow plusone = a => a + 100; ``` ### Funzione bind La funzione bind permette di creare una **copia** di una **funzione modificando** l'oggetto **`this`** e i **parametri** forniti. ```javascript //This will use the this object and print "Hello World" var fn = function ( param1, param2 ) { console.info( this, param1, param2 ); } fn('Hello', 'World') //This will still use the this object and print "Hello World" var copyFn = fn.bind(); copyFn('Hello', 'World') //This will use the "console" object as "this" object inside the function and print "fixingparam1 Hello" var bindFn_change = fn.bind(console, "fixingparam1"); bindFn_change('Hello', 'World') //This will still use the this object and print "fixingparam1 Hello" var bindFn_thisnull = fn.bind(null, "fixingparam1"); bindFn_change('Hello', 'World') //This will still use the this object and print "fixingparam1 Hello" var bindFn_this = fn.bind(this, "fixingparam1"); bindFn_change('Hello', 'World') ``` {% hint style="info" %} Nota che utilizzando **`bind`** puoi manipolare l'oggetto **`this`** che verrà utilizzato quando si chiama la funzione. {% endhint %} ### Fuga di codice della funzione Se puoi **accedere all'oggetto** di una funzione, puoi **ottenere il codice** di quella funzione. ```javascript function afunc(){ return 1+1; } console.log(afunc.toString()); //This will print the code of the function console.log(String(afunc)); //This will print the code of the function console.log(this.afunc.toString()); //This will print the code of the function console.log(global.afunc.toString()); //This will print the code of the function ``` Nei casi in cui la **funzione non ha un nome**, è comunque possibile stampare il **codice della funzione** da all'interno: ```javascript (function (){ return arguments.callee.toString(); })() (function (){ return arguments[0]; })("arg0") ``` Alcuni modi **casuali** per **estrarre il codice** di una funzione (anche i commenti) da un'altra funzione: ```javascript (function (){ return retFunc => String(arguments[0]) })(a=>{/* Hidden commment */})() (function (){ return retFunc => Array(arguments[0].toString()) })(a=>{/* Hidden commment */})() (function (){ return String(this)}).bind(()=>{ /* Hidden commment */ })() (u=>(String(u)))(_=>{ /* Hidden commment */ }) (u=>_=>(String(u)))(_=>{ /* Hidden commment */ })() ``` ## Fuga dalla sandbox - Recupero dell'oggetto window L'oggetto Window consente di accedere alle funzioni definite globalmente come alert o eval. {% code overflow="wrap" %} ```javascript // Some ways to access window window.eval("alert(1)") frames globalThis parent self top //If inside a frame, this is top most window // Access window from document document.defaultView.alert(1) // Access document from a node object node = document.createElement('div') node.ownerDocument.defaultView.alert(1) // There is a path property on each error event whose last element is the window // In other browsers the method is // In case of svg, the "event" object is called "evt" // Abusing Error.prepareStackTrace to get Window back Error.prepareStackTrace=function(error, callSites){ 2 callSites.shift().getThis().alert(1337); 3 }; 4 new Error().stack // From an HTML event // Events from HTML are executed in this context with(document) { with(element) { //executed event } } // Because of that with(document) it's possible to access properties of document like: ``` {% endcode %} ## Punto di interruzione sull'accesso al valore ```javascript // Stop when a property in sessionStorage or localStorage is set/get // via getItem or setItem functions sessionStorage.getItem = localStorage.getItem = function(prop) { debugger; return sessionStorage[prop]; } localStorage.setItem = function(prop, val) { debugger; localStorage[prop] = val; } ``` ```javascript // Stop when anyone sets or gets the property "ppmap" in any object // For example sessionStorage.ppmap // "123".ppmap // Useful to find where weird properties are being set or accessed // or to find where prototype pollutions are occurring function debugAccess(obj, prop, debugGet=true){ var origValue = obj[prop]; Object.defineProperty(obj, prop, { get: function () { if ( debugGet ) debugger; return origValue; }, set: function(val) { debugger; origValue = val; } }); }; debugAccess(Object.prototype, 'ppmap') ``` ## Accesso automatico del browser per testare i payload Sometimes, when testing for Cross-Site Scripting (XSS) vulnerabilities, it can be useful to automate the process of accessing the target website with different payloads. This can help in identifying potential XSS vulnerabilities and their impact. In order to achieve this, you can use tools like Selenium WebDriver or Puppeteer. These tools allow you to control a web browser programmatically, enabling you to interact with web pages, fill out forms, and execute JavaScript code. Here is an example of how you can use Selenium WebDriver with Python to automatically access a website and test XSS payloads: ```python from selenium import webdriver # Create a new instance of the Firefox driver driver = webdriver.Firefox() # Navigate to the target website driver.get("https://www.example.com") # Find an input field on the page input_field = driver.find_element_by_id("input_field") # Clear the input field input_field.clear() # Enter an XSS payload into the input field input_field.send_keys("") # Submit the form input_field.submit() # Close the browser driver.quit() ``` This code snippet demonstrates how you can use Selenium WebDriver to automate the process of accessing a website, entering an XSS payload into an input field, and submitting the form. You can modify the code to test different payloads and explore the website for potential vulnerabilities. By automating the browser access, you can save time and effort in testing for XSS vulnerabilities, allowing you to focus on analyzing the results and identifying potential security issues. ```javascript //Taken from https://github.com/svennergr/writeups/blob/master/inti/0621/README.md const puppeteer = require("puppeteer"); const realPasswordLength = 3000; async function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); //Loop to iterate through different values for (let i = 0; i < 10000; i += 100) { console.log(`Run number ${i}`); const input = `${"0".repeat(i)}${realPasswordLength}`; console.log(` https://challenge-0621.intigriti.io/passgen.php?passwordLength=${input}&allowNumbers=true&allowSymbols=true×tamp=1624556811000`); //Go to the page await page.goto( `https://challenge-0621.intigriti.io/passgen.php?passwordLength=${input}&allowNumbers=true&allowSymbols=true×tamp=1624556811000` ); //Call function "generate()" inside the page await page.evaluate("generate()"); //Get node inner text from an HTML element const passwordContent = await page.$$eval( ".alert .page-content", (node) => node[0].innerText ); //Transform the content and print it in console const plainPassword = passwordContent.replace("Your password is: ", ""); if (plainPassword.length != realPasswordLength) { console.log(i, plainPassword.length, plainPassword); } await sleep(1000); } await browser.close(); })(); ```
Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)! * Lavori in una **azienda di sicurezza informatica**? Vuoi vedere la tua **azienda pubblicizzata in HackTricks**? o vuoi avere accesso all'**ultima versione di PEASS o scaricare HackTricks in PDF**? Controlla i [**PIANI DI ABBONAMENTO**](https://github.com/sponsors/carlospolop)! * Scopri [**La Famiglia PEASS**](https://opensea.io/collection/the-peass-family), la nostra collezione di esclusive [**NFT**](https://opensea.io/collection/the-peass-family) * Ottieni il [**merchandising ufficiale di PEASS & HackTricks**](https://peass.creator-spring.com) * **Unisciti al** [**💬**](https://emojipedia.org/speech-balloon/) [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo Telegram**](https://t.me/peass) o **seguimi** su **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Condividi i tuoi trucchi di hacking inviando PR al** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **e al** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).