本篇继续对于安全性测试话题, 结合 DVWA 进行研习.
Session Hijacking 用户会话劫持
1. Session 和 Cookies
这篇严格来说是用户会话劫持诸多情况中的一种, 通过会话标识规则来破解用户 session.
而且与前几篇不同, 我们有必要先来理解一下 Session 和 Cookie 的工作机制.
实际上要谈论这两个小伙伴, 又要先理解 http 协议的运作机制, 这样讨论下去可就篇幅太长了.
我们只需要了解以下事实:
http 协议是无状态的
就好像两个人用老式的手摇电话机通电话. 每一次 http 请求和数据交换就像这样的一次电话通话过程, 当请求完毕以后, 再进行下一次请求时, http 协议是无法追踪上一则通话记录的. 这样每一次用户与服务器的交互都是独立的一次通话, 对于一个 web 应用而言显然是存在问题的, 因为用户的请求十有八九具有连续性. 就比如一个用户在商城添加了某商品到购物车, 当他去结账时, 又是一次新的请求, 他的购物车 http 协议仅仅通过连接状态是无法追踪的!
Session: 来来来 给你分配个号码牌
为了解决用户的接续访问问题, 一个简单的想法就是, 将每一次用户与服务器之间的持续通话做为一个 "会话" 存放在服务器端.
当用户第一次打 call 进来的时候, 你先别说话, 先给你个小牌牌, 这个小牌牌就用来做为这次用户会话的跟踪.
在我们的应用内通常使用 sessionID 或者类似的形式进行记录.
Cookie: 请你证明你是你, 你妈是你妈
在会话中我们有了标识自己身份的号码牌, 由服务器生成颁发. 用户拿到小牌牌, 当然要妥善保管啦, 将他存放到 cookie 里面就是现在的主流手段. 当用户继续向服务器发出交互时, 每一次接线员都先看一看这个小牌牌, 证明你是你, 然后再继续给你服务, 不然别怪我翻脸不认人.
他们关系就类似这样婶儿的:
下图就是在 DVWA 上面我的用户 cookie, 使用 JS 弹框将其展示出来的效果:
2. Session Hijacking 会话劫持攻击
了解 session 和 cookie 的原理机制之后, 我们来思考, 如果我是攻击者, 我有没有方法利用到用户的 cookie 和 session?
这种思路是有很多的:
一种思路是, 攻击者不获取用户的 cookie 和 session, 而是想办法让用户在不知情的情况自己去踩坑.
比如上一篇我们讲 CSRF 跨站脚本伪造时, 就是让已经被服务器验证通过的用户来帮我做一个操作.
另一种思路是, 攻击者自己创造一个 session 信息, 然后诱使用户使用这套 session.
如果用户使用这套 session 进行了登录, 那么攻击者使用同样的 session 去访问, 就截取到了用户这次会话了.(这种攻击叫 Session Fiaxtion - 固定会话攻击)
另一种思路则更直接, 我想办法获取到用户的会话信息, 那么我就能够盗取用户的身份了.
这些就是所谓的 session hijacking, 用户会话劫持.
那么接下来的问题是, 攻击者如何能获取到用户会话呢?
通过 XSS 攻击漏洞就可以达成目标, 这个我们会在后续去探讨.
其实还有更简单的方式, 服务器所颁发的这个 session 的标识符, 也是基于一定的规则生成的. 如果这套规则过于简单, 那么通过猜都能猜出来!
DVWA 的 weak session IDs 模块
DVWA 就给我们演示了什么叫过于简单的 session 规则:
真是... 太简单了, 简单的数字递增. 想要攻击, 很容易就可以猜出 sessionid, 然后加以利用.
3. sessionID 的更合理颁发机制
下面我们同样看看 DVWA 是如何加强 session 颁发机制的:
Medium 级别防御
- <?PHP
- $html = "";
- if ($_SERVER['REQUEST_METHOD'] == "POST") {
- $cookie_value = time();
- setcookie("dvwaSession", $cookie_value);
- }
- ?>
使用时间戳来生成 session 标识, 还是挺好猜的.
High 级别防御
- <?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);
- }
- ?>
颁发完了的 sessionID 长这样:
看起来好厉害哦, MD5 加密了.
然鹅, 破解他只需要 0.05 秒的 MD5 在线解密了解一下?
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);
- }
- ?>
使用随机数 + 时间戳 + 常量字符串 + sha1 加密. 好吧, 确实很难猜出来了, 是不是 impossible 呢? 唔...
4. 会话劫持的测试
事实上到此为止我们还不能全面讨论会话劫持的测试, 因为还有很多种劫持的方法我们没有去了解.
不过呢, 我们可以借这个机会来解释一下安全测试的大方向.
路是一步步走出来的, 同样的道理, 产品的安全能力也是一层一层构建起来的.
一个产品的防御机制是一种典型的 1+1>2 的概念.
我在项目中间经常看到这种现象: 由于现在的前端技术也比较成熟了, 很多后端工程师就依赖于前端去完成数据校验工作, 后端校验就省去了.
但是实际上任何产品的安全机制都应该是层层叠加的体系, 任何单层的防御都不能确保产品的绝对安全.
上面提到的前后端校验就是很好的例子: 前端校验实在太容易绕过了, 后端必须要做好二重校验, 这就是个双保险的概念.
回到用户劫持攻击的测试, session 标识颁发规则就是产品层叠防御机制中的其中一层.
测试人员可以通过解读这一规则来判断他的合理性. 简单来说, 如果你们的 session 标识规则, 你能够想办法破解掉, 不用想了报 bug 吧.
来源: https://www.cnblogs.com/yingyingja/p/10932140.html