目录
DVWA(Damn Vulnerable Web Application)中的 弱会话Weak Session IDs关卡是用于练习和演示 弱会话ID的不同场景,不同安全等级存在不同的脆弱点和绕过方法,本小节对高等级别的关卡进行渗透实战。
一、Session ID
Session ID(会话 ID)是 Web 应用程序中用于标识用户会话的唯一标识符,是用户访问网站时的 “电子身份证”。会话id的核心作用和身份证类似,id用于区分不同的用户,核心作用如下所示。
- 区分用户会话:当用户访问网站时,服务器会为其创建一个会话(Session),并生成唯一的 Session ID,通过 Cookie 存储在用户浏览器或 URL 中。后续请求携带该 ID,服务器即可识别用户身份,保持会话状态(如登录状态、购物车数据等)。
- 跨请求状态保持:由于默认情况下HTTP应用层协议是无状态的,Session ID 让服务器能 “记住” 用户的操作,例如用户登录后,服务器通过 Session ID 关联其权限和数据。
Session ID(会话 ID)通常使用Cookie 存储:默认通过名为PHPSESSID(PHP)等的 Cookie 传输,浏览器自动携带。以DVWA的盲注关卡Impossible级别为例,使用bp抓包,如下报文的sesssion id使用PHPSESSID存储,值为tssqfshe2838kcg5nbkf4464u3,具体如下所示。
二、代码审计(High级别)
1、配置security为High级别
进入到弱会话id关卡,完整URL地址具体如下所示。
http://192.168.59.1/dvwa/vulnerabilities/weak_id/
2、源码分析
(1)index.php
进入DVWA靶场源目录,找到index.php源码。
这段
PHP
代码是
Damn Vulnerable Web Application (DVWA)
中
“弱会话
ID
”
演示页面的核心逻辑,通过对比不同安全级别的实现方式,帮助开发者理解弱会话
ID
的风险和安全的会话管理实践。主要功能如下所示。
- 安全级别控制:根据用户 Cookie 中存储的安全级别(低、中、高、安全),动态加载不同的会话 ID 生成算法实现文件,展示不同防护级别的会话管理场景。
- 用户交互界面:
- 提供一个 “Generate” 按钮,每次点击时会触发会话 ID 的生成。
- 页面说明文字提示用户每次点击按钮会设置一个名为 dvwaSession 的新 Cookie。
- 会话 ID 生成演示:根据低、中、高、安全共4个级别演示会话id的生成。
- 辅助功能:
- 提供帮助文档和源代码查看功能。
- 根据不同安全级别显示相应的会话 ID 生成结果
经过注释后的详细代码如下所示。
<?php
// 定义网站根目录路径常量,用于后续文件引用
define( 'DVWA_WEB_PAGE_TO_ROOT', '../../' );
// 引入DVWA页面基础功能库
require_once DVWA_WEB_PAGE_TO_ROOT . 'dvwa/includes/dvwaPage.inc.php';
// 启动页面,验证用户是否已认证并初始化PHPIDS(入侵检测系统)
dvwaPageStartup( array( 'authenticated', 'phpids' ) );
// 创建新页面实例
$page = dvwaPageNewGrab();
// 设置页面标题,包含名称
$page[ 'title' ] = 'Vulnerability: Weak Session IDs' . $page[ 'title_separator' ].$page[ 'title' ];
// 设置页面ID,用于导航和标识
$page[ 'page_id' ] = 'weak_id';
// 添加帮助按钮和源代码按钮
$page[ 'help_button' ] = 'weak_id';
$page[ 'source_button' ] = 'weak_id';
// 连接数据库
dvwaDatabaseConnect();
// 设置HTTP请求方法(默认为GET)
$method = 'GET';
// 配置不同级别对应的源文件
$vulnerabilityFile = '';
// 根据安全级别Cookie值选择不同的实现文件
switch( $_COOKIE[ 'security' ] ) {
case 'low':
// 低安全级别:使用易预测的会话ID生成算法
$vulnerabilityFile = 'low.php';
break;
case 'medium':
// 中安全级别:部分增强的会话ID生成算法
$vulnerabilityFile = 'medium.php';
break;
case 'high':
// 高安全级别:进一步增强的会话ID生成算法
$vulnerabilityFile = 'high.php';
break;
default:
// 安全模式:使用安全的会话ID生成算法
$vulnerabilityFile = 'impossible.php';
$method = 'POST';
break;
}
// 引入选定的实现文件
require_once DVWA_WEB_PAGE_TO_ROOT . "vulnerabilities/weak_id/source/{$vulnerabilityFile}";
// 构建页面主体内容,包含说明文字和生成会话ID的按钮
$page[ 'body' ] .= <<<EOF
<div class="body_padded">
<h1>Vulnerability: Weak Session IDs</h1>
<p>
This page will set a new cookie called dvwaSession each time the button is clicked.<br />
</p>
<form method="post">
<input type="submit" value="Generate" />
</form>
$html
EOF;
/*
Maybe display this, don't think it is needed though
if (isset ($cookie_value)) {
$page[ 'body' ] .= <<<EOF
The new cookie value is $cookie_value
EOF;
}
*/
// 输出最终HTML页面
dvwaHtmlEcho( $page );
?>
(2)high.php
进入DVWA靶场源目录,找到high.php源码。
打开源码high.php,分析可知这段代码实现了一个会话session id生成功能,如下所示。
代码的功能如下所示。
- 会话计数:通过会话变量last_session_id_high记录 POST 请求次数,每次请求递增。
- 会话 ID 生成:将计数器值进行 MD5 哈希处理,生成会话 ID。
- Cookie 设置:将会话 ID 存储在客户端 Cookie 中,有效期 1 小时,作用域限定在/vulnerabilities/weak_id/路径。
详细注释后的代码如下所示。
<?php
// 初始化HTML输出变量(可能用于后续页面渲染)
$html = "";
// 检查请求方法是否为POST
if ($_SERVER['REQUEST_METHOD'] == "POST") {
// 检查会话计数器是否存在,不存在则初始化为0
if (!isset ($_SESSION['last_session_id_high'])) {
$_SESSION['last_session_id_high'] = 0;
}
// 会话计数器递增(每次POST请求+1)
$_SESSION['last_session_id_high']++;
// 使用MD5哈希算法处理会话计数器值,生成会话ID
// 注意:MD5已不安全,易被碰撞攻击
$cookie_value = md5($_SESSION['last_session_id_high']);
// 设置名为"dvwaSession"的Cookie,包含以下参数:
// 1. Cookie值:MD5哈希后的会话ID
// 2. 过期时间:当前时间+3600秒(1小时)
// 3. 路径:"/vulnerabilities/weak_id/"(限制Cookie仅在该路径下有效)
// 4. 域名:当前请求的主机名
// 5. 安全标志:false(不要求HTTPS传输)
// 6. HttpOnly标志:false(允许JavaScript访问,存在XSS风险)
setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], false, false);
}
?>
(3)对比low级别
对比low和high关卡,源码如下所示。
DVWA的high关卡与low关卡的安全级别对比后, 此代码增加了md5函数处理last_session_id,具体如下所示。
对比项 |
Low安全级别 |
High安全级别 |
会话 ID 生成方式 |
直接使用会话计数器的原始值(如 1,2,3...) |
使用 MD5 哈希处理会话计数器值 (如e10adc3949ba59abbe56e057f20f883e) |
可预测性 |
极高(攻击者可通过递增规律预测后续会话 ID) |
高(MD5 输出固定长度,但计数器递增规律仍可被逆向推导) |
唯一性 |
低(会话重置或服务器重启可能导致 ID 重复) |
低(仅改变表现形式,本质仍依赖计数器) |
抗枚举能力 |
无(纯数字 ID 易被暴破) |
中(哈希值增加了复杂度,但未引入随机性) |
安全风险 |
1. 会话固定攻击风险 |
1. MD5 已被破解(存在碰撞风险) |
Cookie 配置 |
默认配置(会话结束失效,作用域为当前路径) |
1. 有效期 1 小时 |
(4)set_cookie函数
set_cookie用于在HTTP响应中设置cookie,将数据存储在客户端浏览器中。
setcookie(
string $name,
string $value = "",
int|array $expires_or_options = 0,
string $path = "",
string $domain = "",
bool $secure = false,
bool $httponly = false
): bool
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
name | string | - | 必填,Cookie的名称 |
value | string | - | 必填,Cookie的值 |
expires | Date/int | - | 过期时间(GMT时间或秒数) |
max_age | int | - | 相对过期时间(秒),优先级高于 expires |
path | string | "/" | Cookie生效的路径,默认为根路径 |
domain | string | - | Cookie生效的域名(如 .example.com 对所有子域名有效) |
secure | boolean | false | 若为 true ,则仅通过HTTPS传输 |
httponly | boolean | false | 若为 true ,则禁止JavaScript通过 document.cookie 访问 |
(5)渗透思路
核心问题:具有弱会话 ID(Predictable Session ID)攻击可能性。
- 会话ID可预测性:因计数器是顺序递增且MD5输出固定长度,攻击者可通过枚举方式猜测后续会话 ID。
- 哈希算法不安全:MD5 已被破解,存在碰撞风险,不适合用于安全敏感场景。
- Cookie 安全属性缺失:未设置HttpOnly和Secure标志,可能导致 XSS 攻击和会话劫持。
- 会话固定攻击风险:未验证初始会话 ID 来源,攻击者可能通过预设已知 ID 进行攻击。
影响:攻击者可通过枚举会话 ID 值再进,伪造合法用户会话,获取未授权访问权限。
三、渗透实战
1、点击生成会话ID
bp开启拦截功能,进入靶场的脆弱的session id关卡,点击生成会话id,如下所示。
2、Burpsuite抓包分析
在burpsuite中找到该报文,红圈分别为request和response中的dvwaSession,如下图所示。
当前请求报文的dvwaSession=c20ad4d76fe97759aa27a0c99bff6710,这个是数字12的md5值。
当前响应报文中dvwaSession= c51ce410c124a10e0db5e4b97fc2af39,这个是数字13的md5值。
3、预测后续会话 ID
由于会话 ID 是简单通过md5处理,攻击者可通过如下方式进行预测。
- 记录受害者上一个报文的会话id(如c51ce410c124a10e0db5e4b97fc2af39,这个是13的md5)
- 预测后续会话 ID ,对md5解密后获知其为13,对其进行加一处理后为14
- 接下来对14进行md5处理,新的md5值为aab3238922bcc25a6f606eb525ffdc56
验证推测是否正确,再次点击generate抓包如下所示,序号为88的报文response中的dvwaSession值正是我们推断的结果,说明我们预测正确。