深入浅出Session攻击方式之一 – 固定会话ID

标签: 安全 | 发表时间:2013-09-07 23:39 | 作者:360weboy
出处:http://www.blogread.cn/it/

标签:   Session   会话

随着php语言的流行,出现了无数的使用php开发的web应用程序,这吸引了大批的攻击者开始寻找,攻击有安全漏洞的php应用程序。 所以,程序的安全问题得到了越来越多的关注。做为一个专业的php开发者,必须要重视安全问题。

接下来,我们来谈谈攻击session的方法之一 - 固定会话ID。 这种攻击方式的核心要点就是让合法用户使用攻击者预先设定的session ID来访问被攻击的应用程序,一旦用户的会话ID被成功固定,攻击者就可以通过此session id来冒充用户访问应用程序(只要该session id还是有效的,也就是没有被系统重新生成或者销毁)。 通过这种方式,攻击者就不需要捕获用户的Session id(该种方式难度相对稍大)。

当然,以上的解释的前提是攻击者也知道session name了。我们简单讲个概念啊,下面提到的session标识符,php中默认的格式就是PHPSESSID=1234。等号前面的是session name, 后面的是session id。

固定会话id

在我看来,Session的安全性应该说是最重要的,也是最复杂的。对于web应用程序来说,加强安全性的第一条原则就是 - 不要信任来自客户端的数据,一定要进行数据验证以及过滤,才能在程序中使用,进而保存到数据层。 然而,为了维持来自同一个用户的不同请求之间的状态, 客户端必须要给服务器端发送一个唯一的身份标识符(Session ID)。 很显然,这和前面提到的安全原则是矛盾的,但是没有办法,http协议是无状态的,为了维持状态,我们别无选择。 可以看出,web应用程序中最脆弱的环节就是session,因为服务器端是通过来自客户端的一个身份标识来认证用户的, 所以session是web应用程序中最需要加强安全性的环节。

基于session的攻击有很多种方式。大部分的手段都是首先通过捕获合法用户的session, 然后冒充该用户来访问系统。也就是说,攻击者至少必须要获取到一个有效的session标识符,用于接下来的身份验证。

据我所知,攻击者至少可以通过以下三种方式来获取一个有效的session标识符:

  • 预测

  • 捕获(劫持)

  • 固定

预测这种方式,也就是攻击者需要猜测出系统中使用的有效的session标识符,有点类似暴力破解。 php内部session的实现机制虽然不是很安全,但是关于生成session id的关节还是比较安全的,这个随机的session id往往是极其复杂的并且难于被预测出来,所以说,这种攻击方式基本上是不太可能成功的。

捕获一个有效的session标识符 - 这种方式使用的就比较普遍了,很多的攻击类型都是使用这种方式来获取session标识符。当session标识符存储在浏览器的cookie中的时候,如果浏览器有漏洞的话(比如早期的IE),就就可能暴露其中的session标识符信息。当通过url参数来传递session标识符的话,那就更加容易暴露这个标识符,有很多方法可以捕获存在于url中的session标识符。所以,一般都是通过cookie来存储传递session标识符,尽管也有可能因为浏览器的漏洞而被攻击,但是相比通过url来传递,cookie这种方式要安全的多。

Session固定这种方式,简单来讲,攻击者要想办法,让某个用户通过他预先选择的session标识符来访问系统。一旦系统接收到了这个用户的请求,并且使用用户传递过来的session标识创建了会话,攻击者就可以使用这个session标识了。这种方式是最简单的获取有效的session标识符,但是不一定能成功,因为有的系统发现在服务器端找不到对应该session标识符的数据的话,会自动重新创建一个session标识符,并且保存到客户端。

看个示例

举个最简单的例子,一个可以固定会话id的链接:

  <ahref="http://host/index.php?PHPSESSID=1234">             Click here         </a>

或者一个php程序中的重导向,也就是应用http协议中的header来进行对请求重导向:

  header('Location: http://host/index.php?PHPSESSID=1234');    

当然,关于重导向请求的方法,还有其它几种方式。 比如, 通过HTTP中的Refresh头部来实现以及在html head标签中加入一个具有http-equiv属性的meta tag。不管使用哪种方式,关键点就是要使某个用户访问某个url, 在这个url中包括了攻击者预先设定的session标识符。这就是一般攻击中的第一步,图1对此过程进行了简单描述:

图1. 固定session id示例图

如果系统没有对此进行防御的话,用户的session标识符就这样被攻击者固定住了,接着攻击者就可以通过此session标识符来对系统进行更危险的攻击。

建议你用下面的示例代码1进行一下试验,来验证此种攻击的危险性:

示例代码1

  session_start();         if (!isset($_SESSION['count']))         {            $_SESSION['count'] =0;         }         else         {            $_SESSION['count']++;         }                  echo$_SESSION['count'];    

请将以上示例代码保存为session.php, 并且放在能通过域名进行测试的目录下面,你可以在本地建立web服务器然后配置一个虚拟域名,这个就不在这里详细讲怎么做了。假设,你在本地可以通过http://www.myhost.me/session.php在firefox浏览器中访问这个文件,请清除firefox浏览器中关于该自定义域名的所有cookie, 然后再通过http://www.myhost.me/session.php?PHPSESSID=1234再次访问session.php文件。这种情况下,在第一次访问的时候,这段代码会输出0,刷新页面,将输出1。不断刷新的话,输出的数值会不断增大,这意味着每一次请求的值得到了保留,客户端和服务端之间的状态得到了保持。

Okay.现在请换用另外一个浏览器进行测试,就用chrome(google的产品确实够快)吧。请同样地访问http://www.myhost.me/session.php?PHPSESSID=1234,你会发现初次访问的输出值不是0,而是在firefox上面浏览器中最后输出值基础上增加了1。这说明你已经侵入了前一次创建的session,虽然你在同一台电脑上,但是这两个不同的浏览器就可以代表两个不同的用户,后者成功冒充成了前者。你甚至可以换一台电脑,只要能访问到http://www.myhost.me/session.php?PHPSESSID=1234,那么你也能在另一台电脑上看到同样的结果。

所以,假如你的系统只是使用了session_start(), 请尽量不要通过url来传递session标识符,这是相当危险的,因为php默认如果没有发现cookie中的session标识符的话,就会查找是否有session标识符包含在get或者post数据中,也就是session标识符处于url参数中或者表单的隐藏域中,如果php发现了session标识符,就不在重新生成一个新的随机session id了,它会使用来自请求中获得的session id来标识此次会话。

当然,这种简单的攻击方式只对那些接受来自url的session标识符的系统起作用,不然就会失败。既然是这样,那么无论在什么情况下,对于第一次请求,我们必须保证系统要生成一个新的session id,并且颁发给客户端。有很多方法可以实现这个目标,请看下面的示例代码2(这个方式,还是有些问题,不够完善,下面还有更专业些的方案):

示例代码2

  session_start();          if (!isset($_SESSION['initiated']))         {            session_regenerate_id();            $_SESSION['initiated'] =true;         }     

假如使用上述代码来启动所有的sessions,任何已成功创建的session肯定会包含一个初始的initiated,并且其值为true。如果没有包含这个初始值,那么可以断定这是个新会话,系统会调用session_regenerate_id这个函数来重新随机生成一个session id,原先的session id会被替代,但是其下的信息还是保留的,如果要删除旧的session的数据,可以给这个函数传递一个bool参数来实现。可以看出,在这种情况下,即使攻击者已经成功使某个用户携带预先设定的session id来访问系统,该用户也会被颁发一个新的session id。很明显,这个新的id,攻击者暂时是无法获知的,除非使用其它方式获取。但是,一个老练的攻击者还是有办法来绕过以上检查,请看下节。

老练的攻击

一个经验丰富一些的攻击者,往往会自己先访问目标系统,从而从系统处获得一个合法的session标识符,并且保持这个session标识符不过期,然后再使用前面讲过的方式,来使某个目标用户使用攻击者获取的,当前有效的session标识符来访问目标系统。这种情况下,如果该用户登录后(假设在用户登录时,系统没有重新生成session id),那么攻击者就可以通过同样的session标识符来侵入用户在该系统中的账务,这是很危险的事情,意味着用户的敏感信息会被泄露,或者导致后续更危险的操作的发生。所以,在用户登录的时候,切记一定要重新生成session id,因为这个时刻关于此用户的敏感信息会被保存到session数据中。建议你在认证了用户的用户名以及密码后,可以先调用session_regenerate_id来重新生成一个session id,然后再初始化一个表明用户处在登录状态的session变量,例如下面的示例代码:

  session_regenerate_id();         $_SESSION['logged_in'] =true;    

以上代码,可以有效地抵御固定会话ID的攻击。事实上,最好在用户权限发生变化的时候或者因为闲置时间太长而导致session过期,用户再次进行验证身份的时候,就进行一次session id的重新生成。这样的话,可以肯定的说,你的系统就不会受到以上攻击方式的侵害。

由此可见,以上方式比前面的例子安全级别高多了,因为我们给攻击者制造了另外一层障碍,这道障碍有效地防止了攻击者先获取合法session标识符,并且保持有效性,然后再实施侵入。

总结

总的来说,抵御固定会话ID此类攻击的最有效的措施就是在用户提供验证信息,相应的权限级别发生改变的时候,就进行session id的重新生成。当然,情况总是不断变化,这不总是万无一失的。 你可能还有更好的办法,愿意分享的话,请在下面留言!

您可能还对下面的文章感兴趣:

  1. 说说会话串号 [2013-06-17 23:49:02]
  2. Shell Tips: 用GNU Screen实现发送交互到所有会话 [2011-03-27 23:37:28]
  3. Oracle MTS模式下 进程地址与会话信息 [2010-11-01 19:56:17]

相关 [session 攻击 会话] 推荐:

session fixation攻击

- - 互联网 - ITeye博客
什么是session fixation攻击. Session fixation有人翻译成“Session完成攻击”,实际上fixation是确知和确定的意思,在此是指Web服务的会话ID是确知不变的,攻击者为受害着确定一个会话ID从而达到攻击的目的. 在维基百科中专门有个词条 http://en.wikipedia.org/wiki/Session_fixation,在此引述其攻击情景,防范策略参考原文.

深入浅出Session攻击方式之一 – 固定会话ID

- - IT技术博客大学习
标签:   Session   会话. 随着php语言的流行,出现了无数的使用php开发的web应用程序,这吸引了大批的攻击者开始寻找,攻击有安全漏洞的php应用程序. 所以,程序的安全问题得到了越来越多的关注. 做为一个专业的php开发者,必须要重视安全问题. 接下来,我们来谈谈攻击session的方法之一 - 固定会话ID.

Zookeeper的Session

- - 行业应用 - ITeye博客
介绍一下基于zookeeper的一些API的编程. 在此之前,我们先来熟悉一下相关知识:. Zookeeper的Session:. (1)客户端和server间采用长连接. (2)连接建立后,server产生session ID(64位)返还给客户端. (3)客户端定期发送ping包来检查和保持和server的连接.

Session机制解析

- - ITeye博客
虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一技术. 本文将详细讨论session的工作机制并且对在Java web application中应用session机制时常见的问题作出解答. 二、HTTP协议与状态保持.

session和cookie详解

- - ITeye博客
摘要:虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一 技术. 本文将详细讨论session的工作机制并且对在Java web application中应用session机制时常见的问题作出解答. 二、HTTP协议与状态保持.

nginx + memcached session 同步

- - 企业架构 - ITeye博客
squid 缓存疑问 问题归纳:. 1 squid 缓存的数据,何时过期,如何判断缓存的数据已经过期,如何把最新的数据缓入squid 并且替换掉旧的内容. 2 如何判断数据是否应该被缓存. 3 校验失败时,是否给出缓存中旧的内容. 上面的几个问题  都可以通过 squid中的 refresh_pattern 配置项 找到答案.

session深入解读

- - CSDN博客推荐文章
林炳文Evankaka原创作品. 转载请注明出处 http://blog.csdn.net/evankaka. 摘要:虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一技术. 本文将详细讨论session的工作机制并且对在Java web application中应用session机制时常见的问题作出解答.

JavaOne美国之行–Session篇

- LightingMan - 淘宝JAVA中间件团队博客
Session的总结是重头戏,在这篇blog中,来分享下我参与过的Session,以及听完后我对Session的评价和对于有收获的Session制定的一些Action Plan. 本届JavaOne我总共参加了24个Session,主要集中在JVM方面以及Experience Talk方面,5分为最高分的话,我给这些Session的评分状况如下所示:.

PHP Session学习笔记

- 张大糊涂 - 标点符
在web开发中,session是个非常重要的概念. Session一般译作会话,Session是一种基于HTTP协议的用以增强web应用能力的机制或者说一种方案,它不是单指某种特定的动态页面技术,而这种能力就是保持状态,也可以称作保持会话. 在许多动态网站的开发者看来,session就是一个变量,而且其表现像个黑洞,他只需要将东西在合适的时机放进这个洞里,等需要的时候再把东西取出来.

session工作机制解析

- - 企业架构 - ITeye博客
摘要:虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一技术. 本文将详细讨论session的工作机制并且对在Java web application中应用session机制时常见的问题作出解答. 二、HTTP协议与状态保持.