Fork me on GitHub

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.题解

 打开时候发现是个登录框,先抓个包看看吧~
 
 
 
 
我们看到Responsetoken是这个样子的:
 
 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
 
 
 
 
 
posted @ 2020-11-27 15:34  0yst3r  阅读(2294)  评论(6编辑  收藏  举报
返回顶部