免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3082 | 回复: 1
打印 上一主题 下一主题

深入浅出防御Session攻击方式之一 – 固定会话ID [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-15 15:48 |只看该作者 |倒序浏览
以下文章由360weboy撰写, 原文地址:深入浅出防御Session攻击方式之一 – 固定会话ID。该篇文章作为你必须了解的Session的本质的续篇。 360weboy – 专注php web开发, web前端开发, 打造专业的php社区。希望本篇文章对你有所帮助,感兴趣的话可以加入360weboy的qq群-197642724,或者关注360weboy的新浪微博 – weibo.sina.com/360weboy,大家在一起分享讨论开发中的技术以及思想,如发现文章有什么不对之处,请在评论中及时指出,如果确实有问题,我会及时纠正。

随着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标识符:

1. 预测
2. 捕获(劫持)
3. 固定

预测这种方式,也就是攻击者需要猜测出系统中使用的有效的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的链接:
  1. <a href="http://host/index.php?PHPSESSID=1234">
  2. Click here
  3. </a>
复制代码
或者一个php程序中的重导向,也就是应用http协议中的header来进行对请求重导向:
  1. <?php
  2. header('Location: http://host/index.php?PHPSESSID=1234');
  3. ?>
复制代码
当然,关于重导向请求的方法,还有其它几种方式。 比如, 通过HTTP中的Refresh头部来实现以及在html head标签中加入一个具有http-equiv属性的meta tag。不管使用哪种方式,关键点就是要使某个用户访问某个url, 在这个url中包括了攻击者预先设定的session标识符。这就是一般攻击中的第一步,图1对此过程进行了简单描述:

图1. 固定session id示例图

如果系统没有对此进行防御的话,用户的session标识符就这样被攻击者固定住了,接着攻击者就可以通过此session标识符来对系统进行更危险的攻击。
建议你用下面的示例代码1进行一下试验,来验证此种攻击的危险性:

示例代码1
  1. <?php
  2. session_start();

  3. if (!isset($_SESSION['count']))
  4. {
  5.    $_SESSION['count'] = 0;
  6. }
  7. else
  8. {
  9.    $_SESSION['count']++;
  10. }

  11. echo $_SESSION['count'];
  12. ?>
复制代码
请将以上示例代码保存为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

  1. <?php
  2. session_start();

  3. if (!isset($_SESSION['initiated']))
  4. {
  5.    session_regenerate_id();
  6.    $_SESSION['initiated'] = true;
  7. }
  8. ?>
复制代码
假如使用上述代码来启动所有的sessions,任何已成功创建的session肯定会包含一个初始的initiated,并且其值为true。如果没有包含这个初始值,那么可以断定这是个新会话,系统会调用session_regenerate_id这个函数来重新随机生成一个session id,原先的session id会被替代,但是其下的信息还是保留的,如果要删除旧的session的数据,可以给这个函数传递一个bool参数来实现。可以看出,在这种情况下,即使攻击者已经成功使某个用户携带预先设定的session id来访问系统,该用户也会被颁发一个新的session id。很明显,这个新的id,攻击者暂时是无法获知的,除非使用其它方式获取。

待续。。。

论坛徽章:
0
2 [报告]
发表于 2012-12-12 11:54 |只看该作者
有帮助
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP