This detection identifies the deployment of a small Java Server Pages (JSP) webshell on a target server, signaling potential adversary persistence and command-and-control capabilities following an initial compromise. A SOC team should proactively hunt for this artifact in Azure Sentinel to rapidly isolate compromised endpoints before attackers can leverage the webshell for lateral movement or data exfiltration within the cloud environment.
rule EXT_WEBSHELL_JSP_Generic_Tiny
{
meta:
description = "Generic JSP webshell tiny"
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/07"
modified = "2024-12-16"
hash = "8fd343db0442136e693e745d7af1018a99b042af"
hash = "87c3ac9b75a72187e8bc6c61f50659435dbdc4fde6ed720cebb93881ba5989d8"
hash = "1aa6af726137bf261849c05d18d0a630d95530588832aadd5101af28acc034b5"
id = "fad14524-de44-52ea-95e6-3e5de3138926"
strings:
$payload1 = "ProcessBuilder" fullword wide ascii
$payload2 = "URLClassLoader" fullword wide ascii
// Runtime.getRuntime().exec(
$payload_rt1 = "Runtime" fullword wide ascii
$payload_rt2 = "getRuntime" fullword wide ascii
$payload_rt3 = "exec" fullword wide ascii
$jg_sus1 = "xe /c" ascii wide // of cmd.exe /c
$jg_sus2 = /getParameter\("."\)/ ascii wide // one char param
$jg_sus3 = "</pre>" ascii wide // webshells like fixed font wide
$jg_sus4 = "BASE64Decoder" fullword ascii wide
//strings from private rule capa_jsp_safe
$cjsp_short1 = "<%" ascii wide
$cjsp_short2 = "%>" wide ascii
$cjsp_long1 = "<jsp:" ascii wide
$cjsp_long2 = /language=[\"']java[\"\']/ ascii wide
// JSF
$cjsp_long3 = "/jstl/core" ascii wide
$cjsp_long4 = "<%@p" nocase ascii wide
$cjsp_long5 = "<%@ " nocase ascii wide
$cjsp_long6 = "<% " ascii wide
$cjsp_long7 = "< %" ascii wide
//strings from private rule capa_jsp_input
// request.getParameter
$input1 = "getParameter" fullword ascii wide
// request.getHeaders
$input2 = "getHeaders" fullword ascii wide
$input3 = "getInputStream" fullword ascii wide
$input4 = "getReader" fullword ascii wide
$req1 = "request" fullword ascii wide
$req2 = "HttpServletRequest" fullword ascii wide
$req3 = "getRequest" fullword ascii wide
// no web input but fixed command to create reverse shell
$fixed_cmd1 = "bash -i >& /dev/" ascii wide
$fp1 = "Find Security Bugs is a plugin that aims to help security audit.</Details>"
condition:
//any of them or
(
(
filesize < 1000 and
any of ( $jg_sus* )
) or
filesize < 250
) and (
$cjsp_short1 at 0 or
any of ( $cjsp_long* ) or
($cjsp_short1 and $cjsp_short2 in ( filesize-100..filesize )) or
(
$cjsp_short2 and (
$cjsp_short1 in ( 0..1000 ) or
$cjsp_short1 in ( filesize-1000..filesize )
)
)
)
and (
(
any of ( $input* ) and
any of ( $req* )
) or (
any of ( $fixed_cmd* )
)
)
and
( 1 of ( $payload* ) or all of ( $payload_rt* ) )
and not any of ( $fp* )
}
This YARA rule can be deployed in the following contexts:
This rule contains 27 string patterns in its detection logic.
Here are 5 specific false positive scenarios for the Generic JSP webshell tiny detection rule, along with suggested filters or exclusions:
Scenario: Scheduled Backup of Web Application Artifacts
webapps directory. During this process, the backup agent may temporarily create or modify small .jsp files within the web root before compression, mimicking the “tiny” file creation behavior of a webshell.svc_backup_agent) on the application server host during the defined maintenance window (e.g., 02:00–04:00 UTC).Scenario: CI/CD Pipeline Deployment of Micro-Components
health_check.jsp or version_info.jsp) to the staging environment. These files are often small (<5KB) and created by the deployment service account rather than an interactive user session.jenkins-agent or gitlab-runner) AND the filename matches known utility patterns (regex: ^(health|status|version|info)\.jsp$).Scenario: Automated Health Monitoring Probes