This detection identifies potential webshell deployments by analyzing incoming traffic for characteristic command execution strings often associated with remote access tools or malicious scripts. Proactively hunting for these indicators in Azure Sentinel is critical to uncovering early-stage post-exploitation activities where adversaries establish persistent footholds through compromised web applications before initiating lateral movement.
rule WEBSHELL_PHP_Strings_SUSP
{
meta:
description = "typical webshell strings, suspicious"
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"
date = "2021/01/12"
modified = "2023-07-05"
score = 50
hash = "0dd568dbe946b5aa4e1d33eab1decbd71903ea04"
hash = "dde2bdcde95730510b22ae8d52e4344997cb1e74"
hash = "499db4d70955f7d40cf5cbaf2ecaf7a2"
hash = "281b66f62db5caab2a6eb08929575ad95628a690"
hash = "1ab3ae4d613b120f9681f6aa8933d66fa38e4886"
id = "25f25df5-4398-562b-9383-e01ccb17e8de"
strings:
$sstring1 = "eval(\"?>\"" nocase 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
//strings from private rule php_false_positive
// try to use only strings which would be flagged by themselves as suspicious by other rules, e.g. eval
// a good choice is a string with good atom quality = ideally 4 unusual characters next to each other
$gfp1 = "eval(\"return [$serialised_parameter" // elgg
$gfp2 = "$this->assert(strpos($styles, $"
$gfp3 = "$module = new $_GET['module']($_GET['scope']);"
$gfp4 = "$plugin->$_POST['action']($_POST['id']);"
$gfp5 = "$_POST[partition_by]($_POST["
$gfp6 = "$object = new $_REQUEST['type']($_REQUEST['id']);"
$gfp7 = "The above example code can be easily exploited by passing in a string such as" // ... ;)
$gfp8 = "Smarty_Internal_Debug::start_render($_template);"
$gfp9 = "?p4yl04d=UNION%20SELECT%20'<?%20system($_GET['command']);%20?>',2,3%20INTO%20OUTFILE%20'/var/www/w3bsh3ll.php"
$gfp10 = "[][}{;|]\\|\\\\[+=]\\|<?=>?"
$gfp11 = "(eval (getenv \"EPROLOG\")))"
$gfp12 = "ZmlsZV9nZXRfY29udGVudHMoJ2h0dHA6Ly9saWNlbnNlLm9wZW5jYXJ0LWFwaS5jb20vbGljZW5zZS5waHA/b3JkZXJ"
//strings from private rule capa_php_input
$inp1 = "php://input" wide ascii
$inp2 = /_GET\s?\[/ wide ascii
// for passing $_GET to a function
$inp3 = /\(\s?\$_GET\s?\)/ wide ascii
$inp4 = /_POST\s?\[/ wide ascii
$inp5 = /\(\s?\$_POST\s?\)/ wide ascii
$inp6 = /_REQUEST\s?\[/ wide ascii
$inp7 = /\(\s?\$_REQUEST\s?\)/ wide ascii
// PHP automatically adds all the request headers into the $_SERVER global array, prefixing each header name by the "HTTP_" string, so e.g. @eval($_SERVER['HTTP_CMD']) will run any code in the HTTP header CMD
$inp15 = "_SERVER['HTTP_" wide ascii
$inp16 = "_SERVER[\"HTTP_" wide ascii
$inp17 = /getenv[\t ]{0,20}\([\t ]{0,20}['"]HTTP_/ wide ascii
$inp18 = "array_values($_SERVER)" wide ascii
$inp19 = /file_get_contents\("https?:\/\// wide ascii
condition:
filesize < 700KB and (
(
(
$php_short in (0..100) or
$php_short in (filesize-1000..filesize)
)
and not any of ( $no_* )
)
or any of ( $php_new* )
)
and not (
any of ( $gfp* )
)
and
( 1 of ( $sstring* ) and (
any of ( $inp* )
)
)
}
This YARA rule can be deployed in the following contexts:
This rule contains 36 string patterns in its detection logic.
Here are 4 specific false positive scenarios for the “typical webshell strings, suspicious” detection rule, including targeted filters and exclusions:
Scenario: Automated Backup Scripts Executing via Web Server
<?php system($_GET['cmd']); ?>) that mimic webshell behavior when the backup service polls the server.C:\Program Files\Veeam\Backup and Replication Server\Web\Scripts\). Additionally, exclude traffic originating from the specific Service Account used by the backup agent (e.g., DOMAIN\VeeamService) during defined maintenance windows.Scenario: CI/CD Pipeline Deployment Artifacts
IIS or Apache). These artifacts often include diagnostic scripts with generic execution strings that trigger the rule before the final cleanup job runs./var/www/html/deploy-staging/* or C:\inetpub\wwwroot\temp-builds). Implement a time-based filter to suppress alerts for these paths during known deployment windows (e.g., 02:00–04:00 UTC).Scenario: Third-Party Analytics and Monitoring Agents