Unfortunately, I solved this challenge only 30 minutes after the CTF ended. Here is my write-up about the challenge.

image.png

image.png

Description

This is a fixed challenge of disconnection.

disconnection-revenge.tar.gz

Exploit

In this challenge, we are given source code like this:

import express from "express";

const html = `
<h1>XSS Playground</h1>
<script>eval(new URLSearchParams(location.search).get("xss"));</script>
`.trim();

express()
  .use("/", (req, res, next) => {
    res.setHeader(
      "Content-Security-Policy",
      "script-src 'unsafe-inline' 'unsafe-eval'; default-src 'none'"
    );
    next();
  })
  .get("/", (req, res) => res.type("html").send(html))
  .all("/*", (req, res) => res.socket.destroy()) // disconnected
  .use((err, req, res, next) => {
    // revenge!
    res.socket.destroy(); // disconnected
  })
  .listen(3000);

The interesting part about this source code is in the Content Security Policy (CSP):

res.setHeader(
  "Content-Security-Policy",
  "script-src 'unsafe-inline' 'unsafe-eval'; default-src 'none'"
);

The disconnect mechanism:

.all("/*", (req, res) => res.socket.destroy()) // disconnected
.use((err, req, res, next) => {
  // revenge!
  res.socket.destroy(); // disconnected
})

There's also a code injection vulnerability here that allows us to gain XSS:

const html = `
<h1>XSS Playground</h1>
<script>eval(new URLSearchParams(location.search).get("xss"));</script>
`.trim();

The flag is located in the /cookie path, as shown in this snippet of the source code:

await page.setCookie({
  name: "FLAG",
  value: FLAG,
  domain: APP_HOST,
  path: "/cookie", // 🍪
});

The interesting part is that we can't get the flag easily by accessing /cookie directly using XSS and get the cookie from that. The disconnect mechanism causes us to be instantly disconnected when accessing any URL except /, resulting in a browser error. Therefore, when we try to access URLs like /cookie, the browser will instantly error ERR_EMPTY_RESPONSE, and the origin will be null as shown in the image below.

https://prod-files-secure.s3.us-west-2.amazonaws.com/39d1be85-e7c6-4263-a666-a42da95a70df/60d9778e-ab5f-4ab8-92bb-6539f24f1033/image.png