LFI2RCE via Eternal waiting

Support HackTricks

Basic Information

Από προεπιλογή, όταν ένα αρχείο ανεβαίνει σε PHP (ακόμα και αν δεν το περιμένει), θα δημιουργήσει ένα προσωρινό αρχείο στο /tmp με ένα όνομα όπως php[a-zA-Z0-9]{6}, αν και έχω δει μερικές εικόνες docker όπου τα παραγόμενα αρχεία δεν περιέχουν ψηφία.

Σε μια τοπική συμπερίληψη αρχείου, αν καταφέρετε να συμπεριλάβετε αυτό το ανεβασμένο αρχείο, θα αποκτήσετε RCE.

Σημειώστε ότι από προεπιλογή η PHP επιτρέπει μόνο την ανάρτηση 20 αρχείων σε ένα μόνο αίτημα (ρυθμισμένο στο /etc/php/<version>/apache2/php.ini):

; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20

Επίσης, ο αριθμός των πιθανών ονομάτων αρχείων είναι 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 δυστυχώς...).

Δοκιμάστε το απλά καλώντας:

php -a # open php cli
include("/sys/kernel/security/apparmor/revision");

Apache2

Κατά προεπιλογή, το 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-FMP

Αν αντί να χρησιμοποιήσουμε το κανονικό 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

Φαίνεται ότι κατά προεπιλογή το Nginx υποστηρίζει 512 παράλληλες συνδέσεις ταυτόχρονα (και αυτός ο αριθμός μπορεί να βελτιωθεί).

Support HackTricks

Last updated