Broken Authentication
Authentication Bypasses 绕过认证
题2: 密码重置
前面介绍了通过删除验证回答字段的方式来绕过认证的一个案例。下面题目就是要你绕过验证问题
解:
- 获取请求信息后发送到 repeater ,把两个提问的字段和值都删掉,发送请求,返回未成功
{ "feedback" : "Not quite, please try again."}
- 看样照搬例子中的方法不行,尝试了很多次之后,才发现修改字段名序号之后的字符后,提交可以成功
再尝试几次后发现只要保留了secQuestion,前后怎么填都可以。猜想应该是使用了contains匹配来验证字段的有效性的
JWT tokens
题3: Decoding a JWT token
解: 很简单 用base64反编码即可,得到用户名为 user
题5: JWT signing
尝试更改您收到的令牌,并通过更改令牌成为管理员用户并重置投票
解:
这里主要是体验JWT攻击的几种方式。 JWT攻击参考资料
- 随便选择一个用户,点一下右边的回收站按钮(重置)。获得重置请求的链接。发送到repeater
- 先尝试第一种攻击方式(重置空加密算法), 把请求包中的 token信息复制出来
eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2ODI5MDkxNDksImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiU3lsdmVzdGVyIn0.OgOt7bHkJPszjqJpt4RqUt9iHZXcC79xzZiPC5h0yUEZSdvNP7jQtN4BTLOyaB6spatuI-otQ-UbcnMY2iNnAw;
反编码第一段的header和第二段的claims获得# header {"alg":"HS512"} # claims {"iat":1682909149,"admin":"false","user":"Sylvester"}
把 alg的值改为 none , admin的值改为 true
分别用 Base64Urlencode方法对其进行编码import java.util.Base64; String text = "{\"iat\":1682909149,\"admin\":\"true\",\"user\":\"Sylvester\"}"; byte[] encoded = Base64.getUrlEncoder().encode(text.getBytes(StandardCharsets.UTF_8)); String encodedText = new String(encoded, StandardCharsets.UTF_8);
Base64Urlencode : Base64 URL编码是Base64编码算法的修改版本,用于以URL安全的格式对二进制数据进行编码。它与标准Base64编码非常相似,但用于填充的最后两个字符有所不同。它不使用+和/字符,而是分别使用-和_字符。这是因为在某些上下文中,例如在url中,标准Base64编码可能不是url安全的,并且可能导致特殊字符的问题。此外,Base64 URL编码不使用=字符来填充编码字符串的末尾。这是因为有些系统将=解释为特殊字符,可能会导致解析或解释编码数据时出现问题。
获得编码后的字符串使用 . 进行拼接后如下(注意最后哪个点不能少)
eyJhbGciOiJub25lIn0.eyJpYXQiOjE2ODI5MDkxNDksImFkbWluIjoidHJ1ZSIsInVzZXIiOiJTeWx2ZXN0ZXIifQ.
复制到请求头中 替换到之前的 token,发送请求。重置投票成功
题7: Code review
题8: JWT cracking
破解token,并将username改为WebGoat后重新生成新的token
解 : 这里需要用到第三种攻击方式:暴力破解
先用 JWT编码/解码工具 解码jwt的token
token的第三部分签名,需要用到hashcat工具来暴力破解 hashcat使用手册
hashcat -m 16500 eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImlhdCI6MTY4MjI0MjA4NSwiZXhwIjoxNjgyMjQyMTQ1LCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQub3JnIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.IDcasMh20YhElmSPcCbRCqq0H1Mshb7GZC4fHJGdT5k -a 3 ?l?l?l?l?l?l?l?l -i --increment-min=6 --increment-max=10 --force -o jwtret.txt cat jwtret.txt
获得破解的密钥为 available
使用JWT编码/解码工具把username改为WebGoat,secret处填入破解得到的密钥,左侧自动计算出结果。提交成功!
题10: Refreshing a token
刷新令牌的安全性问题:需要使用tom的账户来为你的订单买单。
解:
- 第一个here链接,看一下关于刷新令牌漏洞的描述(使用别人的刷新令牌刷新你的访问令牌)。以及刷新令牌和访问令牌的消息体格式
- 第二个here链接,可以在这里找到一个历史的刷新令牌,留着备用
- 点一下checkout按钮,把请求发到repeater,查看请求头,此时 Authorization头 为 bear null ,把他改为第2步中找到的刷新令牌,发送请求。提示令牌已经过期了
把刷新令牌复制到JWT编码/解码工具查看一下,加密方式为HS512,我们先把他改为None,去掉后面的签名部分,然后把payload中的exp字段的值改大一点,超过当前时间就行。
复制上面生成的新字符串,放到 Authorization头中,再次发送请求,返回成功
题11: Final challenge
使用jerry的token删除汤姆的账户
解:
- 点一下tom下面的delete按钮。查看请求返回信息为 “io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.”
- 把请求信息发送到repeater,反序列化token,得到以下信息
- 尝试把alg改为none的方式,尝试失败。需要采用其他方式 。参考前面关于JWT攻击方式的介绍 JWT攻击参考资料
前面的练习题我们已经使用过1和3,当前的加密方式为 HS256,也不适用2,只剩下4 篡改kid的方式了。刚好这个token的header中确实是包含kid字段的。所以尝试适用此方式进行破解- kid 介绍 : kid 即为 key ID ,存在于 jwt header 中,是一个可选的字段,用来指定加密算法的密钥。实际上这里就是使用数据库来存储密钥的,而token中的kid就是获取这个密钥的查询条件,因为用到了SQL,所以这里可以使用union注入篡改数据库返回的密钥。 当前的kid为 webgoat_key 也就是表示后端会根据这个kid的值去数据库中查询获取真正的key值,类似于这样的 SQL
select secret_key from tableXX where kid = '" +kid+ "'";
- 首先我们需要确定一个篡改后的key及其base64后的值,比如key为 sdf 那么base64后为 c2Rm
把输入webgoat_key 修改为 ddd’ union select ‘c2Rm’ from INFORMATION_SCHEMA.SYSTEM_USERS –
此时可以推想服务端实际执行的Sql为,因为使用了union注入,所以我们在这里并不关心union前的语句使用了什么表和字段,只要它别返回任何值就行了-- secret_key 和 tableXX在这里都是随便猜想的,正确与否不重要 select secret_key from tableXX where kid = 'asdf' union select 'c2Rm' from INFORMATION_SCHEMA.SYSTEM_USERS --
上面的Sql由于kid=asdf不存在不会返回任何值,而union后的则会返回 c2Rm 也就是表示当前的key已经被篡改为了 sdf。 接下来
- 修改payload中的username为 Tom ;
- 修改payload中的 exp为当前时间这时候的时间戳;
- 设置下面签名处的密钥为 sdf ;
- 查看左边重新生成的 token 。
使用新的token在repeater中替换原有token,发送请求。任务完成
未完待续…
最近在备战信安考试,后续的题要晚一点再做了