
DreamHack - Mango Web Challenge Write-up
Room / Challenge: Mango (Web) Metadata Author: jameskaois CTF: DreamHack Challenge: Mango (web) Link: https://dreamhack.io/wargame/challenges/90 Level: 2 Date: 07-11-2025 Goal Get the flag by leveraging blind NoSQL Injection. My Solution You can download and examine the source code here. The web app just have one main.js file to examine: const express = require('express'); const app = express(); const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/main', { useNewUrlParser: true, useUnifiedTopology: true, }); const db = mongoose.connection; // flag is in db, {'uid': 'admin', 'upw': 'DH{32alphanumeric}'} const BAN = ['admin', 'dh', 'admi']; filter = function (data) { const dump = JSON.stringify(data).toLowerCase(); var flag = false; BAN.forEach(function (word) { if (dump.indexOf(word) != -1) flag = true; }); return flag; }; app.get('/login', function (req, res) { if (filter(req.query)) { res.send('filter'); return; } const { uid, upw } = req.query; db.collection('user').findOne( { uid: uid, upw: upw, }, function (err, result) { if (err) { res.send('err'); } else if (result) { res.send(result['uid']); } else { res.send('undefined'); } }, ); }); app.get('/', function (req, res) { res.send('/login?uid=guest&upw=guest'); }); app.listen(8000, '0.0.0.0'); We have to leverage /login route to get the flag. There is a filter function that prevents us from use admin, dh and admi in the route. For example, when we visit /login?uid=admin&upw=DH{ received filter: ...


