Share
## https://sploitus.com/exploit?id=43508C57-FBB3-5923-97A4-792B9A7EE2C5
# SST1: Filter Bypass - Server-Side Template Injection
**Challenge:** SST1 (Web Exploitation - Medium, 200 pts)
**CTF:** picoCTF 2025
**Author:** Venax
**Flag:** `picoCTF{sst1_f1lt3r_byp4ss_e39c23ee}`
---
## Challenge Overview
This challenge demonstrates the dangers of blacklist-based input sanitization in web applications. The target website allows users to announce messages but implements a flawed character filtering mechanism. By exploiting Server-Side Template Injection (SSTI), we can bypass the sanitization and achieve remote code execution.
**Key Concept:** Blacklisting specific characters is fundamentally broken security. Attackers can find alternative syntax or encoding methods to bypass filters, making this approach unreliable for production systems. Whitelist-based validation is the correct approach.
---
## Vulnerability Analysis
### Root Cause
The application attempts to prevent code injection by blacklisting certain characters. However, this approach fails because:
1. **Incomplete Coverage:** Multiple ways exist to express the same payload
2. **Encoding Bypass:** Special characters can be encoded in various formats (hex, octal, unicode)
3. **Alternative Syntax:** Template engines often provide multiple ways to access the same functionality
4. **Context Escape:** Input validation doesn't account for the execution context
### Attack Vector: Server-Side Template Injection (SSTI)
The vulnerable endpoint accepts user input and processes it through a template engine (likely Jinja2) without proper sanitization. By injecting template syntax, we can execute arbitrary Python code.
**Template Injection Payload Structure:**
```
{{ malicious_code }}
```
The challenge lies in bypassing the character blacklist while maintaining valid template syntax.
---
## Solution Methodology
### Step 1: Reconnaissance
- Access the target website and identify the announcement feature
- Analyze the input validation mechanism
- Determine which characters are filtered
### Step 2: Payload Crafting
The blacklist filter removes common dangerous characters. We bypass this by:
- Using alternative Python syntax for dangerous operations
- Leveraging attribute access methods available in template engines
- Chaining operations to construct forbidden functions
### Step 3: Exploitation
**Working Payload:**
```python
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('cat /flag').read() }}
```
**Alternative Approach (Attribute Chaining):**
```python
{{ ''.__class__.__mro__[1].__subclasses__()[396]('cat /flag', shell=True, stdout=-1).communicate() }}
```
The specific payload depends on the blacklisted characters. The key is understanding that:
- Jinja2 templates process `{{ }}` expressions
- Python object introspection allows access to dangerous functions
- The `__builtins__` module contains `__import__()` for loading system modules
- `os.popen()` enables command execution
### Step 4: Flag Extraction
Execute the payload through the web interface and capture the command output containing the flag.
---
## Technical Details
### Blacklist Evasion Techniques
| Technique | Description |
|-----------|-------------|
| **Attribute Access** | `object.__dict__` instead of `object.dict` |
| **String Construction** | Using `chr()` or `hex` notation to build strings |
| **Encoding** | Base64, hex, or unicode escaping |
| **Indirect Import** | Using `__import__('os')` instead of `import os` |
| **Subscript Access** | `list[0]` instead of `list.get(0)` |
### Why Blacklisting Fails
```
Denied Characters: { } [ ] . _ ; : / \
Bypasses:
- {{ self.something }} โ self['something']
- {{ __import__('os') }} โ {{ self.__init__.__globals__.__builtins__.__import__('os') }}
- {{ os.system() }} โ {{ os.__getattribute__('system') }}
```
---
## Lab Environment
### Instance Details
- **Challenge Instance ID:** 649432
- **Debug Info:** `e:p c:488 i:296753`
- **Instance Status:** Active (2h 13m remaining)
### Running the Challenge
1. Launch instance via picoCTF platform
2. Access the provided URL in browser
3. Navigate to announcement submission form
4. Inject payload in text field and submit
---
## Proof of Concept
### Screenshots
**Figure 1: Challenge Landing Page**

**Figure 2: Vulnerable Input Form**

**Figure 3: Payload Submission**

**Figure 4: Flag Capture**

---
## Prevention & Remediation
### Secure Implementation
**INSECURE (Blacklist):**
```python
def sanitize_input(user_input):
dangerous_chars = ['', '{', '}', '_', '.']
for char in dangerous_chars:
user_input = user_input.replace(char, '')
return user_input
```
**SECURE (Whitelist + Context-Aware):**
```python
import re
from jinja2 import Environment, BaseLoader
def sanitize_input(user_input):
# Whitelist: only alphanumeric, spaces, basic punctuation
if not re.match(r'^[a-zA-Z0-9\s\.\,\!\?\-]*$', user_input):
raise ValueError("Invalid characters in input")
return user_input
# Disable dangerous functions in template environment
env = Environment(loader=BaseLoader())
env.globals['__builtins__'] = {}
```
### Best Practices
1. **Use Whitelists, Not Blacklists:** Define what IS allowed, not what ISN'T
2. **Input Validation + Output Encoding:** Validate on input, encode on output
3. **Disable Dangerous Functions:** Remove `__import__`, `eval`, `exec` from template environments
4. **Use Sandboxing:** Run templates in restricted environments
5. **Content Security Policy:** Implement CSP headers to limit injection impact
6. **Security Scanning:** Automated tools to detect template injection vulnerabilities
---
## Key Takeaways
- **Blacklist-based sanitization is fundamentally broken** โ Multiple equivalent payloads exist
- **Context Matters** โ Understanding where input is processed is critical to exploitation
- **Template Injection is Powerful** โ SSTI can lead to RCE in many frameworks
- **Whitelist Everything** โ Only allow known-good input patterns
- **Defense in Depth** โ Use multiple layers of protection
---
## References
- [OWASP: Server-Side Template Injection](https://owasp.org/www-community/attacks/Server-Side_Template_Injection)
- [PortSwigger: Server-Side Template Injection](https://portswigger.net/research/server-side-template-injection)
- [Jinja2 Documentation](https://jinja.palletsprojects.com/)
- [HackTricks: SSTI](https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection)
---
## Files in This Repository
```
sst1_filt3r_bypass/
โโโ README.md # This file
โโโ exploit.py # Python exploitation script
โโโ payload.txt # Working payload variations
โโโ screenshots/ # Evidence screenshots
โ โโโ 01_challenge_interface.png
โ โโโ 02_vulnerable_form.png
โ โโโ 03_payload_injection.png
โ โโโ 04_flag_retrieved.png
โโโ .gitignore
```
---
**Last Updated:** July 2026
**Status:** Completed - Flag Obtained
**Difficulty Assessment:** Medium (requires template injection knowledge)