一、Session是什么

密码与证书等认证手段,一般用于登录过程。用户登录之后,服务器通常会建立一个新的Session保存用户的状态和相关信息,用以跟踪用户的状态。每个Session对应一个标识符SessionID来标识用户身份,SessionID一般是加密保存在Cookie中。虽然Cookie也是为了跟踪用户状态,但是Cookie存储在客户端上,Session存储在服务器上。有些网站也会将Session保存在Cookie中,以减轻服务器维护Session的压力。Session在网络应用中被称为“会话控制”。

二、Session Hijacking

与盗取用户名、密码登陆用户帐户的方式有所不同,Session劫持是一种通过窃取用户的SessionID,使用该SessionID登录目标账户的攻击方法。此时攻击者实际上是使用了目标账户的有效Session。如果SessionID是保存在Cookie中的,则这种攻击可以成为Cookie劫持。

攻击步骤如下:


<?php 

session_start(); 

if (!isset($_SESSION['count'])) {    

  $_SESSION['count'] = 0

} else {    

  $_SESSION['count']++; 

echo 'Now Count:'.$_SESSION['count'];  

?>

下面通过一个实验来简单演示Session Hijacking的过程。

此段代码部署在服务器上,功能是在服务器上开启Session,初始时将$_SESSION['count']置0。当页面结束后,$_SESSION['count']的值会被自动保存下来,同时在用户浏览器上留下一个包含着SessionID的Cookie。该用户下次再访问时,会使用该Cookie继续会话,$_SESSION['count']自增,实现简单的计数器功能。

在清除浏览器所有Cookie的情况下,用Chrome访问此页面:

2.jpg

多刷新几次页面,由于处于同一个Session,计数器的数字会增长。打开Chrome的开发者工具(F12),查看到SessionID如下,此时计数器显示为9:

3.jpg

打开另一个浏览器(此处以Firefox为例,也可换用另一台电脑)访问session.php,用Firefox插件[Tamper Data]进行抓包。因为两个浏览器处于不同的Session,所以Firefox计数器的初始值为0:

4.jpg

点击“Start Tamper”,再刷新一下Firefox的界面,正常情况下计数器应该刷新为1。现在我们要模拟Session劫持的过程,假设通过某种手段窃取到了Chrome的SessionID,并且将Firefox中的SessionID修改为刚才窃取到的Chrome中的SessionID,点击确定发送数据:

此时,Firefox中的计数器直接变成了10,相当于操纵了Chrome的Session,对刚才的9进行了自增运算:

5_1.jpg

可以看到,虽然换了浏览器,但是只要获得了SessionID,即可窃取到有效会话。如果交替刷新两个浏览器,操纵的其实是同一个计数器。因为在服务器看来,客户端传来了相同的SessionID,即可认定为是同一个Session。常见的应用场景有窃取用户登录后的邮箱、博客的SessionID,对用户账户进行非法登录,盗取隐私信息。

获取SessionID的主要方式:

1) 网络嗅探:在公共上网区域,可通过网络嗅探来获取SessionID,常用的一些工具有:Ettercap、Cain & Abel、Dsniff。

2) SessionID预测:如果SessionID使用非随机的方式产生,则可以通过分析SessionID的强度(长度、字符集以及平均信息量),将其计算出来,例如可以使用Burp Suite中的Sequencer模块对会话进行分析。

3) 客户端攻击:XSS、木马等。

三、 Session Fixation

Session Fixation虽然同为盗用合法用户SessionID的一种方式,但是攻击原理又有所不同。Session Hijacking是攻击者窃取了一个合法的SessionID;Session Fixation是攻击者预先计算一个SessionID,诱使用户使用此SessionID登陆,并使之合法。因此,Session Fixation适用于登陆前后SessionID不发生变化的场景。

攻击步骤如下:

6.jpg

下面使用WebGoat下的Session Management Flaws->Session Fixation来演示这一过程:

攻击者给目标用户发送一封邮件,并在链接中插入预先设定好SessionID:

7.jpg

目标用户收到此邮件后,点开链接并且跳转到登陆界面

8.jpg

目标用户输入正确的用户名、密码发送给服务器,服务器即将此用户的Session与攻击者预先设定好的SessionID进行绑定:

9.jpg

目标用户登录完成后,攻击者打开含有SessionID的链接,即可在不知道用户名和密码的情况下登陆用户帐户:

10.jpg

Session Hijacking与Session Fixation的异同之处如下:

11.jpg

四、防御对策

部署HTTPS防止SessionID被窃取。

设置HttpOnly属性防止XSS攻击。在PHP中,可以通过修改php.ini中的“session.cookie_httponly = 1 ”开启全局Cookie的HttpOnly属性。也可以使用“setcookie”函数来启用。

客户端发生变化时,要求用户重新登录。例如使用User-Agent、IP地址、MAC地址等检测请求的一致性,并且加入Token进行检验。

更改SessionID名称。例如PHP中SessionID的默认名称是PHPSESSID,此变量会保存在Cookie中,如果攻击者不分析站点,就不能猜到SessionID的名称,阻挡部分攻击。加大SessionID的安全长度,加大暴力猜解难度。

为每一次请求生成新的SessionID,特别是登陆前后的 SessionID需要有所不相同,只接受服务器生成的SessionID。

设置会话超时属性,设定阈值强制会话过期。

参考资料

 《白帽子讲web安全》

 http://www.freebuf.com/articles/web/10369.html

 http://blog.csdn.net/h_mxc/article/details/50542038

 https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/06.4.md

 http://shiflett.org/articles/session-fixation

 http://resources.infosecinstitute.com/understanding-session-fixation/

 https://en.wikipedia.org/wiki/Session_fixation

*本文原创作者:ArkTeam/Snowty