本文转载自:https://devco.re/blog/2014/06/03/http-session-protection/
本文未排版,原文排版更好
侵删
By Allen Own on 2014-06-03
大家还记得四月份的OpenSSL Heartbleed事件吗?当时除了网站本身以外,受害最严重的就属VPN Server了。国内外不少骇客不眠不休利用Heartbleed漏洞窃取VPN Server的管理者Session Cookie,运气好的话就可以直接登入大企业的内网。
但是,其实这样的风险是可以避免的,今天我们以开发者的角度来谈谈Session 的攻击与防护。
在谈Session 之前,我们要先了解Cookie。你知道网站是如何辨识我们的身份吗?为什么我们输入完帐号密码之后,网站就知道我们是谁呢?就是利用Cookie。Cookie 是网站在浏览器中存放的资料,内容包括使用者在网站上的偏好设定、或者是登入的Session ID。网站利用Session ID 来辨认访客的身份。
Cookie既然存放在Client端,那就有被窃取的风险。例如透过Cross-Site Scripting(跨站脚本攻击,又称XSS),攻击者可以轻易窃取受害者的Cookie。如果Cookie被偷走了,你的身份就被窃取了。
我们可以用一个譬喻来表示:你加入了一个秘密俱乐部,填写完会员资料后,得到了一张会员卡。之后只要凭这张会员卡,就可以进入这个俱乐部。但是隔天,你的会员卡掉了。捡走你会员卡的人,就可以用你的会员卡进入这个秘密俱乐部,因为会员卡上没有你的照片或是其他足以辨识身分的资讯。这就像是一个会员网站,我们申请了一个帐号(填写会员资料加入俱乐部),输入帐号密码登入之后,得到一组Cookie,其中有Session ID 来辨识你的身分(透过会员卡来辨识身分)。今天如果Cookie 被偷走了(会员卡被捡走了),别人就可以用你的帐号来登入网站(别人用你的会员卡进入俱乐部)。
Session 攻击手法有三种:
我们以下一一介绍。
Session ID 如同我们前面所说的,就如同是会员卡的编号。只要知道Session ID,就可以成为这个使用者。如果Session ID 的长度、复杂度、杂乱度不够,就能够被攻击者猜测。攻击者只要写程式不断暴力计算Session ID,就有机会得到有效的Session ID 而窃取使用者帐号。
分析Session ID 的工具可以用以下几种
观察Session ID 的乱数分布,可以了解是否能够推出规律、猜测有效的Session ID。
分析Session ID
Ref: http://programming4.us/security/3950.aspx
防护措施
使用Session ID 分析程式进行分析,评估是否无法被预测。如果没有100% 的把握自己撰写的Session ID 产生机制是安全的,不妨使用内建的Session ID 产生function,通常都有一定程度的安全。
窃取Session ID 是最常见的攻击手法。攻击者可以利用多种方式窃取Cookie 获取Session ID:
跨站脚本攻击( Cross-Site Scripting (XSS) ):利用XSS漏洞窃取使用者Cookie
网路窃听:使用ARP Spoofing 等手法窃听网路封包获取Cookie
透过Referer 取得:若网站允许Session ID 使用URL 传递,便可能从Referer 取得Session ID
窃取利用的方式如下图:
受害者已经登入网站伺服器,并且取得Session ID,在连线过程中攻击者用窃听的方式获取受害者Session ID。
窃取Session ID
攻击者直接使用窃取到的Session ID 送至伺服器,伪造受害者身分。若伺服器没有检查Session ID 的使用者身分,则可以让攻击者得逞。
伪造Session ID
防护措施
禁止将Session ID 使用URL (GET) 方式来传递
设定加强安全性的Cookie 属性:HttpOnly (无法被JavaScript 存取)
设定加强安全性的Cookie 属性:Secure (只在HTTPS 传递,若网站无HTTPS 请勿设定)
在需要权限的页面请使用者重新输入密码
攻击者诱使受害者使用特定的Session ID 登入网站,而攻击者就能取得受害者的身分。
攻击者从网站取得有效Session ID
使用社交工程等手法诱使受害者点选连结,使用该Session ID 登入网站
受害者输入帐号密码成功登入网站
攻击者使用该Session ID,操作受害者的帐号
Session Fixation
防护措施
Session 防护
那要怎么防范攻击呢?当然会有人说,会员卡不要掉不就没事了吗?当然我们没办法确保用户不会因为各种方式导致Cookie 遭窃(XSS、恶意程式等),因此最后一道防线就是网站的Session 保护。一张会员卡上如果没有任何可识别的个人资料,当然任何人捡去了都可以用。如果上面有照片跟签名呢?偷走会员卡的人在进入俱乐部的时候,在门口就会因为照片跟本人不符而被挡下来。Session 保护也是一样,怎么让我们的Session 保护机制也能辨识身分呢?答案是利用每个使用者特有的识别资讯。
每个使用者在登入网站的时候,我们可以用每个人特有的识别资讯来确认身分:
来源IP 位址
浏览器User-Agent
如果在同一个Session 中,使用者的IP 或者User-Agent 改变了,最安全的作法就是把这个Session 清除,请使用者重新登入。虽然使用者可能因为IP 更换、Proxy 等因素导致被强制登出,但为了安全性,便利性必须要与之取舍。以PHP 为例,我们可以这样撰写:
if($_SERVER['REMOTE_ADDR'] !== $_SESSION['LAST_REMOTE_ADDR'] || $_SERVER['HTTP_USER_AGENT'] !== $_SESSION['LAST_USER_AGENT']) {
session_destroy();
}
session_regenerate_id();
$_SESSION['LAST_REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['LAST_USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];
除了检查个人识别资讯来确认是否盗用之外,也可以增加前述的Session ID 的防护方式:
Cookie 设定Secure Flag (HTTPS)
Cookie 设定HTTP Only Flag
成功登入后立即变更Session ID
Session 的清除机制也非常重要。当伺服器侦测到可疑的使用者Session 行为时,例如攻击者恶意尝试伪造Session ID、使用者Session 可能遭窃、或者逾时等情况,都应该立刻清除该Session ID 以免被攻击者利用。
Session 清除机制时机:
使用者帐号遭窃一直以来都是显著的问题,但却鲜少有网站针对Session的机制进行保护。攻击者可以轻松使用firesheep之类的工具窃取帐号。国外已经有不少网站侦测到Session可能遭窃时将帐号强制登出,但国内目前还鲜少网站实作此防御,设备商的Web管理介面更少针对Session进行保护。如果VPN Server等设备有侦测Session ID的伪造,在OpenSSL Heartbleed事件时就不会有那么惨重的损失了。
立刻把自己的网站加上Session 保护机制吧!
About Allen Own
翁浩正(Allen Own),具备多年骇客技术研究以及网路管理经验,担任学术及政府单位专任讲师及顾问。专长于网站应用程式安全、渗透测试、伺服器建置及开发、专业教育训练。