LFI2RCE via Eternal waiting
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Από προεπιλογή, όταν ένα αρχείο ανεβαίνει σε PHP (ακόμα και αν δεν το περιμένει), θα δημιουργήσει ένα προσωρινό αρχείο στο /tmp
με ένα όνομα όπως php[a-zA-Z0-9]{6}
, αν και έχω δει μερικές εικόνες docker όπου τα παραγόμενα αρχεία δεν περιέχουν ψηφία.
Σε μια τοπική συμπερίληψη αρχείου, αν καταφέρετε να συμπεριλάβετε αυτό το ανεβασμένο αρχείο, θα αποκτήσετε RCE.
Σημειώστε ότι από προεπιλογή η PHP επιτρέπει μόνο την ανάρτηση 20 αρχείων σε ένα μόνο αίτημα (ρυθμισμένο στο /etc/php/<version>/apache2/php.ini
):
Επίσης, ο αριθμός των πιθανών ονομάτων αρχείων είναι 62*62*62*62*62*62 = 56800235584
Άλλες τεχνικές βασίζονται στην επίθεση πρωτοκόλλων PHP (δεν θα μπορέσετε αν ελέγχετε μόνο το τελευταίο μέρος της διαδρομής), αποκαλύπτοντας τη διαδρομή του αρχείου, εκμεταλλευόμενοι αναμενόμενα αρχεία, ή κάνοντάς την PHP να υποστεί σφάλμα τμηματοποίησης ώστε τα ανεβασμένα προσωρινά αρχεία να μην διαγράφονται. Αυτή η τεχνική είναι πολύ παρόμοια με την τελευταία αλλά χωρίς να χρειάζεται να βρείτε μια zero day.
Σε αυτή την τεχνική χρειαζόμαστε μόνο να ελέγξουμε μια σχετική διαδρομή. Αν καταφέρουμε να ανεβάσουμε αρχεία και να κάνουμε το LFI να μην τελειώνει ποτέ, θα έχουμε "αρκετό χρόνο" για να brute-force τα ανεβασμένα αρχεία και να βρούμε οποιοδήποτε από αυτά που έχουν ανέβει.
Πλεονεκτήματα αυτής της τεχνικής:
Χρειάζεστε μόνο να ελέγξετε μια σχετική διαδρομή μέσα σε μια συμπερίληψη
Δεν απαιτεί nginx ή απροσδόκητο επίπεδο πρόσβασης στα αρχεία καταγραφής
Δεν απαιτεί μια 0 day για να προκαλέσει σφάλμα τμηματοποίησης
Δεν απαιτεί αποκάλυψη διαδρομής
Τα κύρια προβλήματα αυτής της τεχνικής είναι:
Χρειάζεται να είναι παρόν ένα συγκεκριμένο αρχείο(α) (μπορεί να υπάρχουν περισσότερα)
Η τρελή ποσότητα πιθανών ονομάτων αρχείων: 56800235584
Αν ο διακομιστής δεν χρησιμοποιεί ψηφία η συνολική πιθανή ποσότητα είναι: 19770609664
Από προεπιλογή μόνο 20 αρχεία μπορούν να ανέβουν σε μία μόνο αίτηση.
Ο μέγιστος αριθμός παράλληλων εργαζομένων του χρησιμοποιούμενου διακομιστή.
Αυτός ο περιορισμός με τους προηγούμενους μπορεί να κάνει αυτή την επίθεση να διαρκέσει πολύ
Timeout για μια αίτηση PHP. Ιδανικά αυτό θα έπρεπε να είναι αιώνιο ή θα έπρεπε να τερματίσει τη διαδικασία PHP χωρίς να διαγράψει τα προσωρινά ανεβασμένα αρχεία, αν όχι, αυτό θα είναι επίσης ένα πρόβλημα
Λοιπόν, πώς μπορείτε να κάνετε μια συμπερίληψη PHP να μην τελειώνει ποτέ; Απλά συμπεριλαμβάνοντας το αρχείο /sys/kernel/security/apparmor/revision
(δεν είναι διαθέσιμο σε κοντέινερ Docker δυστυχώς...).
Δοκιμάστε το απλά καλώντας:
Κατά προεπιλογή, το Apache υποστηρίζει 150 ταυτόχρονες συνδέσεις, ακολουθώντας https://ubiq.co/tech-blog/increase-max-connections-apache/ είναι δυνατόν να αναβαθμιστεί αυτός ο αριθμός έως και 8000. Ακολουθήστε αυτό για να χρησιμοποιήσετε PHP με αυτό το module: https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04.
Κατά προεπιλογή, (όπως μπορώ να δω στις δοκιμές μου), μια διαδικασία PHP μπορεί να διαρκέσει αιώνια.
Ας κάνουμε μερικά μαθηματικά:
Μπορούμε να χρησιμοποιήσουμε 149 συνδέσεις για να δημιουργήσουμε 149 * 20 = 2980 προσωρινά αρχεία με το webshell μας.
Στη συνέχεια, χρησιμοποιήστε τη τελευταία σύνδεση για brute-force πιθανών αρχείων.
Με ταχύτητα 10 αιτήσεων/δευτερόλεπτο οι χρόνοι είναι:
56800235584 / 2980 / 10 / 3600 ~= 530 ώρες (50% πιθανότητα σε 265h)
(χωρίς ψηφία) 19770609664 / 2980 / 10 / 3600 ~= 185h (50% πιθανότητα σε 93h)
Σημειώστε ότι στο προηγούμενο παράδειγμα DoSάρουμε εντελώς άλλους πελάτες!
Αν ο διακομιστής Apache βελτιωθεί και μπορούσαμε να καταχραστούμε 4000 συνδέσεις (στη μέση του μέγιστου αριθμού). Θα μπορούσαμε να δημιουργήσουμε 3999*20 = 79980
αρχεία και ο αριθμός θα ήταν μειωμένος σε περίπου 19.7h ή 6.9h (10h, 3.5h 50% πιθανότητα).
Αν αντί να χρησιμοποιήσουμε το κανονικό php mod για το apache για να εκτελέσουμε PHP scripts η ιστοσελίδα χρησιμοποιεί PHP-FMP (αυτό βελτιώνει την αποδοτικότητα της ιστοσελίδας, οπότε είναι κοινό να το βρίσκουμε), υπάρχει κάτι άλλο που μπορεί να γίνει για να βελτιωθεί η τεχνική.
Το PHP-FMP επιτρέπει να ρυθμίσουμε την παράμετρο request_terminate_timeout
στο /etc/php/<php-version>/fpm/pool.d/www.conf
.
Αυτή η παράμετρος υποδεικνύει τη μέγιστη ποσότητα δευτερολέπτων όταν η αίτηση προς PHP πρέπει να τερματιστεί (άπειρο κατά προεπιλογή, αλλά 30s αν η παράμετρος είναι αποσχολιασμένη). Όταν μια αίτηση επεξεργάζεται από την PHP για τον υποδεικνυόμενο αριθμό δευτερολέπτων, σκοτώνεται. Αυτό σημαίνει ότι αν η αίτηση ανέβαζε προσωρινά αρχεία, επειδή η επεξεργασία php σταμάτησε, αυτά τα αρχεία δεν θα διαγραφούν. Επομένως, αν μπορείτε να κάνετε μια αίτηση να διαρκέσει αυτόν τον χρόνο, μπορείτε να δημιουργήσετε χιλιάδες προσωρινά αρχεία που δεν θα διαγραφούν, γεγονός που θα ταχύτατα τη διαδικασία εύρεσής τους και μειώνει την πιθανότητα DoS στην πλατφόρμα καταναλώνοντας όλες τις συνδέσεις.
Έτσι, για να αποφύγουμε το DoS ας υποθέσουμε ότι ένας επιτιθέμενος θα χρησιμοποιεί μόνο 100 συνδέσεις ταυτόχρονα και ο μέγιστος χρόνος επεξεργασίας php από php-fmp (request_terminate_timeout
) είναι 30s. Επομένως, ο αριθμός των προσωρινών αρχείων που μπορούν να παραχθούν ανά δευτερόλεπτο είναι 100*20/30 = 66.67
.
Στη συνέχεια, για να δημιουργήσει 10000 αρχεία ένας επιτιθέμενος θα χρειαστεί: 10000/66.67 = 150s
(για να δημιουργήσει 100000 αρχεία ο χρόνος θα είναι 25min).
Στη συνέχεια, ο επιτιθέμενος θα μπορούσε να χρησιμοποιήσει αυτές τις 100 συνδέσεις για να εκτελέσει μια αναζήτηση brute-force. **** Υποθέτοντας μια ταχύτητα 300 req/s ο χρόνος που απαιτείται για να εκμεταλλευτεί αυτό είναι ο εξής:
56800235584 / 10000 / 300 / 3600 ~= 5.25 ώρες (50% πιθανότητα σε 2.63h)
(με 100000 αρχεία) 56800235584 / 100000 / 300 / 3600 ~= 0.525 ώρες (50% πιθανότητα σε 0.263h)
Ναι, είναι δυνατόν να δημιουργηθούν 100000 προσωρινά αρχεία σε μια EC2 μεσαίου μεγέθους instance:
Σημειώστε ότι για να ενεργοποιηθεί το timeout θα ήταν αρκετό να συμπεριληφθεί η ευάλωτη σελίδα LFI, ώστε να εισέλθει σε έναν αιώνιο βρόχο συμπερίληψης.
Φαίνεται ότι κατά προεπιλογή το Nginx υποστηρίζει 512 παράλληλες συνδέσεις ταυτόχρονα (και αυτός ο αριθμός μπορεί να βελτιωθεί).
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)