安全性测试入门 (四):Session Hijacking 用户会话劫持的攻击和防御

发布于 更新于
本文目录
  1. 1. Session和Cookies
  2. 2. Session Hijacking会话劫持攻击
  3. DVWA的weak session IDs 模块
  4. 3. sessionID的更合理颁发机制
  5. 4. 会话劫持的测试

技术文章安全测试

本篇继续对于安全性测试话题,结合DVWA进行研习。

本篇继续对于安全性测试话题,结合DVWA进行研习。

Session Hijacking用户会话劫持

image.png

1. Session和Cookies

这篇严格来说是用户会话劫持诸多情况中的一种,通过会话标识规则来破解用户session。

而且与前几篇不同,我们有必要先来理解一下Session和Cookie的工作机制。

实际上要谈论这两个小伙伴,又要先理解http协议的运作机制,这样讨论下去可就篇幅太长了。

我们只需要了解以下事实:

  • http协议是无状态的。

就好像两个人用老式的手摇电话机通电话。每一次http请求和数据交换就像这样的一次电话通话过程,当请求完毕以后,再进行下一次请求时,http协议是无法追踪上一则通话记录的。这样每一次用户与服务器的交互都是独立的一次通话,对于一个web应用而言显然是存在问题的,因为用户的请求十有八九具有连续性。就比如一个用户在商城添加了某商品到购物车,当他去结账时,又是一次新的请求,他的购物车http协议仅仅通过连接状态是无法追踪的!

  • Session:来来来 给你分配个号码牌。

为了解决用户的接续访问问题,一个简单的想法就是,将每一次用户与服务器之间的持续通话做为一个“会话”存放在服务器端。 当用户第一次打call进来的时候,你先别说话,先给你个小牌牌,这个小牌牌就用来做为这次用户会话的跟踪。 在我们的应用内通常使用sessionID或者类似的形式进行记录。

  • Cookie:请你证明你是你,你妈是你妈

在会话中我们有了标识自己身份的号码牌,由服务器生成颁发。用户拿到小牌牌,当然要妥善保管啦,将他存放到cookie里面就是现在的主流手段。当用户继续向服务器发出交互时,每一次接线员都先看一看这个小牌牌,证明你是你,然后再继续给你服务,不然别怪我翻脸不认人。

下图就是在DVWA上面我的用户cookie,使用JS弹框将其展示出来的效果:

image.png

2. Session Hijacking会话劫持攻击

了解session和cookie的原理机制之后,我们来思考,如果我是攻击者,我有没有方法利用到用户的cookie和session?

这种思路是有很多的:

  • 一种思路是,攻击者不获取用户的cookie和session,而是想办法让用户在不知情的情况自己去踩坑。

比如上一篇我们讲CSRF跨站脚本伪造时,就是让已经被服务器验证通过的用户来帮我做一个操作。

  • 另一种思路是,攻击者自己创造一个session信息,然后诱使用户使用这套session。

如果用户使用这套session进行了登录,那么攻击者使用同样的session去访问,就截取到了用户这次会话了。

这种套路叫做Session Fixation。

  • 另一种思路则更直接,我想办法获取到用户的会话,那么我就能够盗取用户的身份了。

这些就是所谓的session hijacking,用户会话劫持。

那么接下来的问题是,攻击者如何能获取到用户会话呢?

通过XSS攻击漏洞就可以达成目标,这个我们会在后续去探讨。

其实还有更简单的方式,服务器所颁发的这个session的标识符,也是基于一定的规则生成的。如果这套规则过于简单,那么通过猜都能猜出来!

DVWA的weak session IDs 模块

DVWA就给我们演示了什么叫过于简单的session规则:

image.png

真是。。。太简单了,简单的数字递增。想要攻击,很容易就可以猜出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长这样:

image.png

看起来好厉害哦,MD5加密了。

然鹅,破解他只需要0.05秒的MD5在线解密了解一下?

image.png

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吧。

来源:testingpai

继续阅读