PHP Tricks
Συνηθισμένη τοποθεσία Cookies:
Αυτό ισχύει επίσης για τα cookies του phpMyAdmin.
Τοποθεσίες:
Παράκαμψη συγκρίσεων στην PHP
Χαλαρές συγκρίσεις/Τύπος Juggling ( == )
Εάν χρησιμοποιείται το ==
στην PHP, τότε υπάρχουν απροσδόκητες περιπτώσεις όπου η σύγκριση δεν συμπεριφέρεται όπως αναμένεται. Αυτό συμβαίνει επειδή το "==" συγκρίνει μόνο τιμές που έχουν μετατραπεί στον ίδιο τύπο, εάν θέλετε επίσης να συγκρίνετε τον τύπο των δεδομένων που συγκρίνονται, πρέπει να χρησιμοποιήσετε το ===
.
Πίνακες σύγκρισης στην PHP: https://www.php.net/manual/en/types.comparisons.php
"string" == 0 -> True
Ένα string που δεν ξεκινά με έναν αριθμό είναι ίσο με έναν αριθμό"0xAAAA" == "43690" -> True
Strings που αποτελούνται από αριθμούς σε δεκαδική ή εξαδική μορφή μπορούν να συγκριθούν με άλλους αριθμούς/strings με αποτέλεσμα True εάν οι αριθμοί ήταν ίδιοι (οι αριθμοί σε ένα string ερμηνεύονται ως αριθμοί)"0e3264578" == 0 --> True
Ένα string που ξεκινά με "0e" και ακολουθείται από οτιδήποτε θα είναι ίσο με 0"0X3264578" == 0X --> True
Ένα string που ξεκινά με "0" και ακολουθείται από οποιοδήποτε γράμμα (το X μπορεί να είναι οποιοδήποτε γράμμα) και ακολουθείται από οτιδήποτε θα είναι ίσο με 0"0e12334" == "0" --> True
Αυτό είναι πολύ ενδιαφέρον επειδή σε ορισμένες περιπτώσεις μπορείτε να ελέγξετε τη συμβολοσειρά εισόδου του "0" και κάποιο περιεχόμενο που υπολογίζεται και συγκρίνεται με αυτό. Επομένως, εάν μπορείτε να παρέχετε μια τιμή που θα δημιουργήσει ένα hash που ξεκινά με "0e" και χωρίς κανένα γράμμα, μπορείτε να παρακάμψετε τη σύγκριση. Μπορείτε να βρείτε ήδη κατακερματισμένες συμβολοσειρές με αυτήν τη μορφή εδώ: https://github.com/spaze/hashes"X" == 0 --> True
Οποιοδήποτε γράμμα σε ένα string είναι ίσο με τον ακέραιο 0
Περισσότερες πληροφορίες στο https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09
in_array()
Ο Τύπος Juggling επηρεάζει επίσης τη λειτουργία της συνάρτησης in_array()
από προεπιλογή (χρειάζεται να ορίσετε σε true το τρίτο όρισμα για να γίνει μια αυστηρή σύγκριση):
strcmp()/strcasecmp()
Εάν αυτή η συνάρτηση χρησιμοποιείται για οποιονδήποτε έλεγχο ταυτότητας (όπως έλεγχος κωδικού πρόσβασης) και ο χρήστης ελέγχει ένα μέρος της σύγκρισης, μπορεί να στείλει ένα κενό πίνακα αντί για συμβολοσειρά ως τιμή του κωδικού πρόσβασης (https://example.com/login.php/?username=admin&password[]=
) και να παρακάμψει αυτόν τον έλεγχο:
Η ίδια σφάλμα συμβαίνει με το strcasecmp()
Αυστηρή τύπου μαγεία
Ακόμα κι αν χρησιμοποιείται το ===
ενδέχεται να υπάρχουν σφάλματα που καθιστούν τη σύγκριση ευάλωτη στην τύπου μαγεία. Για παράδειγμα, αν η σύγκριση μετατρέπει τα δεδομένα σε διαφορετικό τύπο αντικειμένου πριν τη σύγκριση:
preg_match(/^.*/)
preg_match()
μπορεί να χρησιμοποιηθεί για να επικυρώσει την είσοδο του χρήστη (ελέγχει αν κάποια λέξη/regex από μια μαύρη λίστα είναι παρούσα στην είσοδο του χρήστη και αν δεν είναι, ο κώδικας μπορεί να συνεχίσει την εκτέλεσή του).
Παράκαμψη νέας γραμμής
Ωστόσο, όταν περιορίζετε την αρχή του regexppreg_match()
ελέγχει μόνο την πρώτη γραμμή της εισόδου του χρήστη, έπειτα αν με κάποιο τρόπο μπορείτε να στείλετε την είσοδο σε πολλαπλές γραμμές, θα μπορούσατε να παρακάμψετε αυτόν τον έλεγχο. Παράδειγμα:
Για να παρακάμψετε αυτόν τον έλεγχο μπορείτε να στείλετε την τιμή με νέες γραμμές urlencoded (%0A
) ή αν μπορείτε να στείλετε δεδομένα JSON, στείλτε τα σε πολλές γραμμές:
Βρείτε ένα παράδειγμα εδώ: https://ramadistra.dev/fbctf-2019-rceservice
Παράκαμψη σφάλματος μήκους
(Αυτή η παράκαμψη δοκιμάστηκε προφανώς σε PHP 5.2.5 και δεν μπόρεσα να την κάνω να λειτουργήσει σε PHP 7.3.15)
Αν μπορείτε να στείλετε στο preg_match()
ένα πολύ μεγάλο έγκυρο είσοδο, δεν θα μπορέσει να το επεξεργαστεί και θα μπορέσετε να παρακάμψετε τον έλεγχο. Για παράδειγμα, αν απαγορεύει ένα JSON μπορείτε να στείλετε:
Παράκαμψη ReDoS
Κόλπο από: https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223 και https://mizu.re/post/pong
Συνοπτικά, το πρόβλημα συμβαίνει επειδή οι συναρτήσεις preg_*
στο PHP βασίζονται στη βιβλιοθήκη PCRE. Στο PCRE, ορισμένες κανονικές εκφράσεις ταιριάζονται χρησιμοποιώντας πολλές αναδρομικές κλήσεις, οι οποίες χρησιμοποιούν πολύ χώρο στο stack. Είναι δυνατόν να οριστεί ένα όριο στον αριθμό των αναδρομών που επιτρέπονται, αλλά στο PHP αυτό το όριο ορίζεται από προεπιλογή σε 100.000 που είναι περισσότερο από όσο χωράει στο stack.
Αυτό το νήμα στο Stackoverflow συνδέθηκε επίσης στην ανάρτηση όπου μιλάει πιο αναλυτικά για αυτό το θέμα. Η εργασία μας ήταν τώρα σαφής:
Στείλτε μια είσοδο που θα κάνει την κανονική έκφραση να κάνει 100.000+ αναδρομές, προκαλώντας SIGSEGV, κάνοντας τη συνάρτηση preg_match()
να επιστρέψει false
και έτσι να πείσει την εφαρμογή ότι η είσοδός μας δεν είναι κακόβουλη, ρίχνοντας την έκπληξη στο τέλος του φορτίου κάτι σαν {system(<verybadcommand>)}
για να πάρουμε SSTI --> RCE --> σημαία :).
Καλά, σε όρους κανονικών εκφράσεων, δεν κάνουμε πραγματικά 100.000 "αναδρομές", αλλά αντίθετα μετράμε "βήματα επιστροφής", τα οποία όπως αναφέρει το έγγραφο του PHP ορίζονται από προεπιλογή σε 1.000.000 (1M) στη μεταβλητή pcre.backtrack_limit
.
Για να φτάσουμε εκεί, 'X'*500_001
θα οδηγήσει σε 1 εκατομμύριο βήματα επιστροφής (500k προς τα εμπρός και 500k προς τα πίσω):
Τύπος Κρούσης για Απόκρυψη στο PHP
Εκτέλεση Μετά την Ανακατεύθυνση (EAR)
Εάν το PHP ανακατευθύνει σε μια άλλη σελίδα αλλά δεν καλείται η συνάρτηση die
ή exit
μετά τον ορισμό του κεφαλίδας Location
, τότε το PHP συνεχίζει την εκτέλεση και προσθέτει τα δεδομένα στο σώμα της απόκρισης:
Εκμετάλλευση Διάβασης Διαδρομής και Συμπερίληψης Αρχείων
Ελέγξτε:
pageFile Inclusion/Path traversalΠερισσότερα κόλπα
register_globals: Στο PHP < 4.1.1.1 ή αν δεν έχει ρυθμιστεί σωστά, το register_globals μπορεί να είναι ενεργό (ή η συμπεριφορά του να μιμείται). Αυτό σημαίνει ότι σε γενικές μεταβλητές όπως το $_GET αν έχουν μια τιμή π.χ. $_GET["param"]="1234", μπορείτε να την προσπελάσετε μέσω του $param. Έτσι, με την αποστολή παραμέτρων HTTP μπορείτε να αντικαταστήσετε μεταβλητές που χρησιμοποιούνται στον κώδικα.
Τα PHPSESSION cookies του ίδιου τομέα αποθηκεύονται στον ίδιο τόπο, επομένως αν εντός ενός τομέα χρησιμοποιούνται διαφορετικά cookies σε διαφορετικά μονοπάτια μπορείτε να κάνετε ένα μονοπάτι να έχει πρόσβαση στο cookie του μονοπατιού ορίζοντας την τιμή του cookie του άλλου μονοπατιού. Με αυτόν τον τρόπο, αν και τα δύο μονοπάτια έχουν πρόσβαση σε μια μεταβλητή με το ίδιο όνομα μπορείτε να κάνετε τη τιμή αυτής της μεταβλητής στο μονοπάτι1 να ισχύει για το μονοπάτι2. Και στη συνέχεια το μονοπάτι2 θα θεωρήσει ως έγκυρες τις μεταβλητές του μονοπατιού1 (δίνοντας στο cookie το όνομα που του αντιστοιχεί στο μονοπάτι2).
Όταν έχετε τα ονόματα χρηστών των χρηστών της μηχανής. Ελέγξτε τη διεύθυνση: /~<USERNAME> για να δείτε αν οι κατάλογοι php είναι ενεργοποιημένοι.
password_hash/password_verify
Αυτές οι λειτουργίες χρησιμοποιούνται τυπικά στο PHP για το δημιουργία hashes από κωδικούς πρόσβασης και για να ελέγξουν αν ένας κωδικός πρόσβασης είναι σωστός σε σύγκριση με ένα hash.
Οι υποστηριζόμενοι αλγόριθμοι είναι: PASSWORD_DEFAULT
και PASSWORD_BCRYPT
(ξεκινά με $2y$
). Σημειώστε ότι το PASSWORD_DEFAULT είναι συχνά το ίδιο με το PASSWORD_BCRYPT. Και επί του παρόντος, το PASSWORD_BCRYPT έχει μια περιορισμένη μέγεθος εισόδου στα 72bytes. Επομένως, όταν προσπαθείτε να κάνετε hash κάτι μεγαλύτερο από 72bytes με αυτόν τον αλγόριθμο, θα χρησιμοποιηθούν μόνο τα πρώτα 72B:
Παράκαμψη κεφαλίδων HTTP εκμεταλλευόμενος σφάλματα PHP
Εάν μια σελίδα PHP εκτυπώνει σφάλματα και αντανακλά κάποια είσοδο που παρέχεται από τον χρήστη, ο χρήστης μπορεί να κάνει τον διακομιστή PHP να εκτυπώσει κάποιο περιεχόμενο αρκετά μεγάλο ώστε όταν προσπαθήσει να προσθέσει τις κεφαλίδες στην απόκριση, ο διακομιστής θα εκτοξεύσει ένα σφάλμα. Στο ακόλουθο σενάριο ο επιτιθέμενος έκανε τον διακομιστή να εκτοξεύσει μερικά μεγάλα σφάλματα, και όπως μπορείτε να δείτε στην οθόνη, όταν το PHP προσπάθησε να τροποποιήσει τις πληροφορίες της κεφαλίδας, δεν μπόρεσε (έτσι για παράδειγμα η κεφαλίδα CSP δεν απεστάλη στον χρήστη):
Εκτέλεση κώδικα
system("ls"); `ls`; shell_exec("ls");
Ελέγξτε αυτό για περισσότερες χρήσιμες συναρτήσεις PHP
RCE μέσω preg_replace()
Για να εκτελεστεί ο κώδικας στο όρισμα "replace" απαιτείται τουλάχιστον ένα ταίριασμα. Αυτή η επιλογή της preg_replace έχει αποσυρθεί από την PHP 5.5.0.
RCE μέσω Eval()
RCE μέσω Assert()
Αυτή η λειτουργία στην php σάς επιτρέπει να εκτελέσετε κώδικα που έχει γραφτεί σε ένα string προκειμένου να επιστρέψει true ή false (και ανάλογα με αυτό να αλλάξει την εκτέλεση). Συνήθως η μεταβλητή χρήστη θα εισαχθεί στη μέση ενός string. Για παράδειγμα:
assert("strpos($_GET['page']),'..') === false")
--> Σε αυτήν την περίπτωση για να πάρετε RCE μπορείτε να κάνετε:
Θα πρέπει να διακόψετε τη σύνταξη του κώδικα, προσθέσετε το φορτίο σας, και μετά να το διορθώσετε ξανά. Μπορείτε να χρησιμοποιήσετε λογικές λειτουργίες όπως "and" ή "%26%26" ή "|". Σημειώστε ότι το "or", "||" δεν λειτουργεί επειδή αν η πρώτη συνθήκη είναι αληθής το φορτίο μας δεν θα εκτελεστεί. Με τον ίδιο τρόπο το ";" δεν λειτουργεί επειδή το φορτίο μας δεν θα εκτελεστεί.
Άλλη επιλογή είναι να προσθέσετε στο string την εκτέλεση της εντολής: '.highlight_file('.passwd').'
Άλλη επιλογή (αν έχετε τον εσωτερικό κώδικα) είναι να τροποποιήσετε κάποια μεταβλητή για να αλλοιώσετε την εκτέλεση: $file = "hola"
RCE μέσω usort()
Αυτή η συνάρτηση χρησιμοποιείται για την ταξινόμηση ενός πίνακα στοιχείων χρησιμοποιώντας μια συγκεκριμένη συνάρτηση. Για να καταχραστείτε αυτήν τη συνάρτηση:
Μπορείτε επίσης να χρησιμοποιήσετε // για να σχολιάσετε το υπόλοιπο του κώδικα.
Για να ανακαλύψετε τον αριθμό των παρενθέσεων που χρειάζεστε να κλείσετε:
?order=id;}//
: λαμβάνουμε ένα μήνυμα σφάλματος (Parse error: syntax error, unexpected ';'
). Πιθανότατα λείπει μία ή περισσότερες αγκύλες.?order=id);}//
: λαμβάνουμε ένα προειδοποιητικό μήνυμα. Φαίνεται ότι είναι σωστό.?order=id));}//
: λαμβάνουμε ένα μήνυμα σφάλματος (Parse error: syntax error, unexpected ')' i
). Πιθανότατα έχουμε πολλές κλειστές αγκύλες.
RCE μέσω .httaccess
Αν μπορείτε να ανεβάσετε ένα .htaccess, τότε μπορείτε να διαμορφώσετε διάφορα πράγματα και ακόμη να εκτελέσετε κώδικα (διαμορφώνοντας ότι τα αρχεία με κατάληξη .htaccess μπορούν να εκτελεστούν).
Διαφορετικά .htaccess shells μπορούν να βρεθούν εδώ
RCE μέσω Μεταβλητών Περιβάλλοντος
Αν βρείτε μια ευπάθεια που σας επιτρέπει να τροποποιήσετε μεταβλητές περιβάλλοντος στο PHP (και μια άλλη για να ανεβάσετε αρχεία, αν και με περισσότερη έρευνα ίσως αυτό να μπορεί να ανακληθεί), θα μπορούσατε να εκμεταλλευτείτε αυτή τη συμπεριφορά για να πάρετε RCE.
LD_PRELOAD
: Αυτή η μεταβλητή περιβάλλοντος σάς επιτρέπει να φορτώσετε τυχαίες βιβλιοθήκες κατά την εκτέλεση άλλων δυαδικών (αν και σε αυτήν την περίπτωση ενδέχεται να μη λειτουργεί).PHPRC
: Οδηγεί το PHP σχετικά με το πού να εντοπίσει το αρχείο διαμόρφωσής του, συνήθως ονομάζεταιphp.ini
. Αν μπορείτε να ανεβάσετε το δικό σας αρχείο διαμόρφωσης, τότε χρησιμοποιήστε τοPHPRC
για να το κατευθύνετε στο PHP. Προσθέστε μια καταχώρισηauto_prepend_file
που καθορίζει ένα δεύτερο ανεβασμένο αρχείο. Αυτό το δεύτερο αρχείο περιέχει κανονικό κώδικα PHP, ο οποίος στη συνέχεια εκτελείται από το χρόνο εκτέλεσης του PHP πριν από οποιονδήποτε άλλο κώδικα.
Ανεβάστε ένα αρχείο PHP που περιέχει τον κώδικα του shell μας
Ανεβάστε ένα δεύτερο αρχείο που περιέχει μια οδηγία
auto_prepend_file
που εντολοδοτεί τον προεπεξεργαστή PHP να εκτελέσει το αρχείο που ανεβάσαμε στο βήμα 1Ορίστε τη μεταβλητή
PHPRC
στο αρχείο που ανεβάσαμε στο βήμα 2.
Λάβετε περισσότερες πληροφορίες για το πώς να εκτελέσετε αυτή τη σειρά από την αρχική αναφορά.
PHPRC - μια άλλη επιλογή
Αν δεν μπορείτε να ανεβάσετε αρχεία, μπορείτε να χρησιμοποιήσετε στο FreeBSD το "αρχείο"
/dev/fd/0
που περιέχει τοstdin
, είναι το σώμα του αιτήματος που στάλθηκε στοstdin
:curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'
Ή για να λάβετε RCE, ενεργοποιήστε το
allow_url_include
και προσθέστε ένα αρχείο με κώδικα PHP base64:curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary $'allow_url_include=1\nauto_prepend_file="data://text/plain;base64,PD8KICAgcGhwaW5mbygpOwo/Pg=="'
Τεχνική από αυτήν την αναφορά.
Στατική ανάλυση PHP
Ελέγξτε αν μπορείτε να εισάγετε κώδικα σε κλήσεις αυτών των συναρτήσεων (από εδώ):
Αν αποσφαλματίζετε μια εφαρμογή PHP, μπορείτε να ενεργοποιήσετε γενικά την εκτύπωση σφαλμάτων στο /etc/php5/apache2/php.ini
προσθέτοντας display_errors = On
και επανεκκινήστε τον Apache: sudo systemctl restart apache2
Αποκρυπτογράφηση κώδικα PHP
Μπορείτε να χρησιμοποιήσετε τον ιστότοπο www.unphp.net για να αποκρυπτογραφήσετε κώδικα php.
Πρωτόκολλα & Πρωτόκολλα PHP
Τα πρωτόκολλα και τα πρωτόκολλα PHP μπορεί να σας επιτρέψουν να παρακάμψετε τις προστασίες εγγραφής και ανάγνωσης σε ένα σύστημα και να τον απειλήσετε. Για περισσότερες πληροφορίες ελέγξτε αυτήν τη σελίδα.
Xdebug μη εξουσιοδοτημένο RCE
Αν δείτε ότι το Xdebug είναι ενεργοποιημένο σε έξοδο phpconfig()
, πρέπει να προσπαθήσετε να λάβετε RCE μέσω https://github.com/nqxcode/xdebug-exploit
Μεταβλητές μεταβλητές
RCE κατάχρηση νέου $_GET["a"]($_GET["b"])
Αν σε μια σελίδα μπορείς να δημιουργήσεις ένα νέο αντικείμενο μιας τυχαίας κλάσης, ενδέχεται να μπορείς να αποκτήσεις RCE, ελέγξτε την ακόλουθη σελίδα για να μάθετε πώς:
pagePHP - RCE abusing object creation: new $_GET["a"]($_GET["b"])Εκτέλεση PHP χωρίς γράμματα
https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/
Χρησιμοποιώντας οκταδικά
XOR
Το XOR (Αποκλειστικό OR) είναι ένας τελεστής που χρησιμοποιείται συχνά σε τεχνικές κρυπτογραφίας και hacking.
XOR εύκολος κώδικας κέλυφους
Σύμφωνα με αυτή την ανάλυση, είναι δυνατόν να δημιουργηθεί ένας εύκολος κώδικας κέλυφους με αυτόν τον τρόπο:
Έτσι, αν μπορείτε να εκτελέσετε τυχαίο PHP χωρίς αριθμούς και γράμματα μπορείτε να στείλετε ένα αίτημα όπως το παρακάτω καταχρώμενοντας αυτό το φορτίο για να εκτελέσετε τυχαίο PHP:
Για μια πιο λεπτομερή εξήγηση ελέγξτε https://ctf-wiki.org/web/php/php/#preg_match
XOR Shellcode (μέσα σε eval)
Παρόμοιο με την Perl
Last updated