freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

高级漏洞篇之JWT攻击专题
NaTsUk0 2023-08-19 02:24:10 522317

今天又是新知识啊,嘎嘎新哦,好多师傅都遇到过JWT的站点,但是都是三板斧,而且有的还抡不明白,今天我们就把它们抡明白吧!!!

声明

该系列共三篇,26个专题(截止2023.8.10),其中有21个专题的大部分内容已于2021年7-9月首发于安全客,由于某些原因,该系列后续更新部分梨子打算转投Freebuf社区(下称"社区")。因后续更新部分的部分内容为这21个专题中的,故在转投社区时会将更新部分一并加入对应的专题中,所以会与发布于安全客的版本略有出入,会更完整,望周知。
注:本篇为Freebuf首发

本系列介绍

PortSwigger是信息安全从业者必备工具burpsuite的发行商,作为网络空间安全的领导者,他们为信息安全初学者提供了一个在线的网络安全学院(也称练兵场),在讲解相关漏洞的同时还配套了相关的在线靶场供初学者练习,本系列旨在以梨子这个初学者视角出发对学习该学院内容及靶场练习进行全程记录并为其他初学者提供学习参考,希望能对初学者们有所帮助。

梨子有话说

梨子也算是Web安全初学者,所以本系列文章中难免出现各种各样的低级错误,还请各位见谅,梨子创作本系列文章的初衷是觉得现在大部分的材料对漏洞原理的讲解都是模棱两可的,很多初学者看了很久依然是一知半解的,故希望本系列能够帮助初学者快速地掌握漏洞原理。

高级漏洞篇介绍

相对于服务器端漏洞篇和客户端漏洞篇,高级漏洞篇需要更深入的知识以及更复杂的利用手段,该篇也是梨子的全程学习记录,力求把漏洞原理及利用等讲的通俗易懂。

什么是JWT?

JSON Web Tokn(JWT)是一种标准化格式,用于在系统之间发送加密签名的JSON数据。它们理论上可以包含任何类型的数据,但最常用于发送有关用户的信息(“声明”),作为身份验证、会话处理和访问控制机制的一部分。
与经典会话token不同,服务器需要的所有数据都存储在客户端,也就是JWT本体中。这使得JWT成为高度分布式网站的热门选择,在这些网站中,用户需要与多个后端服务器无缝交互。

JWT格式

JWT由3部分组成:头、payload和签名。它们各自用.分隔,如以下示例所示:
image.png
JWT的头和payload部分只是base64url编码的JSON对象。头包含有关token本身的元数据,而payload包含有关用户的实际“声明”。例如,我们可以从上面的token中解码payload以揭示以下声明:

{
    "iss": "portswigger",
    "exp": 1648037164,
    "name": "Carlos Montoya",
    "sub": "carlos",
    "role": "blog_author",
    "email": "carlos@carlos-montoya.net",
    "iat": 1516239022
}

在大多数情况下,任何有权访问token的人都可以轻松读取或修改此数据。因此,任何基于JWT的机制的安全性都严重依赖于加密签名。

JWT签名

颁发token的服务器通常通过对头和payload做hash来生成签名。在某些情况下,他们还会加密生成的哈希值。无论哪种方式,此过程都涉及私密签名密钥。此机制为服务器提供了一种方法来验证token中的任何数据自发布以来均未被篡改:

  • 由于签名直接源自token的其余部分,因此更改头或payload的单个字节会导致签名不匹配。

  • 在不知道服务器的私密签名密钥的情况下,不可能为给定的头或payload生成正确的签名。

JWT vs JWS vs JWE

JWT规范实际上非常有限。它只定义了一种格式,用于将信息(“声明”)表示为可以在两方之间传输的JSON对象。实际上,JWT并不是真正用作独立实体。JWT规范由JSON Web Signature(JWS)和JSON Web Encryption(JWE)规范扩展,它们定义了实际实现JWT的具体方法。
image.png
换句话说,JWT通常是JWS或JWE token。当人们使用术语“JWT”时,他们几乎总是指JWS token。JWE非常相似,只是token的实际内容是加密的,而不仅仅是编码的。后面文中的JWT多指JWS,即使某些漏洞确实也适用于JWE。

什么是JWT攻击?

JWT攻击涉及用户将修改后的JWT发送到服务器以实现恶意目标。通常,此目标是通过模拟另一个已经过身份验证的用户来绕过身份验证和访问控制。

JWT攻击的影响是什么?

JWT攻击的影响通常很严重。如果攻击者能够使用任意值创建自己的有效token,他们可能会提升自己的权限或冒充其他用户,从而完全控制他们的帐户。

JWT攻击的漏洞是如何产生的?

JWT漏洞通常是由于应用程序本身的JWT处理有缺陷而引起的。与JWT相关的各种规范在设计上相对灵活,允许网站开发人员自行决定许多实现细节。这可能会导致他们意外地引入漏洞,即使是在使用久经沙场的库时也是如此。
这些实施缺陷通常意味着JWT的签名未正确验证。这使攻击者能够篡改通过token的payload传递给应用程序的值。即使签名得到了可靠的验证,它是否真正可信在很大程度上取决于服务器的私密密钥是否保密。如果此密钥以某种方式泄露,或者可以被猜测或暴力破解,则攻击者可以为任意token生成有效签名,从而破坏整个机制。

利用有缺陷的JWT签名验证

按照设计,服务器通常不会存储有关它们发出的JWT的任何信息。相反,每个token都是一个完全独立的实体。这有几个优点,但也引入了一个基本问题 - 服务器实际上不知道tokne的原始内容,甚至不知道原始签名是什么。因此,如果服务器没有正确验证签名,就无法阻止攻击者对token的其余部分进行任意更改。
例如,考虑包含以下声明的JWT:

{
    "username": "carlos",
    "isAdmin": false
}

如果服务器根据此用户名识别会话,则修改其值可能使攻击者能够冒充其他登录用户。同样,如果isAdmin值用于访问控制,这可以为权限升级提供一个简单的向量。\

接受任意签名

JWT库通常提供一种方法用来验证token,另一种方法只是用来解码它们。例如,Node.js库jsonwebtoken就有verify()和decode()两种方法。
有时,开发人员会混淆这两种方法,只将传入的token传递给decode()方法。这实际上意味着应用程序根本不验证签名。

配套靶场:通过未经验证的签名绕过JWT身份验证

显而易见的,这道题使用了JWT机制,但是它有缺陷,它不会校验签名,所以我们可以篡改身份。目标就是篡改成管理员然后删除倒霉蛋carlos用户,应该很简单,抓个包先。
image.png
然后我们拿到jwt.io解一下。
image.png
然后我们直接拿到Inspector解码,该说不说,新版burp是真的超级舒服啊,越来越爱burp了。
image.png
然后我们直接在这里改就可以!是不是超级方便!然后我们路径改成/admin
image.png
Burp真的太方便了!然后我们就删除carlos呗,解题成功!
image.png

接受没有签名的token

除其他事项外,JWT头包含一个alg参数。这告诉服务器使用哪种算法对token进行签名,并且想当然地,它在验证签名时就会使用哪种算法:

{
    "alg": "HS256",
    "typ": "JWT"
}

这在本质上是有缺陷的,因为服务器别无选择,只能隐含地信任来自token的用户可控输入,此时,token根本没有经过验证。换句话说,攻击者可以直接影响服务器检查token是否可信的方式。
JWT可以使用一系列不同的算法进行签名,但也可以不签名。在这种情况下,alg参数设置为 none,表示所谓的“不安全的JWT”。由于这样做的明显危险,服务器通常会拒绝没有签名的token。但是,由于这种过滤依赖于字符串解析,我们有时可以使用经典的混淆技术绕过这些过滤器,例如混合大小写和奇葩编码。
这里要注意,即使无签名,那JWT也要以.结尾。

配套靶场:过有缺陷的签名验证绕过JWT身份验证

上面讲的是无签名,目标还是那个目标,那我们就开搞。
image.png
这里我们把算法改成none,并且把JWT的第三个部分即签名的部分删掉,主要要留着最后的.,然后再改用户名。
image.png
然后就成功删除倒霉蛋carlos,解题成功!
image.png

爆破密钥

一些签名算法,例如HS256(HMAC+SHA-256),使用任意的独立字符串作为密钥。就像密码一样,重要的是这个密钥不能轻易被攻击者猜到或暴力破解。不然,他们可能能够使用他们喜欢的任何头和payload值创建JWT,然后使用密钥重新签署具有有效签名的token。
在实施JWT应用程序时,开发人员有时会犯错误,例如忘记更改默认或占位密钥。他们甚至可能复制并粘贴他们在网上找到的代码片段,然后忘记更改作为示例提供的硬编码密钥。在这种情况下,攻击者使用常见密钥字典来暴力破解服务器的密钥可能是小菜一碟。

使用hashcat爆破密钥

我们可以搭配上面讲的那个字典使用hashcat爆破我们想要爆破的JWT。例如这样:

hashcat -a 0 -m 16500 <jwt> <wordlist>

Hashcat使用单词列表中的每个秘密对来自JWT的标头和有效负载进行签名,然后将生成的签名与来自服务器的原始签名进行比较。Hashcat使用字典中的每个密钥对来自JWT的标和payload进行签名,然后将生成的签名与来自服务器的原始签名进行比较。如果任何签名匹配,hashcat将以下列格式输出已识别的密钥,以及各种其他详细信息:

<jwt>:<已识别的密钥>

由于hashcat在我们的机器上本地运行并且不依赖于向服务器发送请求,因此这个过程非常快,即使在使用庞大的单词列表时也是如此。
确定密钥后,我们可以使用它定制JWT头和payload同时生成有效签名。
如果服务器使用了一个非常弱的密钥,甚至可以逐个字符地暴力破解,而不是使用字典。

配套靶场:通过弱签名密钥绕过JWT身份验证

这道题就是要利用上面提供的字典爆破出生成签名的密钥,然后重新生成签名。梨子费了九牛二虎之力才发现在ubuntu上装hashcat成功率很高,装好以后我们执行这样的命令去爆破:

hashcat -a 0 -m 16500 [JWT] [字典路径]

image.png
我们跑出来密钥是secret1,现在我们可以重新生成签名了,这里我们需要安装一个burp插件 - JWT Editor,然后我们点击那个"New Symmetric Key",直接点Generate,密钥大小不用管,它会自动更新,然后我们把secret1base64编码以后贴到k值的位置。
image.png
然后我们来到repeater,把该改的地方都先改完,然后点击标签JSON Web Token,好家伙,梨子的burp变异啦!然后点击sign,选择Don't modify header,好方便啊,直接重新签名完了,然后我们就可以又一次删除倒霉蛋carlos了,解题成功!太好玩了吧!
image.png

JWT头参数注入

根据JWS规范,

可试读前40%内容
¥ 9.9 全文查看
9.9元开通FVIP会员
畅读付费文章
最低0.3元/天
# burpsuite # web安全 # JWT
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 NaTsUk0 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
梨子去上PortSwigger网络安全学院系列
NaTsUk0 LV.5
一个可爱的老实人
  • 31 文章数
  • 175 关注者
服务器端漏洞篇 | Web缓存欺骗专题
2024-09-10
高级漏洞篇 | Web大语言模型攻击专题
2024-09-10
服务器端漏洞篇 | API测试专题
2024-09-10
文章目录