HITB CTF Singapore 2017 Web WP

线上第三,最后被绝杀,pwn一道题没做出来,全队苦练pwn。

Web pasty

空的⽤户名密码可以直接登录, 但是没什么⽤, 登录后可以发表paste, 没有XSS和注⼊, 发现注册登录后会返回⼀个JSON Web Token

根据JWT的格式,base64解密第一部分为

{"kid":"keys/3c3c2ea1c3f113f649dc9389dd71b851","typ":"JWT","alg":"RS256"}

第二部分为

{"sub":"au1ge"}

RSA算法签名, 密钥由kid提供, 其中的sub⽤来验证身份, 看起来这道题是需要我们伪造⼀个admin的签名,⾸先尝试只有⼀个密钥的HS256签名发现⽆法绕过验证, 所以还是要⽤RS256的⽅法签名, 可以看到JWT获取解密签名的公钥是⽤kid直接引⽤⼀个pem⽂件, 再联想到我们可以通过类似/api/paste/27bd4411-6433-4503-a76b-1ba5c28764ac这样的url来取得我们发出的⼀条paste,所以可以⾃⼰发布⼀个内容是RSA公钥的paste, 再在kid⾥引⽤他就可以绕过签名的验证。
首先用openssl生成一个RSA公钥和密钥,然后发布一条内容为公钥的paste,更改token中sub为admin,kid为/keys/../api/paste/{公钥paste},即可绕过验证成为admin,然后直接访问/api/paste可以看到admin发布的flag。

Web website

这道题非预期拿了一血,非预期解法:

登录后发现set了一个cookie为user, 猜测与当前用户的身份验证有关, 扫目录时发现一个test.php里也有一段类似cookie中user的base64, 于是使用这里的cookie访问getinfo, 发现的确返回了admin的名字和他的csrftoken, 然后直接用这个csrftoken访问getflag就拿到了flag
预期解法:
没有test.php的情况下, 在getinfo的时候可以发现一个没有经过任何过滤的反射型XSS, 同时还会发现更改自己个人网站地址的时候会有admin去check, 于是可以在自己的vps上放置一个恶意页面, 让admin去check后请求getinfo中的token, 再用token去访问getflag, 把flag返回即可。贴一个别人WP的JS地址:https://pastebin.com/TqdGcYjP

Web blog

首先发现是GraphQL的语句, 首先fuzz一下可以报错看到具体查询语句和数据库是sqlite以及后端用的是python

还可以看到在把我们输入的item id先base64解码后再传入查询, 查询的参数是bYj0x把b去掉后base64解码Yj0x是b=1, 于是得到了查询的方式
尝试查询__schema可以发现一个没有在站点中出现的itemSelection的field, 测试发现这里有注入点, 可以构造union查询, 共有4个列

最后用语句b=') union select 1,group_concat(flag),3,4 from secret_flags --+可拿到flag

总结

Web这方面,一直在打CTF的都可以看到现在国内靠谱CTF的Web题和年初的时候ZCTF那段时间的Web题目有了很大的区别,开始向国外的Web题靠拢,摒弃之前的各种用trick解题和极限利用的思路,转而提高了整个Web题覆盖面的宽度和广度。服务端不再是一成不变的php,python和nodejs成为主流,数据库也大多用了更符合当前时代的nosql和sqlite等,与此同时也开始考察Web选手的密码学基础和对编码以及协议等基础的理解深度。可能唯一没多大区别的就是XSS的题目,因为XSS题目本身考察的就是选手对JS和同源策略的理解,以及对CSP和Chrome Auditor等waf的极限利用,也因为XSS的变数实在太多,本身就是一个非常有趣的类型,所以可以看到越来越多的Web安全研究员开始着眼于前端安全。

所以Web选手的视野一定要非常广阔,视野的差距在比赛中会主要体现为时间上的差距,比如这次的GraphQL,我之前因为完全没有接触过,所以开始做这题的时候基本是懵的,后来认真看了GraphQL的文档后才开始有点思路,而如果是一个了解过甚至研究过这个的选手,他可能首先就会查询__schema得到隐藏的field,从而很快的可以做出这道题,多出来的时间可以直接转向别的题目,导致时间上的差距滚雪球一样越拉越大。

//2018更新,似乎Web方面又倒退回去了。。。