This rule detects adversaries deploying RegAsp webshells in ASPX C# format to establish persistent command-and-control channels and execute arbitrary code on compromised web servers. Proactive hunting for this behavior is critical within Azure Sentinel to identify early-stage post-exploitation activities that often evade standard signature-based detection due to the webshell’s ability to blend with legitimate traffic patterns.
rule WEBSHELL_ASPX_Regeorg_CSHARP
{
meta:
description = "Webshell regeorg aspx c# version"
license = "Detection Rule License 1.1 https://github.com/Neo23x0/signature-base/blob/master/LICENSE"
reference = "https://github.com/sensepost/reGeorg"
hash = "c1f43b7cf46ba12cfc1357b17e4f5af408740af7ae70572c9cf988ac50260ce1"
author = "Arnim Rupp (https://github.com/ruppde)"
score = 75
date = "2021/01/11"
modified = "2023-07-05"
hash = "479c1e1f1c263abe339de8be99806c733da4e8c1"
hash = "38a1f1fc4e30c0b4ad6e7f0e1df5a92a7d05020b"
hash = "e54f1a3eab740201feda235835fc0aa2e0c44ba9"
hash = "aea0999c6e5952ec04bf9ee717469250cddf8a6f"
id = "0a53d368-5f1b-55b7-b08f-36b0f8c5612f"
strings:
$input_sa1 = "Request.QueryString.Get" fullword nocase wide ascii
$input_sa2 = "Request.Headers.Get" fullword nocase wide ascii
$sa1 = "AddressFamily.InterNetwork" fullword nocase wide ascii
$sa2 = "Response.AddHeader" fullword nocase wide ascii
$sa3 = "Request.InputStream.Read" nocase wide ascii
$sa4 = "Response.BinaryWrite" nocase wide ascii
$sa5 = "Socket" nocase wide ascii
$georg = "Response.Write(\"Georg says, 'All seems fine'\")"
//strings from private rule capa_asp
$tagasp_short1 = /<%[^"]/ wide ascii
// also looking for %> to reduce fp (yeah, short atom but seldom since special chars)
$tagasp_short2 = "%>" wide ascii
// classids for scripting host etc
$tagasp_classid1 = "72C24DD5-D70A-438B-8A42-98424B88AFB8" nocase wide ascii
$tagasp_classid2 = "F935DC22-1CF0-11D0-ADB9-00C04FD58A0B" nocase wide ascii
$tagasp_classid3 = "093FF999-1EA0-4079-9525-9614C3504B74" nocase wide ascii
$tagasp_classid4 = "F935DC26-1CF0-11D0-ADB9-00C04FD58A0B" nocase wide ascii
$tagasp_classid5 = "0D43FE01-F093-11CF-8940-00A0C9054228" nocase wide ascii
$tagasp_long10 = "<%@ " wide ascii
// <% eval
$tagasp_long11 = /<% \w/ nocase wide ascii
$tagasp_long12 = "<%ex" nocase wide ascii
$tagasp_long13 = "<%ev" nocase wide ascii
// <%@ LANGUAGE = VBScript.encode%>
// <%@ Language = "JScript" %>
// <%@ WebHandler Language="C#" class="Handler" %>
// <%@ WebService Language="C#" Class="Service" %>
// <%@Page Language="Jscript"%>
// <%@ Page Language = Jscript %>
// <%@PAGE LANGUAGE=JSCRIPT%>
// <%@ Page Language="Jscript" validateRequest="false" %>
// <%@ Page Language = Jscript %>
// <%@ Page Language="C#" %>
// <%@ Page Language="VB" ContentType="text/html" validaterequest="false" AspCompat="true" Debug="true" %>
// <script runat="server" language="JScript">
// <SCRIPT RUNAT=SERVER LANGUAGE=JSCRIPT>
// <SCRIPT RUNAT=SERVER LANGUAGE=JSCRIPT>
// <msxsl:script language="JScript" ...
$tagasp_long20 = /<(%|script|msxsl:script).{0,60}language="?(vb|jscript|c#)/ nocase wide ascii
$tagasp_long32 = /<script\s{1,30}runat=/ wide ascii
$tagasp_long33 = /<SCRIPT\s{1,30}RUNAT=/ wide ascii
// avoid hitting php
$php1 = "<?php"
$php2 = "<?="
// avoid hitting jsp
$jsp1 = "=\"java." wide ascii
$jsp2 = "=\"javax." wide ascii
$jsp3 = "java.lang." wide ascii
$jsp4 = "public" fullword wide ascii
$jsp5 = "throws" fullword wide ascii
$jsp6 = "getValue" fullword wide ascii
$jsp7 = "getBytes" fullword wide ascii
$perl1 = "PerlScript" fullword
condition:
filesize < 300KB and (
(
any of ( $tagasp_long* ) or
// TODO : yara_push_private_rules.py doesn't do private rules in private rules yet
any of ( $tagasp_classid* ) or
(
$tagasp_short1 and
$tagasp_short2 in ( filesize-100..filesize )
) or (
$tagasp_short2 and (
$tagasp_short1 in ( 0..1000 ) or
$tagasp_short1 in ( filesize-1000..filesize )
)
)
) and not (
(
any of ( $perl* ) or
$php1 at 0 or
$php2 at 0
) or (
( #jsp1 + #jsp2 + #jsp3 ) > 0 and ( #jsp4 + #jsp5 + #jsp6 + #jsp7 ) > 0
)
)
)
and
( $georg or
( all of ( $sa* ) and any of ( $input_sa* ) ) )
}
This YARA rule can be deployed in the following contexts:
This rule contains 32 string patterns in its detection logic.
Here are 4 specific false positive scenarios for the Webshell regeorg aspx c# version detection rule, tailored for an enterprise environment:
Scenario: Automated Backup and Migration Tools
regeorg.aspx or similar) within the IIS web root to handle chunked data uploads and integrity checks.10.20.50.5) and restrict the rule trigger to only fire when the HTTP User-Agent header does not match known backup tool signatures (e.g., exclude VeeamAgent or Rubrik-Backup).Scenario: Scheduled Health Check & Monitoring Scripts
HTTP_METHOD is strictly GET and the response status code is 200, as webshells often involve more complex POST interactions with file uploads.Scenario: Third-Party Integration Webhooks