在日常的渗透测试工作中经常发现会话固定漏洞,但是由于实际危害较小,多数情况下并没有把该漏洞写进报告中。一直对这个洞没什么深入的认识,今天好好看看,所以就有了这篇小短文,跟大家分享下我的理解。
漏洞原理
代码语言:javascript复制抛开花里胡哨的包装,看最本质的东西。
漏洞的本质用一句话来说是把一个无效的或者说低权限的令牌提升为高权限的令牌,而这个令牌标识是攻击者可以控制的。利用漏洞攻击的整体流程。如下图。
攻击流程分为五个阶段:
1、攻击者请求 web 服务器生成会话令牌。(这一步不是必须的,因为有的服务器接受任意的会话令牌。)
2、web 服务器将令牌回复给攻击者。(这一步不是必须的,因为有的服务器接受任意的会话令牌。)
3、攻击者将与其当前令牌所关联的认证页面发送给用户。
4、用户使用攻击者发送的链接登陆 web 服务器,此时攻击者令牌提权,获得了用户的权限。
5、攻击者使用已知令牌登陆系统。
为什么要从客户端接收会话令牌
漏洞一般是与业务功能、客户需求等相伴相生的。结合自己不多的经验,我总结推想出两种可能的漏洞场景:
1、为了适应不使用 cookies 的客户端
有一些客户端基于种种原因,不愿使用 cookies,或者压根就不支持。为了照顾这一部分用户,web 程序的开发者则不得不做出妥协,使用其他的方式传送会话令牌。
2、引入了 SSO 的认证场景
SSO(Single Sign On)也就是单点认证,一处登陆多处访问。在同一域下的登陆与资源访问可以很方便的使用 cookies 实现的会话令牌进行控制,如下图。
但是如果跨域了,cookies 也就不那么方便了。就得用能跨域的东西做会话令牌了(比如说把令牌放到参数中),如下图:
认真看图就能发现,登陆过程的 url 和免登 url 都可能携带会话令牌。web 开发者各有千秋,业务需求也各有不同,其他位置也都有可能出现会话令牌。(图中是比较完备的 SSO 实现,真实的系统不一定能实现的这么完整,应该说实现的不完整的 SSO 更易受到会话固定攻击。)
漏洞测试
为了看到直观的漏洞攻击效果,这里使用世界上最好的语言之一——PHP 进行测试。为了适应客户端的奇葩需求,PHP 实现了一种可以通过 url 参数传递 session id 的机制,不过不是默认配置(应该不是)。需要在 php 配置文件中配置一下:
加入这几条配置:
设置是否适用 cookies 存储 sessionid,如果为 0 则不适用 cookies,对演示效果没有影响,如果为 1,则优先使用 cookies 中的 session id
session.use_cookies = 0
是否只是用 cookies 存储 sessionid,如果为 1,则不能使用 url 传 session id
session.use_only_cookies = 0
是否在 url 中传输 sessionid,为 0 时不能使用 url 传令牌
session.use_trans_sid = 1
测试代码
写了两个简单的界面复现这个漏洞。
index.php
<?php
$id=md5(time().'salt');//无法预测的salt
header('location:login.php?PHPSESSID='.$id);
login.php
<?php
session_start();
$user='admin';
$pass='password';
if(isset($user)&&isset($pass)){
if($_GET['user']==$user&&$_GET['pass']==$pass){ $_SESSION['user']='admin';
}
}if($_SESSION['user']=='admin'){
echo'hello admin!';
}else{
echo'please login.';
}
echo'<br>';
echosession_id();//方便查看当前的session id是啥
测试过程
首先使用攻击者浏览器访问 index.php 获得带令牌的登陆 url。
然后到另外一个浏览器(用户浏览器)使用该链接登陆账户
此时在攻击者浏览器刷新下页面
漏洞实例
由于这个漏洞实际危害较低,又为了安全研究与学习的目的,所以要看一下生产环境中该漏洞的危害。
直接百度 inurl:PHPSESSID
直接搜一个站看看。
我挑了一个有注册登陆功能的站。初步测试下,基本实锤了。
这个站可以接收任意的 session id
首先使用常规操作注册一个账号,作为待测试的用户账号。
构造 url
http://www.xxx.com/?PHPSESSID=你的sessionid
超长的字符串容易引起警觉,所以我直接改个短的。把 1 作为 sessionid
在受害者浏览器打开并登陆
随后在攻击者浏览器把 session id 改为 1
刷新页面,发现已经登陆成功。
后话
1、不只形如 http://test/?XXXSESSIONID=1234
的链接可能存在这种问题,通过 POST 传递参数也同样存在这种问题。
2、对会话固定漏洞的挖掘不能局限于对形如 sessioniid 的变量的监控,应该着眼于一切有会话令牌性质的变量。(换句话说就是 sessionid 不只是 cookies 里那一点。)
3、会话固定与其定性为漏洞,不如定性为一个普通的攻击手法。