VCTF2024-web

hackjs

看下源码:

const express = require('express')
const fs = require('fs')
var bodyParser = require('body-parser');
const app = express()
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

app.post('/plz', (req, res) => {

    venom = req.body.venom

    if (Object.keys(venom).length < 3 && venom.welcome == 159753) {
        try {
            if(venom.hasOwnProperty("text")){
                res.send(venom.text)
            }else{
                res.send("no text detected")
            }
        } catch {
            if (venom.text=="flag") {
                let flag=fs.readFileSync("/flag");
                res.send("Congratulations:"+flag);
            } else {
                res.end("Nothing here!")
            }
        }
    } else {
        res.end("happy game");
    }
})

 

app.get('/',
function(req, res, next) {
    res.send('<title>oldjs</title><a>Hack me plz</a><br><form action="/plz" method="POST">text:<input type="text" name="venom[text]" value="ezjs"><input type="submit" value="Hack"></form>  ');
});

app.listen(80, () => {
  console.log(`listening at port 80`)
}) 

很显然的思路,首先要进if,那就需要有个welcome的属性,然后里面让hasOwnProperty抛错,从而进入catch块,并且键值对里面还要有text==flag的东西。

首先很容易网上搜到,hasOwnProperty是来自Object.prototype的方法,如果对象内部重新写一个hasOwnProperty,再去调用的时候就会调用你自己重新覆写的hasOwnProperty,所以就会报TypeError这种类型的错。

但是键值对限制死了只能传<3,welcome一个,hasOwnPeoperty一个,text一个,超了:

然后重新审计源码,发现根目录路由可以传参,抓个包看看:

这里传参的是数组。

这里我一开始想到了多线程,能不能这里传数据,那边传json然后卡进去,但是实际上传参后我发现,如果开多线程是不行的,回显是happy game

如果写个脚本一起传参也不行,因为等效于一起发的,还是回显happy game

怎么办?

重新考虑,能不能从原型链下手,重温一下prototype:

JavaScript原型链污染原理及相关CVE漏洞剖析 - FreeBuf网络安全行业门户

n8tz/CVE-2022-24999:“qs”原型中毒漏洞 ( CVE-2022-24999 ) (github.com)

非常形象生动的图:

所以我们可以想到:

一次[__proto__]到venom构造函数的prototype,再一次[__proto__]到Object.prototype,我们在这里创造welcome,本质上能让这个welcome继承下去,所以venom.welcome能够访问到但是venom对象里面只存在我们写入的"hasOwnProperty":1和"text":"flag"两个键值对,所以能够绕过键值对的长度判断(这是鄙人理解,如有错误还请指正!)。

而且这里只用一次__proto__也是可行的,详见:2024 第一届VCTF 纳新赛 Web方向 题解WP (hqwc.cn)

没来得及截图,看赛后群里师傅发的:

但是有趣的是,这道题发json这么做是不能出的:

所以这种解析方法应该是只存在于把__proto__写入数组方式的情况,对应CVE-2022-24999,高版本已经修复。

Archived elephant(Unsolved)

待复现,本地docker-compose一直报错打不开浏览器。修好了可以试试。

posted @ 2024-03-17 14:04  Eddie_Murphy  阅读(41)  评论(0编辑  收藏  举报