AnalysisP1~90 min

Detect and Analyze Web Shells on Compromised Servers

Scan web directories for web shells, analyze suspicious file timestamps, check for encoded/obfuscated code, and correlate web server access logs with shell access patterns.

Actions

  1. 1

    Scan web root directories for common web shell patterns: `find /var/www -name "*.php" -newer /var/log/syslog -exec grep -l "eval\|base64_decode\|system\|exec\|passthru" {} \;` (Linux) or search IIS directories for aspx files with suspicious content.

  2. 2

    Check file timestamps for anomalies: files created during non-business hours, files with modification dates matching the compromise window, or timestomped files where $MFT timestamps disagree with $UsnJrnl.

  3. 3

    Analyze identified web shells for functionality: command execution, file upload/download, database access, reverse shell capability. Determine the attacker skill level and objectives.

  4. 4

    Correlate web server access logs with identified web shell files: extract source IPs that accessed the shell, timing of access, and commands executed.

  5. 5

    Check for web shell persistence mechanisms: scheduled tasks that recreate the web shell, modified legitimate files with injected shell code, or new virtual directories in IIS.

Queries

W3CIISLog | where TimeGenerated between (datetime(T_START) .. datetime(T_END)) | where csUriStem has_any (".aspx",".asp",".php",".jsp",".jspx") | summarize RequestCount=count(), DistinctIPs=dcount(cIP), FirstSeen=min(TimeGenerated) by csUriStem | where DistinctIPs <= 2 and RequestCount > 5 | order by FirstSeen asc // Find web shells: few IPs, many requests
DeviceFileEvents | where Timestamp between (datetime(T_START) .. datetime(T_END)) | where FolderPath has_any ("wwwroot","inetpub","www","html","htdocs") | where FileName endswith ".php" or FileName endswith ".aspx" or FileName endswith ".jsp" | where ActionType == "FileCreated" | project Timestamp, DeviceName, FileName, FolderPath, InitiatingProcessFileName
index=iis sourcetype=iis (cs_uri_stem="*.aspx" OR cs_uri_stem="*.php" OR cs_uri_stem="*.jsp" OR cs_uri_stem="*.jspx") | stats dc(c_ip) AS distinct_ips, count AS request_count, min(_time) AS first_seen by cs_uri_stem | search distinct_ips<=2 request_count>5 | sort first_seen
index=wineventlog sourcetype=WinEventLog:Sysmon EventCode=11 (TargetFilename="*\inetpub\wwwroot\*" OR TargetFilename="*\htdocs\*") (TargetFilename="*.aspx" OR TargetFilename="*.php" OR TargetFilename="*.jsp") | stats count by TargetFilename, Image, ComputerName | sort -count

Notes

Web shells can be extremely small (one-liners) or highly sophisticated with encryption, authentication, and anti-detection features.

Check for memory-only web shells that do not exist on disk (loaded via deserialization or injection into the web server process).

Where to Go Next

Related Resources