CSS Injection
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
CSS selektori su napravljeni da odgovaraju vrednostima atributa name
i value
elementa input
. Ako atribut vrednosti elementa input počinje sa određenim karakterom, učitava se unapred definisani spoljašnji resurs:
Međutim, ovaj pristup se suočava sa ograničenjem kada se radi o skrivenim ulaznim elementima (type="hidden"
) jer skriveni elementi ne učitavaju pozadine.
Da biste zaobišli ovo ograničenje, možete ciljati sledeći element brata koristeći ~
general sibling combinator. CSS pravilo se zatim primenjuje na sve braće koja slede skriveni ulazni element, uzrokujući učitavanje pozadinske slike:
Praktičan primer iskorišćavanja ove tehnike detaljno je opisan u priloženom kodu. Možete ga pogledati ovde.
Da bi tehnika CSS Injection bila efikasna, moraju biti ispunjeni određeni uslovi:
Dužina Payload-a: Vektor CSS injekcije mora podržavati dovoljno duge payload-ove da bi se prilagodili kreiranim selektorima.
Ponovna evaluacija CSS-a: Trebalo bi da imate mogućnost da uokvirite stranicu, što je neophodno za pokretanje ponovne evaluacije CSS-a sa novim generisanim payload-ima.
Spoljni resursi: Tehnika pretpostavlja mogućnost korišćenja slika hostovanih na spoljnim serverima. Ovo može biti ograničeno politikom bezbednosti sadržaja (CSP) sajta.
Kao što je objašnjeno u ovom postu, moguće je kombinovati selektore :has
i :not
da bi se identifikovao sadržaj čak i iz slepih elemenata. Ovo je veoma korisno kada nemate pojma šta se nalazi unutar web stranice koja učitava CSS injekciju.
Takođe je moguće koristiti te selektore za ekstrakciju informacija iz nekoliko blokova istog tipa kao u:
Kombinovanjem ovoga sa sledećom @import tehnikom, moguće je eksfiltrirati mnogo informacija koristeći CSS injekciju sa slepih stranica uz blind-css-exfiltration.
Prethodna tehnika ima neke nedostatke, proverite preduslove. Morate biti u mogućnosti da pošaljete više linkova žrtvi, ili morate biti u mogućnosti da iframe-ujete stranicu ranjivu na CSS injekciju.
Međutim, postoji još jedna pametna tehnika koja koristi CSS @import
da poboljša kvalitet tehnike.
Ovo je prvi put prikazano od strane Pepe Vila i funkcioniše ovako:
Umesto da učitavamo istu stranicu iznova i iznova sa desetinama različitih payload-a svaki put (kao u prethodnoj), učitaćemo stranicu samo jednom i samo sa importom na server napadača (ovo je payload koji treba poslati žrtvi):
Uvoz će primiti neki CSS skript od napadača i pregledač će ga učitati.
Prvi deo CSS skripta koji će napadač poslati je još jedan @import
na server napadača ponovo.
Server napadača neće odgovoriti na ovaj zahtev još, jer želimo da otkrijemo neke karaktere i zatim odgovorimo na ovaj uvoz sa payload-om da otkrijemo sledeće.
Drugi i veći deo payload-a će biti payload za curenje atribut selektora
Ovo će poslati serveru napadača prvi karakter tajne i poslednji.
Kada server napadača primi prvi i poslednji karakter tajne, on će odgovoriti na uvoz zatražen u koraku 2.
Odgovor će biti tačno isti kao u koracima 2, 3 i 4, ali ovaj put će pokušati da pronađe drugi karakter tajne i zatim pretposlednji.
Napadač će slediti tu petlju dok ne uspe potpuno da otkrije tajnu.
Možete pronaći originalni kod Pepe Vile za eksploataciju ovde ili možete pronaći skoro isti kod ali komentarisani ovde.
Skript će pokušati da otkrije 2 karaktera svaki put (od početka i od kraja) jer atribut selektor omogućava da se rade stvari kao:
Ovo omogućava skripti da brže otkrije tajnu.
Ponekad skripta ne detektuje ispravno da je otkriveni prefiks + sufiks već potpuna zastava i nastaviće napred (u prefiksu) i unazad (u sufiksu) i u nekom trenutku će se zamrznuti. Bez brige, samo proverite izlaz jer možete videti zastavu tamo.
Ostali načini za pristup delovima DOM-a pomoću CSS selektora:
.class-to-search:nth-child(2)
: Ovo će pretražiti drugi element sa klasom "class-to-search" u DOM-u.
:empty
selektor: Koristi se na primer u ovoj analizi:
Referenca: CSS zasnovan napad: Zloupotreba unicode-range @font-face, Greška zasnovana XS-Search PoC od @terjanq
Opšta namera je da se koristi prilagođeni font sa kontrolisanog krajnjeg tačke i osigura da se tekst (u ovom slučaju, 'A') prikazuje sa ovim fontom samo ako navedeni resurs (favicon.ico
) ne može biti učitan.
Korišćenje Prilagođenih Fontova:
Prilagođeni font se definiše koristeći pravilo @font-face
unutar <style>
taga u <head>
sekciji.
Font se naziva poc
i preuzima se sa spoljnog krajnjeg tačke (http://attacker.com/?leak
).
Svojstvo unicode-range
je postavljeno na U+0041
, cilja specifični Unicode karakter 'A'.
Element Objekta sa Rezervnim Tekstom:
<object>
element sa id="poc0"
se kreira u <body>
sekciji. Ovaj element pokušava da učita resurs sa http://192.168.0.1/favicon.ico
.
font-family
za ovaj element je postavljen na 'poc'
, kao što je definisano u <style>
sekciji.
Ako resurs (favicon.ico
) ne uspe da se učita, rezervni sadržaj (slovo 'A') unutar <object>
taga se prikazuje.
Rezervni sadržaj ('A') će biti prikazan koristeći prilagođeni font poc
ako spoljašnji resurs ne može da se učita.
:target
pseudo-klasa se koristi za selektovanje elementa koji je ciljan od strane URL fragmenta, kao što je navedeno u CSS Selectors Level 4 specification. Ključno je razumeti da ::target-text
ne odgovara nijednom elementu osim ako tekst nije eksplicitno ciljan fragmentom.
Bezbednosna zabrinutost se javlja kada napadači koriste funkciju Scroll-to-text fragmenta, omogućavajući im da potvrde prisustvo specifičnog teksta na veb stranici učitavanjem resursa sa svog servera putem HTML injekcije. Metoda uključuje injektovanje CSS pravila poput ovog:
U takvim scenarijima, ako je tekst "Administrator" prisutan na stranici, resurs target.png
se zahteva sa servera, što ukazuje na prisustvo teksta. Primer ovog napada može se izvršiti putem posebno kreirane URL adrese koja ugrađuje injektovani CSS zajedno sa fragmentom Scroll-to-text:
Ovde, napad manipuliše HTML injekcijom kako bi prenio CSS kod, ciljajući na specifičan tekst "Administrator" kroz Scroll-to-text fragment (#:~:text=Administrator
). Ako se tekst pronađe, navedeni resurs se učitava, nenamerno signalizirajući svoju prisutnost napadaču.
Za ublažavanje, sledeće tačke treba imati na umu:
Ograničeno STTF podudaranje: Scroll-to-text Fragment (STTF) je dizajniran da se podudara samo sa rečima ili rečenicama, čime se ograničava njegova sposobnost da otkrije proizvoljne tajne ili tokene.
Ograničenje na kontekste najvišeg nivoa pretraživanja: STTF funkcioniše isključivo u kontekstima najvišeg nivoa pretraživanja i ne radi unutar iframe-ova, čineći svaki pokušaj eksploatacije uočljivijim za korisnika.
Potrebna aktivacija korisnika: STTF zahteva gest aktivacije korisnika da bi funkcionisao, što znači da su eksploatacije moguće samo kroz navigacije koje inicira korisnik. Ovaj zahtev značajno smanjuje rizik od automatizovanih napada bez interakcije korisnika. Ipak, autor bloga ukazuje na specifične uslove i zaobilaženja (npr. socijalno inženjerstvo, interakcija sa prisutnim ekstenzijama pretraživača) koja bi mogla olakšati automatizaciju napada.
Svest o ovim mehanizmima i potencijalnim ranjivostima je ključna za održavanje bezbednosti veba i zaštitu od ovakvih eksploatativnih taktika.
Za više informacija proverite izvorni izveštaj: https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/
Možete proveriti eksploit koristeći ovu tehniku za CTF ovde.
Možete odrediti spoljašnje fontove za specifične unicode vrednosti koje će biti prikupljene samo ako su te unicode vrednosti prisutne na stranici. Na primer:
When you access this page, Chrome and Firefox fetch "?A" and "?B" because text node of sensitive-information contains "A" and "B" characters. But Chrome and Firefox do not fetch "?C" because it does not contain "C". This means that we have been able to read "A" and "B".
Reference: Wykradanje podataka u sjajnom stilu – odnosno kako iskoristiti CSS za napade na web aplikaciju
The technique described involves extracting text from a node by exploiting font ligatures and monitoring changes in width. The process involves several steps:
Creation of Custom Fonts:
SVG fonts are crafted with glyphs having a horiz-adv-x
attribute, which sets a large width for a glyph representing a two-character sequence.
Example SVG glyph: <glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>
, where "XY" denotes a two-character sequence.
These fonts are then converted to woff format using fontforge.
Detection of Width Changes:
CSS is used to ensure that text does not wrap (white-space: nowrap
) and to customize the scrollbar style.
The appearance of a horizontal scrollbar, styled distinctly, acts as an indicator (oracle) that a specific ligature, and hence a specific character sequence, is present in the text.
The CSS involved:
Exploit Process:
Step 1: Fonts are created for pairs of characters with substantial width.
Step 2: A scrollbar-based trick is employed to detect when the large width glyph (ligature for a character pair) is rendered, indicating the presence of the character sequence.
Step 3: Upon detecting a ligature, new glyphs representing three-character sequences are generated, incorporating the detected pair and adding a preceding or succeeding character.
Step 4: Detection of the three-character ligature is carried out.
Step 5: The process repeats, progressively revealing the entire text.
Optimization:
The current initialization method using <meta refresh=...
is not optimal.
A more efficient approach could involve the CSS @import
trick, enhancing the exploit's performance.
Reference: PoC koristeći Comic Sans od @Cgvwzq & @Terjanq
This trick was released in this Slackers thread. The charset used in a text node can be leaked using the default fonts installed in the browser: no external -or custom- fonts are needed.
The concept revolves around utilizing an animation to incrementally expand a div
's width, allowing one character at a time to transition from the 'suffix' part of the text to the 'prefix' part. This process effectively splits the text into two sections:
Prefix: The initial line.
Suffix: The subsequent line(s).
The transition stages of the characters would appear as follows:
C ADB
CA DB
CAD B
CADB
During this transition, the unicode-range trick is employed to identify each new character as it joins the prefix. This is achieved by switching the font to Comic Sans, which is notably taller than the default font, consequently triggering a vertical scrollbar. This scrollbar's appearance indirectly reveals the presence of a new character in the prefix.
Although this method allows the detection of unique characters as they appear, it does not specify which character is repeated, only that a repetition has occurred.
Basically, the unicode-range is used to detect a char, but as we don't want to load an external font, we need to find another way. When the char is found, it's given the pre-installed Comic Sans font, which makes the char bigger and triggers a scroll bar which will leak the found char.
Check the code extracted from the PoC:
Reference: Ovo je pomenuto kao neuspešno rešenje u ovom izveštaju
Ovaj slučaj je veoma sličan prethodnom, međutim, u ovom slučaju cilj pravljenja specifičnih karaktera većim od drugih je da se sakrije nešto poput dugmeta koje ne bi trebalo da bude pritisnuto od strane bota ili slike koja se neće učitati. Tako bismo mogli meriti akciju (ili nedostatak akcije) i znati da li je specifičan karakter prisutan unutar teksta.
Reference: Ovo je pomenuto kao neuspešno rešenje u ovom izveštaju
U ovom slučaju, mogli bismo pokušati da curimo da li je karakter u tekstu učitavanjem lažnog fonta iz iste domene:
Ako postoji podudaranje, font će biti učitan sa /static/bootstrap.min.css?q=1
. Iako se neće učitati uspešno, pregledač bi trebao da ga kešira, i čak i ako nema keša, postoji 304 not modified mehanizam, tako da bi odgovor trebao biti brži od drugih stvari.
Međutim, ako razlika u vremenu između keširanog odgovora i onog koji nije keširan nije dovoljno velika, ovo neće biti korisno. Na primer, autor je pomenuo: Međutim, nakon testiranja, otkrio sam da je prvi problem to što se brzina ne razlikuje mnogo, a drugi problem je što bot koristi disk-cache-size=1
flag, što je zaista promišljeno.
Reference: Ovo se pominje kao neuspešno rešenje u ovom izveštaju
U ovom slučaju možete naznačiti CSS da učita stotine lažnih fontova sa iste domene kada dođe do podudaranja. Na ovaj način možete meriti vreme koje je potrebno i otkriti da li se karakter pojavljuje ili ne sa nečim poput:
I kod bota izgleda ovako:
Dakle, ako se font ne poklapa, očekuje se da će vreme odgovora prilikom posete botu biti otprilike 30 sekundi. Međutim, ako dođe do poklapanja fonta, biće poslato više zahteva za preuzimanje fonta, što će uzrokovati kontinuiranu aktivnost mreže. Kao rezultat toga, biće potrebno više vremena da se zadovolji uslov zaustavljanja i primi odgovor. Stoga se vreme odgovora može koristiti kao indikator za određivanje da li postoji poklapanje fonta.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)