Session攻击

1、认证和授权

        很多时候,人们会把“认证”和“授权”两个概念搞混,实际上“认证”和“授权”是两件事情,认证的英文是Authentication,授权则是Authorization。分清楚这两个概念其实很简单,只需要记住:认证的目的是为了认出用户是谁,而授权的目的是为了决定用户能够做什么。

        形象地说,假设系统是一间屋子,持有钥匙的人可以开门进入屋子,那么屋子就是通过“锁和钥匙的匹配”来进行认证的,认证的过程就是开锁的过程。钥匙在认证过程中,被称为“凭证”(Credential),开门的过程,在互联网里对应的是登录(Login)。可是开门之后,什么事情能做,什么事情不能做,就是“授权”的管辖范围了。

        如果进来的是屋子的主人,那么他可以坐在沙发上看电视,也可以进到卧室睡觉,可以做任何他想做的事情,因为他具有屋子的“最高权限”。可如果进来的是客人,那么可能就仅仅被允许坐在沙发上看电视,而不允许其进入卧室了。

        “能否进入卧室”这个权限被授予的前提,是需要识别出来者到底是主人还是客人,所以如何授权是取决于认证的。现在问题来了,持有钥匙的人,真的就是主人吗?如果主人把钥匙弄丢了,或者有人造了把一模一样的钥匙,那也能把门打开,进入到屋子里。这些异常情况,就是因为认证出现了问题,系统的安全直接受到了威胁。钥匙仅仅是一个很脆弱的凭证,其他诸如指纹、虹膜、人脸、声音等生物特征也能够作为识别一个人的凭证。认证实际上就是一个验证凭证的过程。

        如果只有一个凭证被用于认证,则称为“单因素认证”;如果有两个或多个凭证被用于认证,则称为“双因素(Two Factors)认证”或“多因素认证”。一般来说,多因素认证的强度要高于单因素认证,但是在用户体验上,多因素认证或多或少都会带来一些不方便的地方。

2、Session与认证

        密码与证书等认证手段,一般仅仅用于登录(Login)的过程。当登录完成后,用户访问网站的页面,不可能每次浏览器请求页面时都再使用密码认证一次。因此,当认证成功后,就需要替换一个对用户透明的凭证。这个凭证,就是SessionID。

        当用户登录完成后,在服务器端就会创建一个新的会话(Session),会话中会保存用户的状态和相关信息。服务器端维护所有在线用户的Session,此时的认证,只需要知道是哪个用户在浏览当前的页面即可。为了告诉服务器应该使用哪一个Session,浏览器需要把当前用户持有的SessionID告知服务器。最常见的做法就是把SessionID加密后保存在Cookie中,因为Cookie会随着HTTP请求头发送,且受到浏览器同源策略的保护。

        Cookie中保存的SessionlD,SessionID一旦在生命周期内被窃取,就等同于账户失窃。同时由于SessionID是用户登录之后才持有的认证凭证,因此黑客不需要再攻击登录过程(比如密码),在设计安全方案时需要意识到这一点。

3、会话(Session)劫持

        会话劫持(Session hijacking)就是一种通过窃取用户SessionID后,使用该SessionID登录进目标账户的攻击方法,此时攻击者实际上是使用了目标账户的有效Session。如果SessionID是保存在Cookie中的,则这种攻击可以称为Cookie劫持。

攻击步骤:

  1. 目标用户需要先登录站点;
  2. 登录成功后,该用户会得到站点提供的一个会话标识SessionID;
  3. 攻击者通过某种攻击手段捕获Session ID;
  4. 攻击者通过捕获到的Session ID访问站点即可获得目标用户合法会话。

攻击者获取SessionID的方式有多种:

  1. 暴力破解:尝试各种Session ID,直到破解为止;
  2. 预测:如果Session ID使用非随机的方式产生,那么就有可能计算出来;
  3. 窃取:使用网络嗅探、本地木马窃取、XSS攻击等方法获得。 

防御方法:

1、Cookie HttpOnly。通过设置Cookie的HttpOnly为true,可以防止客户端脚本访问这个Cookie,从而有效的防止XSS攻击。

response.setHeader("Set-Cookie","user="+request.getParameter("cookie")+";HttpOnly");

SessionCookieConfig接口,用于操作会话Cookie,在ServletContextListener监听器初始化方法中进行设定即可

@WebListener
public class SessionCookieInitialization implements ServletContextListener {
    private static final Log log = LogFactory.getLog(SessionCookieInitialization.class);
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext = sce.getServletContext();
        SessionCookieConfig sessionCookie = servletContext.getSessionCookieConfig();
        //设置HttpOnly
        sessionCookie.setHttpOnly(true);
    }
    public void contextDestroyed(ServletContextEvent sce) {
    }
}

2、Cookie Secure,是设置 COOKIE 时,可以设置的一个属性,设置了这个属性后,只有在 https 访问时,浏览器才会发送该 COOKIE。浏览器默认只要使用http 请求一个站点,就会发送明文 cookie,如果网络中有监控,可能被截获。如果 web 应用网站全站是 https 的,可以设置 cookie 加上 Secure 属性,这样浏览器就只会在 https 访问时,发送 cookie。攻击者即使窃听网络,也无法获取用户明文 cookie

response.setHeader("Set-Cookie"," user="+request.getParameter("cookie")+";HttpOnly;Secure");

或者

@WebListener
public class SessionCookieInitialization implements ServletContextListener {
    private static final Log log = LogFactory.getLog(SessionCookieInitialization.class);

    public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext = sce.getServletContext();
        SessionCookieConfig sessionCookie = servletContext.getSessionCookieConfig();
        // 设置HttpOnly
        sessionCookie.setHttpOnly(true);
        sessionCookie.setSecure(true);
    }

    public void contextDestroyed(ServletContextEvent sce) {
    }
}

4、会话固定(Session fixation)

        会话固定(Session fixation)是一种诱骗受害者使用攻击者指定的会话标识(SessionID)的攻击手段。这是攻击者获取合法会话标识的最简单的方法。让合法用户使用黑客预先设置的sessionID进行登录,从而是Web不再进行生成新的sessionID,从而导致黑客设置的sessionId变成了合法桥梁。

        会话固定也可以看成是会话劫持的一种类型,原因是会话固定的攻击的主要目的同样是获得目标用户的合法会话,不过会话固定还可以是强迫受害者使用攻击者设定的一个有效会话,以此来获得用户的敏感信息。

        什么是Session Fixation呢?举一个形象的例子,假设A有一辆汽车,A把汽车卖给了B,但是A并没有把所有的车钥匙交给B,还自己藏下了一把。这时候如果B没有给车换锁的话,A仍然是可以用藏下的钥匙使用汽车的。这个没有换“锁”而导致的安全问题,就是Session Fixation问题。

攻击步骤:

  1. 攻击者通过某种手段重置目标用户的SessionID,然后监听用户会话状态;
  2. 目标用户携带攻击者设定的Session ID登录站点;
  3. 攻击者通过Session ID获得合法会话

攻击者如何才能让目标用户使用这个SessionID呢?如果SessionID保存在Cookie中,比较难做到这一点。但若是SessionID保存在URL中,则攻击者只需要诱使目标用户打开这个URL即可。 

防御方法:【多个方法结合使用】

1、每当用户登陆的时候就进行重置sessionID

// 会话失效
session.invalidate();
// 会话重建
session=request.getSession(true);

2、sessionID闲置过久时,进行重置sessionID

3、 禁用客户端访问Cookie,设置HttpOnly

5、Session保持攻击

        一般来说,Session是有生命周期的,当用户长时间未活动后,或者用户点击退出后,服务器将销毁Session。Session如果一直未能失效,会导致什么问题呢?前面的章节提到session劫持攻击,是攻击者窃取了用户的SessionID,从而能够登录进用户的账户。

        但如果攻击者能一直持有一个有效的Session(比如间隔性地刷新页面’以告诉服务器这个用户仍然在活动),而服务器对于活动的Session也一直不销毁的话,攻击者就能通过此有效Session—直使用用户的账户,成为一个永久的‘后门。

但是Cookie有失效时间,Session也可能会过期,攻击者能永久地持有这个Session吗?

        一般的应用都会给session设置一个失效时间,当到达失效时间后,Session将被销毁。但有一些系统,出于用户体验的考虑,只要这个用户还“活着”,就不会让这个用户的Session失效。从而攻击者可以通过不停地发起访问请求,让Session一直“活”下去。

保持session长时间存活:

<script>
    //要保持session的url
    var url = "http://bbs.yuanjing.com/wap/index.php?/sid=LOXSAJH4M";
    //定时任务
    window.setInterval("keeyId()",6000);
    function keepsid(){
        document.getElementById("iframe1").src=url+"&time"+Math.random();
    }
</script>
<iframe id="iframe1" src=""/></iframe>

Cookie永不过期:

anehta.dom.persistCookie = function (cookieName){
        if(anehta.dom.checkCookie(cookieName)==false){
           return false;
        }
        try{
           document.cookie =  cookieName + "=" + anehta.dom.getCookie(cookieName)+";" + "expires=Thu, 01-Jan-2038 00:00:01 GMT;";
        } catch( e){
            return false;
        }
           return true;
    }

攻击者甚至可以为Session Cookie增加一个Expire时间,使得原本浏览器关闭就会失效的Cookie持久化地保存在本地,变成一个第三方Cookie(third-partycookie)。

防护方案:
        常见的做法是在一定时间后,强制销毁Session。这个时间可以是从用户登录的时间算起,设定一个阈值,比如3天后就强制Session过期。

        但强制销毁Session可能会影响到一些正常的用户,还可以选择的方法是当用户客户端发生变化时,要求用户重新登录。比如用户的IP、UserAgent等信息发生了变化,就可以强制销毁当前的Session,并要求用户重新登录。

        最后,还需要考虑的是同一用户可以同时拥有几个有效Session。若每个用户只允许拥有一个Session,则攻击者想要一直保持一个Session也是不太可能的。当用户再次登录时,攻击者所保持的Session将被“踢出”。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悠然予夏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值