This detection identifies adversaries deploying malicious PHP webshells that utilize eval() functions to execute dynamically obfuscated strings, a common tactic for establishing persistent backdoors and evading static analysis. Proactively hunting for this behavior in Azure Sentinel is critical because these webshells often serve as the initial foothold for attackers to exfiltrate sensitive data or pivot across internal networks before triggering broader alerting mechanisms.
rule WEBSHELL_PHP_OBFUSC_Str_Replace
{
meta:
description = "PHP webshell which eval()s obfuscated string"
license = "Detection Rule License 1.1 https://github.com/Neo23x0/signature-base/blob/master/LICENSE"
author = "Arnim Rupp (https://github.com/ruppde)"
reference = "Internal Research"
score = 75
date = "2021/01/12"
modified = "2023-04-05"
hash = "691305753e26884d0f930cda0fe5231c6437de94"
hash = "7efd463aeb5bf0120dc5f963b62463211bd9e678"
hash = "fb655ddb90892e522ae1aaaf6cd8bde27a7f49ef"
hash = "d1863aeca1a479462648d975773f795bb33a7af2"
hash = "4d31d94b88e2bbd255cf501e178944425d40ee97"
hash = "e1a2af3477d62a58f9e6431f5a4a123fb897ea80"
id = "1f5b93c9-bdeb-52c7-a99a-69869634a574"
strings:
$payload1 = "str_replace" fullword wide ascii
$payload2 = "function" fullword wide ascii
$goto = "goto" fullword wide ascii
//$hex = "\\x"
$chr1 = "\\61" wide ascii
$chr2 = "\\112" wide ascii
$chr3 = "\\120" wide ascii
//strings from private rule capa_php_old_safe
$php_short = "<?" wide ascii
// prevent xml and asp from hitting with the short tag
$no_xml1 = "<?xml version" nocase wide ascii
$no_xml2 = "<?xml-stylesheet" nocase wide ascii
$no_asp1 = "<%@LANGUAGE" nocase wide ascii
$no_asp2 = /<script language="(vb|jscript|c#)/ nocase wide ascii
$no_pdf = "<?xpacket"
// of course the new tags should also match
// already matched by "<?"
$php_new1 = /<\?=[^?]/ wide ascii
$php_new2 = "<?php" nocase wide ascii
$php_new3 = "<script language=\"php" nocase wide ascii
condition:
filesize < 300KB and (
(
(
$php_short in (0..100) or
$php_short in (filesize-1000..filesize)
)
and not any of ( $no_* )
)
or any of ( $php_new* )
)
and any of ( $payload* ) and #goto > 1 and
( #chr1 > 10 or #chr2 > 10 or #chr3 > 10 )
}
This YARA rule can be deployed in the following contexts:
This rule contains 16 string patterns in its detection logic.
Here are 4 specific false positive scenarios for the “PHP webshell which eval()s obfuscated string” detection rule, including suggested filters and exclusions:
Scenario: Legitimate CMS Plugin Updates via Admin Dashboard
eval() to render dynamic content or process form submissions. These plugins frequently obfuscate strings (e.g., base64 encoded configuration data) before evaluation during the update or activation phase.10.50.x.x) accessing specific CMS directories (e.g., /wp-admin/, /administrator/). Additionally, filter out requests where the User-Agent header matches standard browser strings rather than generic curl/wget tools often used by attackers.Scenario: Scheduled Maintenance Jobs for Log Aggregation
cron) to run PHP scripts that parse and aggregate logs. These scripts often receive obfuscated log payloads from external SIEM tools or monitoring agents, decode them using base64, and evaluate the results to generate reports.02:00 to 04:00 daily) combined with a specific service account identity (e.g., svc-log-aggregator). Filter out alerts where the source IP is a dedicated maintenance server and the request URI contains keywords like /cron/, /maintenance/, or /jobs/.Scenario: Dynamic Reporting Dashboards using Third-Party Visualization Libraries