Web安全之攻击会话管理机制

HTTP协议本身是“无状态”,“无连接”的,也就是说HTTP协议本身并不会记住客户端访问的上下文,也无法保存客户端的各种状态,这其中就包括登录状态。如果HTTP不能保存用户的登录状态那就意味着用户在每次访问需要身份验证的网站时都必须填写用户名及密码,这里的“每次访问”是指每个单次的HTTP请求包括刷新一次页面。为了解决上述的问题Web应用程序就需要使用会话这个概念,即用户登录成功后为其建立一个会话,通过会话记录用户的各种状态,通常使用Cookie及Session实现会话机制。

Web安全之攻击会话管理机制_第1张图片

确定会话令牌

  • 多个数据共同表示一个会话令牌,包括Cookie,URL参数以及隐藏的表单参数
  • 标准的会话Cookie可能存在但是Web应用程序未对其进行使用
  • 观察用户登录前后客户端保存数据的变化,这些变化中包含了建立新会话的令牌
  • 通过删除客户端向服务器端发送的参数来进行判断,比如在删除了某个参数后无法正常访问用户的个人资料,那么这个参数应该与会话令牌有关

会话代替方案

  • HTTP认证:HTTP原生认证机制是通过HTTP头部参数来维持认证状态的,在用户认证成功后的每次请求中,HTTP均会携带用于认证的头部参数。
  • 无会话状态机制:一些应用程序不会发布会话令牌来管理用户与应用程序的交互状态,而是在每次请求中传输所有必要的数据(一般保存在Cookie或者隐藏表单字段中),由客户端管理状态,这种机制类似于 ASP.NET ViewState方式。

令牌使用情景

  • 发送到用户注册邮箱的密码恢复令牌
  • 防止CSRF的会话令牌
  • 用于一次性访问受保护资源的令牌
  • 未使用验证的购物应用程序的消费者用于检索现有订单状态的令牌

会话令牌生成过程中的缺陷

令牌有一定意义

结构化组成成分

  1. 账户用户名
  2. 账户数字标识
  3. 用户姓/名
  4. 电子邮箱
  5. 分组或角色
  6. 日期/时间戳
  7. 可预测数字
  8. 客户端IP

攻击思路:

  • 会话令牌可能由多个字段组成,不同字段之间使用特定字符进行分割,然而Web应用程序并不一定关注令牌中的每一个字段,我们可以使用Burpsuite中Intruder模块的Character frobber载荷逐个字符的修改令牌中的某一字段观察其是否对会话状态产生影响,如果不产生影响则可以在之后的分析过程中忽略此字段。
  • 结构化令牌中各个字段可能使用了不同的编码方式,为了获得原始的令牌内容有必要对每个字段的编码方式进行分析。
  • 对令牌进行分析,查找任何和用户名或者其他的用户可控数据有关的字段,接着尝试使用有规律的用户名及其他的用户可控的影响会话令牌因素的数据进行注册并观察令牌的差别。
  • 如果通过上述过程分析出了令牌的组成结构及编码方式接下来则通过伪造其他用户角色的令牌进行访问尝试,并记录状态。

令牌可预测

  • 隐含序列:有时我们并不能直接的通过观察令牌来发现其隐含的序列或者规律,我们可以通过对令牌进行解码然后发挥想象力通过各种运算或者操作来发现解密后令牌中所蕴含的规律或者隐含的序列。
  • 时间依赖:一些Web服务器和应用程序使用时间来参与令牌的生成。如果使用时间生成令牌的算法没有合并足够的熵攻击者就可能推测出其他用户的令牌。比如本书的作者在对某一个网上零售店的Web应用程序进行测试是,发现如下的令牌序列:
3124538-1172764258718
3124539-1172764259062
3124540-1172764259281
3124541-1172764259734
3124542-1172764260046
3124543-1172764260156
3124544-1172764260296
3124545-1172764260421
3124546-1172764260812
3124547-1172764260890

通过上述序列可以发现“-”将令牌分割为两个字段,第一个字段是连续值,第二个字段是递增的但是每次递增的值不相同,随后攻击者在几分钟后在一次的收集了一批令牌,序列如下所示:

3124553-1172764800468
3124554-1172764800609
3124555-1172764801109
3124556-1172764801406
3124557-1172764801703
3124558-1172764802125
3124559-1172764802500
3124560-1172764802656
3124561-1172764803125
3124562-1172764803562

通过比对这一批序列中的第一个令牌及上一批序列中的最后一个令牌可以发现,两个序列的第一个值相差了5,第二个值相差了539578,为此可以推测出令牌的生成大概与时间有关,第一个值大概是分配给每一个用户的递增ID第二个值应该是时间并且为毫秒表示。随后作者在对这款应用进行审计时证明了这一观点:

String sessId = Interger.toString(s_SessionIndex++)+"-"+System.currentTimeMillis();

为此对于作者收集令牌间隔中的那五个用户(因为第一个字段增加了5),可以通过暴破第二个字段来实现因为我们已经有了第二个字段的范围(1172764260890-1172764800468),使用Burpsuite提供的Intruder模块中的Numbers有效载荷可以轻松的实现上述暴破。

  • 生成数字的随机性不强:计算机生成的随机数都是伪随机数,如果伪随机数的算法强度较弱那么生成随机数很可能被预测。
  • 令牌加密函数对外开放或暴露:如果攻击者可以接触到会话令牌生成函数的源码、算法过程或者相应加密过程的入口(即攻击者可以通过此入口获得任何数据经过和令牌相同的加密方式后的数据)那么攻击者就可以详细的了解令牌生成的过程从而模仿此过程对令牌进行伪造。
  • Burpsuite提供了Sequence模块用来预测令牌的随机性。在进行预测时尽量多的收集令牌数量,500条起步。

加密令牌

通过动态修改与令牌生成相关的字段,比如用户名等查看令牌是否会出现以8或16位的整数倍增长的情况,如果存在则则极有可能使用了分组密码加密算法加密此时可以尝试常见的攻击手段。

会话令牌整个生命周期内的处理

在网络上泄露令牌

  • 应用程序在登录阶段那使用HTTPS但是登录成功后转为使用HTTP或者可以访问验证前使用HTTP的链接,这样尽管保护了用户的证书却保护不了用户的会话令牌
  • 用户在首次访问某一网站时使用HTTP协议,往往此时服务器已经给客户端发布了会话令牌,当用户进行登录时即使网站转换使用HTTPS那么在令牌不改变的情况下原先处于暴露环境中的令牌此刻升级为具有通过验证的令牌。
  • 如果登录界面允许使用HTTP协议登录那么攻击者可以通过各种方式使用户在登录时使用HTTP协议。
  • 在用户使用HTTPS协议登录后如果网页在加载像图片等静态资源时使用的是HTTP协议用户的会话令牌还是可以通过此泄露

渗透测试:

  • 注意访问网页的各个阶段HTTP与HTTPS之间的转换以及新令牌发布的时机
  • 如果使用Cookie来传送会话令牌应该确认是否设置了secure标记
  • 寻找应用程序中使用非加密连接传输会话令牌的情况
  • 观察应用程序是否在用户登录成功后发布新的令牌
  • 观察服务器是否开启80端口,查看HTTPS协议下的会话令牌是否在访问80端口时也进行传输
  • 观察通过HTTP传输的HTTPS协议下创建的会话令牌是否仍然有效。

在日志中泄露令牌

  • 协助网络管理人员的系统日志如果记录了最近的会话日志且未对访问控制进行严格管理那么在此种情况下攻击者可能通过日志获得登录会话
  • 如果应用程序将会话置于URL中那么这些会话会被记录在:
    • 用户浏览器的日志中
    • Web服务器日志
    • 企业或ISP代理服务器日志
    • 反向代理服务器日志
    • 任何站外服务器的Referer(最危险的方式)

渗透:

  • 查明相关日志及访问权限
  • 寻找通过URL传输令牌的情况

会话令牌与会话的映射易受到攻击

  • 允许并行登录
  • 使用静态令牌即一个用户令牌发布后不再改变

会话终止易受攻击

必要性:

  • 尽可能缩短一个会话的寿命可以降低攻击者截获、猜测或滥用有效会话令牌的可能性
  • 终止会话为用户提供了一种使会话失效的途径

然而先用的应用程序并没有提供真实的会话终止功能,这样即使用户选择退出后其Cookie还可以用来在此登录知道服务器端彻底删除会话相关的信息。在客户端执行的任何操作都不会实际意义上终止会话。

客户端暴露在令牌劫持风险中

网站存在如下攻击容易造成会话令牌被劫持

  • XSS
  • CSRF
  • 会话固定
    • 认证前就发布令牌
    • 认证后获得的会话令牌可重新用于其他用户认证
    • 应用程序接受伪造令牌

宽泛的cookie范围

  • 域名
    • 向下匹配
    • 不依赖于端口和协议
  • 路径
    • 向下匹配
    • 路径不闭合以前缀匹配,比如“/login”还可以匹配“/loginest”

JWT攻击

JWT全称叫 JSON Web Token,现代 web 应用中替代 cookie 表示用户身份凭证的载体,如果后台对JWT处理不当可能造成垂直越权攻击。JWT由三段base64编码通过‘.’连接组成其中每部分含义如下(以Zoomeye API认证token为例):

  • 第一段用于设置校验算法:
'{"alg":"HS256","typ":"JWT"}'
  • 第二段存储会话识别信息,后台主要根据这一部分来对用户身份进行判断:
'{"identity":"邮箱","iat":1567854256,"nbf":1567144456,"exp":1564887352}'
  • 第三段是JWT签名是对信息头和数据两部分结合密钥进行哈希而得,服务端通过签名来确保数据的完整性和有效性:
'9lfJfa-Dm7SikeoyDmld5YWfrvCSa8RCnChNEYY_ApQ'

针对于JWT的攻击主要有以下几点:

  • 未校验签名:直接更改第二部分,第三部分不变,碰碰运气,如果后台没有对JWT第三段进行处理则可以达到越权的目的
  • 禁用哈希:直接将第一部分中的alg关键字改为none,然后修改第二部分观察是否生效(需要注意的是有些JWT大小写敏感可尝试将none替换为NoneNONE等)
  • 暴破弱密钥:对第三部分使用的密钥进行暴破,可以使用此工具

可以使用python的JWT模块pyjwt来实现对JWT的操作。

参考: 全程带阻:记一次授权网络攻防演练(上)

你可能感兴趣的:(Web安全,会话管理,token,会话令牌,XSS,会话)