源代码是nodejs。/profile里面可以修改档案,然而注意下面的代码:
“`
const token = crypto.randomBytes(32).toString(‘hex’);
authToken = token;
await Token.create({ userId: req.session.userId, token, valid: true });
await Token.update({
“`
没有截完,但表明了存在token。我们需要获取token。
继续看,结尾处重定向:
“`
if (/^https:\/\/[a-f0-9]{32}\.oss-cn-beijing\.ichunqiu\.com\/$/.exec(bucket)) {
res.redirect(`/user/verify?token=${authToken}`)
“`
“`/…./.exec()“` 是js中的正则匹配。表明在bucket的末尾以一段网址结尾才能通过匹配。
我们接着看/verify
会发现修改成功也会让token失去活性。
于是我们继续研究bucket,发现一个页面是bucket。
“`
try {
const page = new Crawler({
userAgent: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36’,
referrer: ‘https://www.ichunqiu.com/’,
waitDuration: ‘3s’
});
await page.goto(user.bucket);
const html = page.htmlContent;
const headers = page.headers;
const cookies = page.cookies;
await page.close();
return res.json({ html, headers, cookies});
}
“`
这个架势,结合名字可知在爬虫。里面的page来自crawler,因此我们去crawler里面看。
发现引用了zombie库,这是一个js的模拟浏览器。
猜测应该会运行js代码。因此我们修改bucket让它执行远程的恶意js。
为什么知道这个?因为Google:
[Code Injection Vulnerability in zombie Package Secer’s Blog – 记录互联网安全历程与个人成长经历 (cker.in)](https://ha.cker.in/index.php/Article/13563)
Ok。进入细节。考察正则,在/bucket中,正则匹配必须不通过,才会开始访问。而上传则不能不通过,怎么做到呢?考虑上传过程的抓包修改。
程序的修改逻辑如下,发起请求,把请求中的id和bucket等参数存入内存,然后匹配,如果不成功,就停止在当前页面。如果成功,就跳转到验证页面,验证token,并且使得一次性token失活,而后把内存中的bucket修改。
所以两个页面内存一致然而逻辑独立,我可以存一个活着的token,来激活内存中没被销毁的bucket。
因此操作上,先规规矩矩发包,然后得到token,但是不让他跳转,也就是不使用。而后发一个自己的bucket的包,不会被通过,但是会存入内存。此刻把之前的还没用的token使用一次,即可过关。
后续poc可以参考Google上的那篇文章。
“`
a=this.constructor.constructor.constructor.constructor(‘return process’)();b=a.mainModule.require(‘child_process’);c=b.execSync(‘cat /flag’).toString();document.write(c);
“`
声明:
本文采用
BY-NC-SA
协议进行授权,如无注明均为原创,转载请注明转自
CyFin | Blog
本文地址: [喂饭级别]祥云杯2021crawler_z
本文地址: [喂饭级别]祥云杯2021crawler_z