JWT(JSON Web Token)
从其名字就可以看出来,它具有表示身份的作用,其本质是将用户信息储存到一串json字符串中再将其编码得到一串token
JWT由三部分组成,分别是
Header,Payload,Signatrue
JWT=Base64(Header).Base64(Payload).加密函数(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)
例如:
Header部分
{
"kid":"4ff7ccb9-58a2-47de-8f91-cfc7582ebe41",
"alg":"RS256"
}
Payload部分
{
"iss":"portswigger",
"exp":1745253912,
"sub":"administrator"
}
Signature部分
#一大堆加密后的信息(签名)
u9e8ddhECxkGzuvGk9u78LcmBmLK4apCDh84l2BgYjauMcWkzSF2A9rqDEzqdBDiBMyHkUYeLiVF7Nu7km94PfMskQlIeVxuSF0MxI3a7I53mJ7woT3ypQm3Jw6VAOlqapLEC7VRa3Vfgv7H_dJpbFJkrHwE9KfW3TzdQeVAz-QKglJritq5WAPXP4oGAu5lSK8QUVECvUcnTYYzGS_TYYuOewbqgiq1w_dm5wn0M1LEYu1QM1fu7l8kOcDnkw7nMxeBM3iiZpAESvhd2myN_MCuIFFkC5OKghsWqIRehMKG3qR1X2YWnem04_ki6YMRA1jqEcvp5acH58rhGrDEyQ
1.JWT authentication bypass via unverified signature
本关要求我们进入管理员界面/admin并且删除用户carlos
我们访问admin,会发现提示只有administrator可以访问
那么我们登录wiener用户并且抓包,在放行了第一个包后第二个抓到的包就是我们所要的包
我们要去到管理员的/admin界面,就需要以管理员身份去访问
先登录到我们的账号wiener
这一步的目的是先让我们得到自己的cookie以查看jwt信息以让我们可以去分析其构成
再访问/admin界面,同时抓包
我们在burp里双击jwt的内容可以在inspector栏里看到对应的信息以及对应的解码结果,这里我们就查看payload信息,也就是第一个句点.后的内容,可以看到里面有个sub参数对应的值为wiener
我们将其修改为administrator后应用
再放行这个包会发现访问/admin成功,网站将我们认成了administrator
我们要删除carlos用户,执行删除操作也要以管理员的身份执行,具体方法和前面一样,抓包修改jwt信息为administrator
放行后成功过关
2.JWT authentication bypass via flawed signature verification
本关要求也和上一关一样要去/admin里删除carlos
但是本关还会校验jwt里的签名信息,所以单单修改用户名是没有用的,我们还是先登录wiener用户然后访问/admin再抓包
修改payload部分里的用户名为administrator
再修改header里的加密方式为none
修改为none后我们需要把jwt里的签名信息给删掉,但别把句点.也删了,不然jwt格式错误
随后放行,发现成功访问admin界面
删除carlos时也要重复前面一样的操作
放行后成功过关
3.JWT authentication bypass via weak signing key
本关要求也一样是删除carlos
同时将签名加密类型修改为none给过滤掉了,也就是不得不破解加密用的密钥了,并且本关也是提示弱签名,可以爆破
同样的步骤登录账号,访问/admin然后抓包,此时将jwt信息复制出来,使用hashcat工具破解
使用命令
hashcat -a 0 -m 16500 <jwt信息> <爆破字典>
得到密钥为secret1
于是前往json编辑网站JSON Web Tokens - jwt.io进行修改
将原有的jwt复制进去后修改decoded的内容,encoded的内容就是我们要的
将其替换原有的jwt
放行后成功绕过验证
再以一样的操作删除carlos用户
放行后成功过关
4.JWT authentication bypass via jwk header injection
本关也一样要求在/admin下删除carlos
并且本关也同样限制了none加密方式,同时加密很复杂很难爆破,那么根据本关题目提示,应该是通过修改jwt的header部分实现绕过,题目提示服务器支持jwk也就是JSON Web Key,它可以作为jwt里header的一部分,在这里用于数字签名身份验证
一下就是一串jwk结构(以RSA为例)
{"kty": "RSA", // 密钥类型(RSA/EC/oct)"alg": "RS256", // 算法(如 RS256、ES256、HS256)"kid": "2023-01", // 密钥唯一标识(用于轮换)"n": "Modulus...", // RSA 模数(Base64URL)"e": "AQAB", // RSA 公钥指数(通常为 65537)"d": "PrivateExponent", // 私钥参数(仅私钥包含)"p": "Prime1", // 私钥参数(仅私钥包含)"q": "Prime2", // 私钥参数(仅私钥包含)"use": "sig", // 用途(sig 签名/enc 加密)
}
如果服务器没有对用于验证的公钥做筛选(比如白名单),我们可以通过构造管理员的签名来欺骗服务器认为我们是administrator
一样我们先登录wiener,然后抓取前往/admin的包
我们这里要先安装一个burp插件叫做JWT editor
安装后我们抓的包会发现多了一栏选项叫做json web token也就是jwt
我们要构造jwk,就需要用到jwt editor来生成一个rsa密钥
进入jwt editor界面在右边选择new rsa key
选择类型为JWK,然后生成
随后我们要先修改我们的身份信息为administrator
然后在json web token栏内的攻击方式里选择Embedded JWK(嵌入式JWK)
注意要先修改身份信息在配置攻击方式,不然jwk验证出来会是修改之前的wiener
随后选择我们刚生成的rsa密钥,通过kid来选择
确认后可以看到我们的JWT信息已经被修改
随后放行,发现我们已经成功进入/admin了
然后删除carlos,也使用和前面一样的操作,密钥就不用重新生成了
注意要先修改身份信息再配置攻击模式
放行后成功过关