zoukankan      html  css  js  c++  java
  • 浅谈JWT安全问题

    写在前头,总结向笔记类文章,内容有些不是我自己的,详情见参考资料
    0x00 什么是JWT
     
    JWT全称为: json  web token 
    JWT通常用于实现前端和后端的解耦,同时,它还可以与Restful API一起使用,用于构建身份验证机制
     
    0x01 JWT的格式

    JWT的数据分为三部分:头部,有效载荷,签名(图来自freebuf一篇文章,具体找不到了)

    通过base64编码起来
    使用点号进行划分,比如一个JWT如:
    eyJraWQiOiJrZXlzLzNjM2MyZWExYzNmMTEzZjY0OWRjOTM4OWRkNzFiODUxIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJkdWJoZTEyMyJ9.XicP4pq_WIF2bAVtPmAlWIvAUad_eeBhDOQe2MXwHrE8a7930LlfQq1lFqBs0wLMhht6Z9BQXBRos9jvQ7eumEUFWFYKRZfu9POTOEE79wxNwTxGdHc5VidvrwiytkRMtGKIyhbv68duFPI68Qnzh0z0M7t5LkEDvNivfOrxdxwb7IQsAuenKzF67Z6UArbZE8odNZAA9IYaWHeh1b4OUG0OPM3saXYSG-Q1R5X_5nlWogHHYwy2kD9v4nk1BaQ5kHJIl8B3Nc77gVIIVvzI9N_klPcX5xsuw9SsUfr9d99kaKyMUSXxeiZVM-7os_dw3ttz2f-TJSNI0DYprHHLFw
    

    1,头部

    eyJraWQiOiJrZXlzLzNjM2MyZWExYzNmMTEzZjY0OWRjOTM4OWRkNzFiODUxIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ
    

    解码为:

    {“kid”:”keys/3c3c2ea1c3f113f649dc9389dd71b851",”typ”:”JWT”,”alg”:”RS256"}
    

    包括了typ类型,alg:签名算法

    2,有效载荷

    eyJzdWIiOiJkdWJoZTEyMyJ9
    

    有效载荷用来存储用户的数据,解码之后为

    {"sub":"dubhe123"}
    

    3,签名

    XicP4pq_WIF2bAVtPmAlWIvAUad_eeBhDOQe2MXwHrE8a7930LlfQq1lFqBs0wLMhht6Z9BQXBRos9jvQ7eumEUFWFYKRZfu9POTOEE79wxNwTxGdHc5VidvrwiytkRMtGKIyhbv68duFPI68Qnzh0z0M7t5LkEDvNivfOrxdxwb7IQsAuenKzF67Z6UArbZE8odNZAA9IYaWHeh1b4OUG0OPM3saXYSG-Q1R5X_5nlWogHHYwy2kD9v4nk1BaQ5kHJIl8B3Nc77gVIIVvzI9N_klPcX5xsuw9SsUfr9d99kaKyMUSXxeiZVM-7os_dw3ttz2f-TJSNI0DYprHHLFw
    
    由于头部和有效载荷以明文形式存储,因此,需要使用签名来防止数据被篡改。
    提供数据的相关函数使用的签名算法通常是RS256(RSA非对称加密和私钥签名)和HS256(HMAC SHA256对称加密)算法。
    如使用HS256的加密方式为:
    HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret)
    

    0X02 如何攻击JWT

    1,敏感信息泄露
    因为有效载荷是明文传输的,如果有效载荷存在敏感信息的话就会发生信息泄露
     
     
    2,将签名算法改为none
    使用工具: JWTPyCrack
    python jwtcrack.py -m generate -s {"admin":"True"}
    

    3,未校验签名

    直接替换数据,使用https://jwt.io/#debugger
    插入一些常见测试payload,如注入,xss等
     
    4,爆破弱key
    使用工具:JWTPyCrack ,只支持明文,有些时候可能还要考虑base64encode的情况,base64的情况,要自己编写脚本
    python jwtcrack.py -m blasting -s eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU --kf 2.txt
    除此之外,我们也可以用hashcat来爆破
    爆破hahs少不了一个好的字典,而hashcat rules文件夹下其实有不少规则,我们也可以直接拿来用,生成字典:(b0b064.rule来源于Hob0Rules)
    hashcat64.exe --stdout password.txt -r rules/hob064.rule -o pasword_new.txt --force
    

    不想生成文件占磁盘,也可以直接用规则来爆破

    hashcat64.exe -a 0 -m 16500 jwt_token jwt_key.txt -r rules/d3ad0ne.rule --force
    

    当然也可以用掩码方式,爆破出来的时间取决于key的长度和GPU的性能

    0x03 拓展:accessToken与refreshToken问题

    风险点:
    未校验access token和refresh token是否属于同一个用户,导致A用户可使用自己的refresh token去刷新B用户的access token,垂直越权
    建议:
    使用jwt令牌的最佳位置是服务器之间的通信。在普通的web应用程序中,最好使用普通的旧cookies。 
     
    例子:
    webgoat 8 ,使用A账号的refresh token 和 过期B的access_token去刷新 B的access_token
     
    0x04 实战记录
    1,开源程序默认key未修改

    某众测厂商默认key直接伪造超级管理员进去

     github标志,开源系统直接跟过去

     有默认值,虽然作者再三提醒,但鉴于人的本质惰性,相信很多管理员都是不会去修改的,直接伪造超级管理员进去

     2,accessToken与refreshToken问题

    某厂商可用A用户refreshToken刷新B用户的access_token
    假如获取到B用户的过期access_token,那么就可以用A的refresh_token去刷新了
    B用户的access_token与refresh_token
     

     使用A用户的refresh_token去刷新B用户的access_token

     正常B用户的请求

     替换之后的请求,成功请求

    这里过期的access_token可以在搜索引擎搜到或者评论等信息泄漏

    0x05 总结

    简单列举了一下自己遇到的jwt两个案例,笔记向文章没啥好说的。

    0x06 参考资料

  • 相关阅读:
    7-感觉身体被掏空,但还是要学Pandas(下)
    6-感觉身体被掏空,但还是要学Pandas(上)
    5-Numpy似双丝网,中有千千结(下)
    4-Numpy似双丝网,中有千千结(上)
    3-上帝说要有光,于是就有了Python(下)
    2-上帝说要有光,于是就有了Python(上)
    1-在IPython Notebook中愉快地使用python编程
    第11组 Alpha冲刺(2/6)
    第11组 Alpha冲刺(1/6)
    2019 SDN上机第2次作业
  • 原文地址:https://www.cnblogs.com/r00tuser/p/12513046.html
Copyright © 2011-2022 走看看