漏洞简述
以下摘自《白帽子讲 web 安全》
密码与证书等认证手段,一般仅仅用于登录(Login)的过程。当登陆完成后,用户访问网站的页面,不可能每次浏览器请求页面时,都再使用密码认证一次。因此,当认证完成后,就需要替换一个对用户透明的凭证。这个凭证就是SessionID。
当用户登陆完成后,在服务器端就会创建一个新的会话(Session),会话中会保存用户的状态和相关信息。服务器端维护所有在线用户的Session,此时的认证,只需要知道是哪个用户在浏览当前的页面即可。为了告诉服务器应该使用哪一个Session,浏览器需要把当前用户持有的SessionID告知服务器。最常见的做法就是把SessionID加密后保存在Cookie中,因为Cookie会随着HTTP请求头发送,且受到浏览器同源策略的保护。
SessionID一旦在生命周期内被窃取,就等同于账户失窃。同时由于SessionID是用户登录之后才持有的认证凭证,因此黑客不需要再攻击登陆过程(比如密码)。Session劫持就是一种通过窃取用户SessionID后,使用该SessionID登录进目标账户的攻击方法,此时攻击者实际上是使用了目标账户的有效Session。如果SessionID是保存在Cookie中的,则这种攻击可以称为Cookie劫持。SessionID还可以保存在URL中,作为一个请求的一个参数,但是这种方式的安全性难以经受考验。
因此,在生成SessionID时,需要保证足够的随机性,比如采用足够强的伪随机数生成算法。
SessionID利用的实质:SessionID是在登录后,作为特定用户访问站点所需的唯一内容。如果能够计算或轻易猜到该SessionID,则攻击者将可以轻易获取访问权限,无需登录密码直接进入特定用户界面,进而查找其他漏洞如XSS、文件上传等等。
会话标识未及时更新
AppScan会给某些系统报该中危漏洞——会话标识未更新,来看看AppScan对该漏洞的描述。
【危害描述】
可能会窃取或操纵客户会话和 cookie,它们可能用于模仿合法用户,从而使黑客能够以该用户身份查看或变更用户记录以及执行事务。
【技术描述】
在认证用户或者以其他方式建立新用户会话时,如果不使任何现有会话标识失效,攻击者就有机会窃取已认证的会话。通常在以下情况下会观察到这样的场景:
Web 应用程序在没有首先废除现有会话的情况下认证用户,也就是说,继续使用已与用户关联的会话;
攻击者能够强制对用户使用已知会话标识,这样一旦用户进行认证,攻击者就有权访问已认证的会话(参见下文“固定会话攻击”);
应用程序或容器使用可预测的会话标识(参见下文“DVWA弱会话ID实验”)。
AppScan 发现在登录过程之前和之后的会话标识未更新,这意味着有可能发生假冒用户的情况。远程攻击者预先知道了会话标识值,就能够假冒已登录的合法用户的身份。
【攻击流程】
攻击者使用受害者的浏览器来打开易受攻击的站点的登录表单。
一旦打开表单,攻击者就写下会话标识值,然后等待。
在受害者登录到易受攻击的站点时,其会话标识不会更新。
然后攻击者可利用会话标识值来假冒受害的用户,并以该用户的身份操作。
【会话标识值的获得方式】
可通过利用“跨站点脚本编制”脆弱性(导致受害者的浏览器在联系易受攻击的站点时使用预定义的会话标识)来获取;
通过发起“会话固定”攻击(将导致站点向受害者的浏览器提供预定义的会话标识)来获取。
显然,“会话标识未及时更新”的漏洞利用(或者说风险)的关键,就是如何获得会话标识值。
会话固定攻击
会话固定攻击(session fixation attack)是利用应用系统在服务器的会话ID固定不变机制,借助他人用相同的会话ID获取认证和授权,然后利用该会话ID劫持他人的会话以成功冒充他人,造成会话固定攻击。
漏洞分析
案例分析:
Mallory先打开一个网站http://unsafe,然后服务器会回复他一个SessionId。比如SID=mjg4qid0wioq,Mallory把这个id记下了;
Mallory给Alice发送一个电子邮件,他假装是银行在宣传自己的新业务,例如,我行推出了一项新服务,率先体验请点击:http://unsafe/?SID=mjg4qid0wioq,SID后面是Mallory自己的SessionID;
Alice被吸引了,点击了http://unsafe/?SID=mjg4qid0wioq,像往常一样,输入了自己的帐号和口令从而登录到银行网站;
因为服务器的session id不改变,现在Mallory点击 http://unsafe/?SID=mjg4qid0wioq
后,他就拥有了Alice的身份。可以为所欲为了。
【注意】所以以后看到发来的地址带有一串id的比如:SID=mjg4qid0wioq、jsessionid=mjg4qid0wioq的,就要长个心眼了,以防是别有用心之人盗取你的账号。
漏洞修复
1、登录重建会话
每次登录后都重置会话ID,并生成一个新的会话ID,这样攻击者就无法用自己的会话ID来劫持会话,核心代码如下。
// 会话失效
session.invalidate();
// 会话重建
session=request.getSession(true);
1
2
3
4
在spring security中,默认就带了这个方案,有session-fixation-protection。如果想搞个不安全的服务自己玩玩,可以修改session-fixation-protection为"none"
1
2
3
4
2、禁用客户端访问Cookie
此方法也避免了配合XSS攻击来获取Cookie中的会话信息以达成会话固定攻击。在Http响应头中启用HttpOnly属性,或者在tomcat容器中配置。
实战案例
在对某站进行渗透测试的过程中,发现该站的cookie值(jsessionid)无论进行几次登录,都始终保持一致:
【攻击思路】
这开发人员只能用666来形容了!!无论进行几次登录,每次登录的Cookie值的初始值都不变,登陆成功后也依然不变!!!
那么问题来了——Cookie在该系统中还有啥作用?
那我岂不是只要获得系统业务功能的URL,直接拿来就能干进去,不需要经过密码验证就能访问,因为我的Cookie跟成功登录后的管理员的Cookie本来就一毛一样??!!
说干就干!退出登录,直接浏览器访问上图中管理员权限的查询请求的URL试试:
此处只能说……服了!敞开大门让人烧杀淫掠……直接越权访问,系统的访问控制机制哪去了?会话固定的话,系统的登录控制机制不就形同虚设?
DVWA弱会话ID实验
此模块使用四种不同的方式来设置dvwaSession的cookie值,每个级别的目标是计算ID的生成方式,然后推断其他管理员用户的ID。
Low-整数ID递增
服务器源码
<?php
$html = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
if (!isset ($_SESSION['last_session_id'])) {
$_SESSION['last_session_id'] = 0;
}
$_SESSION['last_session_id']++;
$cookie_value = $_SESSION['last_session_id'];
setcookie("dvwaSession", $cookie_value);
}
?>
1
2
3
4
5
6
7
8
9
10
11
可以看出,dvwaSession是从0开始的,每次加1。
Exploit
模拟管理员登录,在浏览器1(谷歌) 里,点击Generate,Burpsuite抓包,发送到Repeater,go一次,发现:
请求头中:PHPSESSID=9igf4g7mcnegrv91ro6eq4msj1; security=low
响应头中:Set-Cookie: dvwaSession=1
多go几次,发现dvwaSession一直增加,且每次加1。
或者我们可以在谷歌浏览器里直接利用F12查看Cookie即可观察以上变化,无需使用BurpSuite:
恶意攻击者通过寻找到上述规律,使用浏览器2(火狐),成功构造出payload:
PHPSESSID=avd2i8qnspgejq264s1130rsb5;dvwaSession=7;security=low
1
使用火狐浏览器黑客插件工具——Hackbar,输入要访问的服务器URL以及上面伪造的cookie,点击execute按键:即可在无密码认证的情况下,成功登陆到界面:
【注意】如果不能顺利跳转到已登录后的页面,请多试几下,可能有的时候谷歌浏览器那边会话ID已过期失效,刷新页面会自动退回到密码登陆界面,此时重新登录,然后返回到火狐浏览器,重新利用Hackbar进行攻击尝试即可。
Medium-时间戳ID
查看服务器源码
<?php
$html = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$cookie_value = time();
setcookie("dvwaSession", $cookie_value);
}
?>
1
2
3
4
5
6
7
发现dvwaSession和时间戳变化一致。不抓包了,直接通过F12观察验证dvwaSession的变化:
刷新重载页面一下:
恶意攻击者通过寻找到上述规律,使用浏览器2,成功构造出payload:
PHPSESSID=6jvh1ra1f87fbulsfbc9hdr436;dvwaSession=1562465950;security=medium
1
在无密码认证的情况下,成功登陆到界面:
High-MD5加密ID
查看服务器源码
<?php
$html = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
if (!isset ($_SESSION['last_session_id_high'])) {
$_SESSION['last_session_id_high'] = 0;
}
$_SESSION['last_session_id_high']++;
$cookie_value = md5($_SESSION['last_session_id_high']);
setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], false, false);
}
?>
1
2
3
4
5
6
7
8
9
10
11
PHP setcookie()函数:
setcookie(name,value,expire,path,domain,secure,httponly)
参数 描述
name 必需。规定cookie的名称。
value 必需。规定cookie的值。
expire 可选。规定cookie的有效期。
path 可选。规定cookie的服务器路径。
domain 可选。规定cookie的域名。
secure 可选。规定是否通过安全的HTTPS连接来传输cookie。
httponly 可选。规定是否Cookie仅可通过HTTP协议访问。
1
2
3
4
5
6
7
8
9
由源码可知:
value 值:last_session_id_high 自增 1,再用 md5 加密
expire 值:当前时间再加一个小时
path 值:/vulnerabilities/weak_id/
1
2
3
Exploit
模拟管理员登录,在浏览器 1 里,点击Generate,在BurpSuite里抓包发送到Repeater模块,多次GO并查看结果:
发现dvwaSession值通过MD5加密。将每次产生的MD5解密,发现解密后的值,发现和低等级中的代码一样,是从0开始加的。
恶意攻击者通过寻找到上述规律,使用浏览器2(火狐),成功构造出payload:
PHPSESSID=2smaebq81bbqcgv6tes9cndu97;dvwaSession=c81e728d9d4c2f636f067f89cc14862c;security=high
1
在无密码认证的情况下,成功登陆到界面:
Impossible-随机数
服务器源码
<?php
$html = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$cookie_value = sha1(mt_rand() . time() . "Impossible");
setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], true, true);
}
?>
1
2
3
4
5
6
7
$cookie_value采用随机数+时间戳+固定字符串"Impossible",再进行sha1运算,完全不能猜测到dvwaSession的值。实现了用户安全会话认证。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_39190897/article/details/94962530