This detection identifies adversaries who deploy encoded PHP webshells to execute malicious commands while evading signature-based security controls through obfuscation. A proactive hunt is essential in Azure Sentinel to uncover these stealthy persistence mechanisms that often bypass standard log analysis and could serve as a foothold for lateral movement or data exfiltration within the environment.
rule WEBSHELL_PHP_OBFUSC_Encoded
{
meta:
description = "PHP webshell obfuscated by encoding"
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/04/18"
modified = "2023-04-05"
score = 70
hash = "119fc058c9c5285498a47aa271ac9a27f6ada1bf4d854ccd4b01db993d61fc52"
hash = "d5ca3e4505ea122019ea263d6433221030b3f64460d3ce2c7d0d63ed91162175"
hash = "8a1e2d72c82f6a846ec066d249bfa0aaf392c65149d39b7b15ba19f9adc3b339"
id = "134c1189-1b41-58d5-af66-beaa4795a704"
strings:
// one without plain e, one without plain v, to avoid hitting on plain "eval("
$enc_eval1 = /(e|\\x65|\\101)(\\x76|\\118)(a|\\x61|\\97)(l|\\x6c|\\108)(\(|\\x28|\\40)/ wide ascii nocase
$enc_eval2 = /(\\x65|\\101)(v|\\x76|\\118)(a|\\x61|\\97)(l|\\x6c|\\108)(\(|\\x28|\\40)/ wide ascii nocase
// one without plain a, one without plain s, to avoid hitting on plain "assert("
$enc_assert1 = /(a|\\97|\\x61)(\\115|\\x73)(s|\\115|\\x73)(e|\\101|\\x65)(r|\\114|\\x72)(t|\\116|\\x74)(\(|\\x28|\\40)/ wide ascii nocase
$enc_assert2 = /(\\97|\\x61)(s|\\115|\\x73)(s|\\115|\\x73)(e|\\101|\\x65)(r|\\114|\\x72)(t|\\116|\\x74)(\(|\\x28|\\40)/ wide ascii nocase
//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 < 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 any of ( $enc* )
}
This YARA rule can be deployed in the following contexts:
This rule contains 13 string patterns in its detection logic.
Here are 5 specific false positive scenarios for the PHP webshell obfuscated by encoding detection rule, including suggested filters and exclusions:
Scenario: Automated Backup Scripts using Base64 Payloads
cron tasks) utilizing tools like Rsync or custom Python/PHP backup agents often encode configuration files or binary data into Base64 strings before writing them to the web root. The detection logic may misinterpret these long, encoded strings within legitimate backup scripts as obfuscated malicious code./var/www/html/backups/ or /opt/app/maintenance/) and filter out events where the user agent is identified as a known internal service account (e.g., backup-service).Scenario: CMS Plugin Updates via Admin Dashboard
/wp-content/plugins/, /sites/all/modules/) and exclude events originating from IP addresses within the corporate admin subnet or authenticated via SAML/OAuth sessions for users with admin roles.Scenario: CI/CD Pipeline Artifact Deployment