PHP Tricks
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Cookies übliche Position:
Dies gilt auch für phpMyAdmin-Cookies.
Cookies:
Standorte:
Umgehen von PHP-Vergleichen
Lose Vergleiche/Typumwandlung ( == )
Wenn ==
in PHP verwendet wird, gibt es unerwartete Fälle, in denen der Vergleich nicht wie erwartet funktioniert. Das liegt daran, dass "==" nur Werte vergleicht, die in denselben Typ umgewandelt wurden. Wenn Sie auch vergleichen möchten, dass der Typ der verglichenen Daten derselbe ist, müssen Sie ===
verwenden.
PHP-Vergleichstabellen: https://www.php.net/manual/en/types.comparisons.php
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F365789996-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FoC7kdpmNTJZIcPU2vQzG%252Fuploads%252Fgit-blob-53dd523e3097738b14730e72b491c182672a1fc0%252Fimage%2520%28567%29.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=f1de04ec&sv=1)
"string" == 0 -> True
Ein String, der nicht mit einer Zahl beginnt, ist gleich einer Zahl"0xAAAA" == "43690" -> True
Strings, die aus Zahlen im Dezimal- oder Hexadezimalformat bestehen, können mit anderen Zahlen/Strings verglichen werden, wobei das Ergebnis True ist, wenn die Zahlen gleich sind (Zahlen in einem String werden als Zahlen interpretiert)"0e3264578" == 0 --> True
Ein String, der mit "0e" beginnt und gefolgt von irgendetwas ist, wird gleich 0 sein"0X3264578" == 0X --> True
Ein String, der mit "0" beginnt und gefolgt von einem beliebigen Buchstaben (X kann jeder Buchstabe sein) und gefolgt von irgendetwas ist, wird gleich 0 sein"0e12334" == "0" --> True
Dies ist sehr interessant, da Sie in einigen Fällen die String-Eingabe von "0" und einige Inhalte, die gehasht und damit verglichen werden, steuern können. Daher, wenn Sie einen Wert bereitstellen können, der einen Hash erzeugt, der mit "0e" beginnt und ohne Buchstaben ist, könnten Sie den Vergleich umgehen. Sie können bereits gehashte Strings mit diesem Format hier finden: https://github.com/spaze/hashes"X" == 0 --> True
Jeder Buchstabe in einem String ist gleich int 0
Weitere Informationen unter https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09
in_array()
Typumwandlung betrifft auch die Funktion in_array()
standardmäßig (Sie müssen das dritte Argument auf true setzen, um einen strengen Vergleich durchzuführen):
strcmp()/strcasecmp()
Wenn diese Funktion für irgendeine Authentifizierungsüberprüfung (wie das Überprüfen des Passworts) verwendet wird und der Benutzer eine Seite des Vergleichs kontrolliert, kann er ein leeres Array anstelle eines Strings als Wert des Passworts senden (https://example.com/login.php/?username=admin&password[]=
) und diese Überprüfung umgehen:
Der gleiche Fehler tritt bei strcasecmp()
auf
Strikte Typumwandlung
Selbst wenn ===
verwendet wird, könnte es Fehler geben, die den Vergleich anfällig für Typumwandlung machen. Zum Beispiel, wenn der Vergleich die Daten in einen anderen Typ von Objekt umwandelt, bevor er vergleicht:
preg_match(/^.*/)
preg_match()
könnte verwendet werden, um Benutzereingaben zu validieren (es prüft, ob ein Wort/Regex aus einer Blacklist in der Benutzereingabe vorhanden ist, und wenn nicht, kann der Code seine Ausführung fortsetzen).
New line bypass
Wenn jedoch der Anfang des Regex mit preg_match()
nur die erste Zeile der Benutzereingabe überprüft, dann könntest du, wenn du die Eingabe in mehreren Zeilen senden kannst, in der Lage sein, diese Überprüfung zu umgehen. Beispiel:
Um diese Überprüfung zu umgehen, könnten Sie den Wert mit URL-kodierten Zeilenumbrüchen (%0A
) senden oder, wenn Sie JSON-Daten senden können, senden Sie es in mehreren Zeilen:
Finden Sie ein Beispiel hier: https://ramadistra.dev/fbctf-2019-rceservice
Längenfehler-Bypass
(Dieser Bypass wurde anscheinend auf PHP 5.2.5 ausprobiert und ich konnte ihn auf PHP 7.3.15 nicht zum Laufen bringen)
Wenn Sie preg_match()
eine gültige sehr große Eingabe senden können, wird es nicht in der Lage sein, sie zu verarbeiten und Sie werden in der Lage sein, die Überprüfung zu umgehen. Zum Beispiel, wenn es eine JSON auf die schwarze Liste setzt, könnten Sie senden:
From: https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0
ReDoS Bypass
Trick von: https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223 und https://mizu.re/post/pong
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F365789996-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FoC7kdpmNTJZIcPU2vQzG%252Fuploads%252Fgit-blob-746083bbabdbedd055c5dddac1d3ebcce0f1f726%252Fimage%2520%2826%29.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=5fe47dd&sv=1)
Kurz gesagt, das Problem tritt auf, weil die preg_*
Funktionen in PHP auf der PCRE-Bibliothek basieren. In PCRE werden bestimmte reguläre Ausdrücke durch viele rekursive Aufrufe abgeglichen, was viel Stack-Speicher benötigt. Es ist möglich, ein Limit für die Anzahl der erlaubten Rekursionen festzulegen, aber in PHP beträgt dieses Limit standardmäßig 100.000, was mehr ist, als im Stack passt.
Dieser Stackoverflow-Thread wurde ebenfalls in dem Beitrag verlinkt, in dem ausführlicher über dieses Problem gesprochen wird. Unsere Aufgabe war nun klar:
Sende eine Eingabe, die die Regex dazu bringt, 100_000+ Rekursionen durchzuführen, was zu SIGSEGV führt, wodurch die preg_match()
Funktion false
zurückgibt und die Anwendung denkt, dass unsere Eingabe nicht bösartig ist, und am Ende des Payloads eine Überraschung wie {system(<verybadcommand>)}
wirft, um SSTI --> RCE --> Flag :) zu erhalten.
Nun, in Bezug auf Regex machen wir tatsächlich keine 100k "Rekursionen", sondern zählen stattdessen "Backtracking-Schritte", die, wie die PHP-Dokumentation angibt, standardmäßig auf 1_000_000 (1M) in der Variablen pcre.backtrack_limit
eingestellt ist.
Um das zu erreichen, wird 'X'*500_001
zu 1 Million Backtracking-Schritten führen (500k vorwärts und 500k rückwärts):
Typ-Juggling zur PHP-Obfuskation
Execute After Redirect (EAR)
Wenn PHP zu einer anderen Seite umleitet, aber keine die
oder exit
Funktion nach dem Setzen des Headers Location
aufgerufen wird, führt PHP die Ausführung fort und fügt die Daten zum Body hinzu:
Path Traversal und File Inclusion Ausnutzung
Check:
File Inclusion/Path traversalWeitere Tricks
register_globals: In PHP < 4.1.1.1 oder wenn falsch konfiguriert, kann register_globals aktiv sein (oder ihr Verhalten wird nachgeahmt). Das bedeutet, dass in globalen Variablen wie $_GET, wenn sie einen Wert haben z.B. $_GET["param"]="1234", Sie darauf über $param zugreifen können. Daher können Sie durch das Senden von HTTP-Parametern Variablen überschreiben, die im Code verwendet werden.
Die PHPSESSION-Cookies der gleichen Domain werden am gleichen Ort gespeichert, daher, wenn innerhalb einer Domain verschiedene Cookies in verschiedenen Pfaden verwendet werden, können Sie einen Pfad so gestalten, dass er das Cookie des anderen Pfades zugreift, indem er den Wert des anderen Pfad-Cookies setzt. Auf diese Weise, wenn beide Pfade auf eine Variable mit dem gleichen Namen zugreifen, können Sie den Wert dieser Variablen in path1 auf path2 anwenden. Und dann wird path2 die Variablen von path1 als gültig betrachten (indem das Cookie den Namen erhält, der ihm in path2 entspricht).
Wenn Sie die Benutzernamen der Benutzer der Maschine haben. Überprüfen Sie die Adresse: /~<BENUTZERNAME>, um zu sehen, ob die PHP-Verzeichnisse aktiviert sind.
password_hash/password_verify
Diese Funktionen werden typischerweise in PHP verwendet, um Hashes aus Passwörtern zu generieren und um zu überprüfen, ob ein Passwort im Vergleich zu einem Hash korrekt ist.
Die unterstützten Algorithmen sind: PASSWORD_DEFAULT
und PASSWORD_BCRYPT
(beginnt mit $2y$
). Beachten Sie, dass PASSWORD_DEFAULT häufig dasselbe wie PASSWORD_BCRYPT ist. Und derzeit hat PASSWORD_BCRYPT eine Größenbeschränkung im Eingabewert von 72 Bytes. Daher, wenn Sie versuchen, etwas Größeres als 72 Bytes mit diesem Algorithmus zu hashen, werden nur die ersten 72B verwendet:
HTTP-Header-Bypass durch Ausnutzung von PHP-Fehlern
Fehler verursachen nach dem Setzen von Headern
Aus diesem Twitter-Thread kann man sehen, dass das Senden von mehr als 1000 GET-Parametern oder 1000 POST-Parametern oder 20 Dateien dazu führt, dass PHP die Header in der Antwort nicht setzen wird.
Dies ermöglicht es, beispielsweise CSP-Header zu umgehen, die in Codes wie:
Füllen eines Körpers, bevor Header gesetzt werden
Wenn eine PHP-Seite Fehler ausgibt und einige vom Benutzer bereitgestellte Eingaben zurückgibt, kann der Benutzer den PHP-Server dazu bringen, einige Inhalte auszugeben, die lang genug sind, sodass der Server beim Versuch, die Header in die Antwort hinzuzufügen, einen Fehler auslöst. Im folgenden Szenario ließ der Angreifer den Server einige große Fehler ausgeben, und wie Sie auf dem Bildschirm sehen können, als PHP versuchte, die Header-Informationen zu ändern, konnte es nicht (zum Beispiel wurde der CSP-Header nicht an den Benutzer gesendet):
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F365789996-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FoC7kdpmNTJZIcPU2vQzG%252Fuploads%252Fgit-blob-14119d0754739cfdb01a8cdd752ea4a282899451%252Fimage%2520%281085%29.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=19823643&sv=1)
SSRF in PHP-Funktionen
Überprüfen Sie die Seite:
PHP SSRFCodeausführung
system("ls"); `ls`; shell_exec("ls");
Überprüfen Sie dies für nützliche PHP-Funktionen
RCE über preg_replace()
Um den Code im "replace"-Argument auszuführen, ist mindestens ein Treffer erforderlich. Diese Option von preg_replace ist seit PHP 5.5.0 veraltet.
RCE über Eval()
RCE über Assert()
Diese Funktion innerhalb von php ermöglicht es Ihnen, Code, der in einer Zeichenkette geschrieben ist, auszuführen, um true oder false zurückzugeben (und je nach dem die Ausführung zu ändern). Normalerweise wird die Benutzervariable in die Mitte einer Zeichenkette eingefügt. Zum Beispiel:
assert("strpos($_GET['page']),'..') === false")
--> In diesem Fall könnten Sie tun, um RCE zu erhalten:
Du musst die Code-Syntax brechen, dein Payload hinzufügen und es dann wieder reparieren. Du kannst logische Operationen wie "and" oder "%26%26" oder "|" verwenden. Beachte, dass "or", "||" nicht funktioniert, da unser Payload nicht ausgeführt wird, wenn die erste Bedingung wahr ist. Ebenso funktioniert ";" nicht, da unser Payload nicht ausgeführt wird.
Andere Option ist, den Befehl zur Ausführung an die Zeichenkette hinzuzufügen: '.highlight_file('.passwd').'
Andere Option (wenn du den internen Code hast) ist, eine Variable zu ändern, um die Ausführung zu verändern: $file = "hola"
RCE über usort()
Diese Funktion wird verwendet, um ein Array von Elementen mit einer bestimmten Funktion zu sortieren. Um diese Funktion auszunutzen:
You can also use // um den Rest des Codes zu kommentieren.
Um die Anzahl der Klammern zu entdecken, die Sie schließen müssen:
?order=id;}//
: wir erhalten eine Fehlermeldung (Parse error: syntax error, unexpected ';'
). Wahrscheinlich fehlen uns eine oder mehrere Klammern.?order=id);}//
: wir erhalten eine Warnung. Das scheint richtig zu sein.?order=id));}//
: wir erhalten eine Fehlermeldung (Parse error: syntax error, unexpected ')' i
). Wahrscheinlich haben wir zu viele schließende Klammern.
RCE über .httaccess
Wenn Sie eine .htaccess hochladen können, dann können Sie mehrere Dinge konfigurieren und sogar Code ausführen (indem Sie konfigurieren, dass Dateien mit der Erweiterung .htaccess ausgeführt werden können).
Verschiedene .htaccess-Shells finden Sie hier
RCE über Env-Variablen
Wenn Sie eine Schwachstelle finden, die es Ihnen ermöglicht, Umgebungsvariablen in PHP zu ändern (und eine andere, um Dateien hochzuladen, obwohl dies mit mehr Forschung möglicherweise umgangen werden kann), könnten Sie dieses Verhalten ausnutzen, um RCE zu erhalten.
LD_PRELOAD
: Diese Umgebungsvariable ermöglicht es Ihnen, beliebige Bibliotheken beim Ausführen anderer Binärdateien zu laden (obwohl es in diesem Fall möglicherweise nicht funktioniert).PHPRC
: Weist PHP an, wo es seine Konfigurationsdatei finden soll, die normalerweisephp.ini
heißt. Wenn Sie Ihre eigene Konfigurationsdatei hochladen können, verwenden SiePHPRC
, um PHP darauf zu verweisen. Fügen Sie einenauto_prepend_file
-Eintrag hinzu, der eine zweite hochgeladene Datei angibt. Diese zweite Datei enthält normalen PHP-Code, der dann von der PHP-Laufzeitumgebung vor jedem anderen Code ausgeführt wird.
Laden Sie eine PHP-Datei mit unserem Shellcode hoch
Laden Sie eine zweite Datei hoch, die eine
auto_prepend_file
-Direktive enthält, die den PHP-Präprozessor anweist, die Datei aus Schritt 1 auszuführenSetzen Sie die
PHPRC
-Variable auf die Datei, die wir in Schritt 2 hochgeladen haben.
Erhalten Sie weitere Informationen, wie Sie diese Kette aus dem ursprünglichen Bericht ausführen können.
PHPRC - eine weitere Option
Wenn Sie keine Dateien hochladen können, könnten Sie in FreeBSD die "Datei"
/dev/fd/0
verwenden, die denstdin
enthält, der den Körper der an denstdin
gesendeten Anfrage darstellt:curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'
Oder um RCE zu erhalten, aktivieren Sie
allow_url_include
und fügen Sie eine Datei mit base64 PHP-Code hinzu: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=="'
Technik aus diesem Bericht.
XAMPP CGI RCE - CVE-2024-4577
Der Webserver analysiert HTTP-Anfragen und leitet sie an ein PHP-Skript weiter, das eine Anfrage wie http://host/cgi.php?foo=bar
als php.exe cgi.php foo=bar
ausführt, was eine Parameterinjektion ermöglicht. Dies würde es ermöglichen, die folgenden Parameter zu injizieren, um den PHP-Code aus dem Körper zu laden:
Darüber hinaus ist es möglich, den "-" Parameter mit dem 0xAD Zeichen zu injizieren, aufgrund der späteren Normalisierung von PHP. Überprüfen Sie das Exploit-Beispiel aus diesem Beitrag:
PHP Sanitization bypass & Brain Fuck
In diesem Beitrag sind großartige Ideen zu finden, um einen Brain Fuck PHP-Code mit sehr wenigen erlaubten Zeichen zu generieren. Darüber hinaus wird auch eine interessante Möglichkeit vorgeschlagen, Funktionen auszuführen, die es ermöglichten, mehrere Überprüfungen zu umgehen:
PHP Statische Analyse
Überprüfen Sie, ob Sie Code in Aufrufen dieser Funktionen einfügen können (von hier):
Wenn Sie eine PHP-Anwendung debuggen, können Sie die Fehlerausgabe global aktivieren, indem Sie display_errors = On
in /etc/php5/apache2/php.ini
hinzufügen und Apache neu starten: sudo systemctl restart apache2
Deobfuskation von PHP-Code
Sie können das Web www.unphp.net verwenden, um PHP-Code zu deobfuskieren.
PHP Wrapper & Protokolle
PHP-Wrapper und Protokolle könnten es Ihnen ermöglichen, Schreib- und Lese-Schutzmaßnahmen in einem System zu umgehen und es zu kompromittieren. Für weitere Informationen überprüfen Sie diese Seite.
Xdebug nicht authentifizierte RCE
Wenn Sie sehen, dass Xdebug in einer phpconfig()
-Ausgabe aktiviert ist, sollten Sie versuchen, RCE über https://github.com/nqxcode/xdebug-exploit zu erhalten.
Variable Variablen
RCE durch Missbrauch von neuen $_GET["a"]($_GET["b")
Wenn Sie auf einer Seite ein neues Objekt einer beliebigen Klasse erstellen können, könnten Sie in der Lage sein, RCE zu erlangen. Überprüfen Sie die folgende Seite, um zu lernen, wie:
PHP - RCE abusing object creation: new $_GET["a"]($_GET["b"])PHP ohne Buchstaben ausführen
https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/
Verwendung von Oktal
XOR
XOR einfacher Shellcode
Laut diesem Bericht ist es möglich, auf diese Weise einen einfachen Shellcode zu generieren:
Also, wenn Sie willkürlichen PHP-Code ohne Zahlen und Buchstaben ausführen können, können Sie eine Anfrage wie die folgende senden, um diese Payload auszunutzen und willkürlichen PHP-Code auszuführen:
Für eine detailliertere Erklärung siehe https://ctf-wiki.org/web/php/php/#preg_match
XOR Shellcode (innerhalb von eval)
Perl ähnlich
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Last updated