Hack.lu CTF 2024 | Buffzone (Web, XSS)
Difficulty: Medium


Previous4T$ CTF | My Sky Blog (Web, Golang Template Injection)NextBuckeyeCTF 2024 | Homecooked & Quotes (Web)
Last updated
Difficulty: Medium


Last updated
const express = require('express')
const markdownit = require('markdown-it');
const puppeteer = require('puppeteer');
const rateLimit = require("express-rate-limit");
const BASEDOMAIN = process.env.BASEDOMAIN;
const FLAG = process.env.FLAG;
const md = markdownit()
const limiter = rateLimit({
windowMs: 1 * 60 * 1000,
limit: 1,
message: "Too many requests, please try again later."
})
const app = express();
app.set('trust proxy', 1);
app.use(express.json());
app.use(express.static("public"))
app.set('view engine', 'pug');
function replaceUrls(text) {
let regex = /(https:\/\/.*?)\s/gi;
let replacedText = text.replace(regex, '<a href="$1">$1</a>');
return replacedText;
}
app.get("/", (req, res) => {
res.render("index")
});
app.get("/buffzone", (req, res) => {
let message = req.query.message;
if (message) {
res.render("buffzone", { message: replaceUrls(md.render("**" + message + "**")) })
}
else {
res.redirect("/")
}
});
async function adminVisits(message){
const browser = await puppeteer.launch({
headless: true,
args: [
// disable stuff we do not need
'--disable-gpu', '--disable-software-rasterizer', '--disable-dev-shm-usage',
// disable sandbox since it does not work inside docker
// (but we will use seccomp at least)
'--no-sandbox',
// no exploits please
"--js-flags=--noexpose_wasm,--jitless",
],
ignoreHTTPSErrors: true
});
const page = await browser.newPage();
let url =`http://${BASEDOMAIN}/buffzone?message=${encodeURIComponent(message)}`;
try {
await page.setCookie({
name: 'flag',
value: FLAG,
domain: BASEDOMAIN,
path: '/',
httpOnly: false,
secure: false
});
await page.goto(url, { waitUntil: 'networkidle2' });
console.log(`Successfully visited: ${url}`);
} catch (error) {
console.error(`Error visiting ${url}:`, error);
}
await browser.close();
}
app.get("/lambdaQuote", limiter, (req, res) => {
let message = req.query.message;
if (message) {
console.log(`Bot visiting ${message}, from ip ${req.ip}.`);
try {
adminVisits(message)
} catch (error) {
console.log(error)
return res.status(500).send("An error occurred")
}
return res.status(200).send("Message sent to admin for review!")
}
else {
return res.status(400).send("No message provided")
}
});
app.listen(80, () => {
console.log("Server running on port 80");
});function replaceUrls(text) {
let regex = /(https:\/\/.*?)\s/gi;
let replacedText = text.replace(regex, '<a href="$1">$1</a>');
return replacedText;
}res.render("buffzone", { message: replaceUrls(md.render("**" + message + "**")) })test**  **testtest**  **test