74 lines
1.8 KiB
JavaScript
74 lines
1.8 KiB
JavaScript
const express = require('express');
|
|
const puppeteer = require('puppeteer');
|
|
const app = express();
|
|
|
|
const FLAG = process.env.FLAG || 'kalmar{test_flag}';
|
|
const CHALLENGE_DOMAIN = process.env.CHALLENGE_DOMAIN || 'http://web:5000/';
|
|
|
|
app.use(express.json());
|
|
|
|
function sleep(ms) {
|
|
return new Promise(res => setTimeout(res, ms));
|
|
}
|
|
|
|
async function visitUrl(url) {
|
|
const browser = await puppeteer.launch({
|
|
headless: true,
|
|
args: [
|
|
// this is not a pwn challenge, please don't rce us
|
|
'--disable-extensions',
|
|
'--disable-gpu',
|
|
'--disable-software-rasterizer',
|
|
'--js-flags=--noexpose_wasm,--jitless',
|
|
'--no-sandbox',
|
|
]
|
|
});
|
|
|
|
try {
|
|
const page = await browser.newPage();
|
|
|
|
await page.goto(CHALLENGE_DOMAIN, {
|
|
waitUntil: 'networkidle0',
|
|
});
|
|
|
|
// Flag is stored in localStorage
|
|
await page.evaluate((flag) => {
|
|
localStorage.setItem("flag", flag);
|
|
}, FLAG);
|
|
|
|
await sleep(1000);
|
|
await page.close()
|
|
|
|
// now visit reported page
|
|
const page2 = await browser.newPage();
|
|
await page2.goto(url, {waitUntil: []});
|
|
|
|
await sleep(5000);
|
|
} catch (err) {
|
|
console.error('Error visiting page:', err);
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
}
|
|
|
|
app.post('/report', async (req, res) => {
|
|
const { url } = req.body;
|
|
|
|
if (!url || typeof url !== 'string' || !url.startsWith(CHALLENGE_DOMAIN + '?')) {
|
|
return res.status(400).json({ error: `Invalid URL. Url should be a string and start with ${CHALLENGE_DOMAIN + '?'}` });
|
|
}
|
|
|
|
try {
|
|
await visitUrl(url);
|
|
res.json({ success: true });
|
|
} catch (err) {
|
|
console.error('Error on /report', err);
|
|
res.status(500).json({ error: 'Failed to visit URL' });
|
|
}
|
|
});
|
|
|
|
const PORT = process.env.PORT || 8080;
|
|
app.listen(PORT, () => {
|
|
console.log(`Bot listening on port ${PORT}`);
|
|
});
|