T1505

Server Software Component

Persistence Last updated:

Adversaries may abuse legitimate extensible development features of servers to establish persistent access to systems. Enterprise server applications include features that allow developers to write and install software or scripts to extend the main application's functionality. Adversaries exploit this by installing malicious server software components such as web shells (ASP/ASPX/PHP/JSP files granting remote command execution), SQL stored procedures (particularly xp_cmdshell for OS command execution), IIS native modules or ISAPI filters, Microsoft Exchange transport agents, terminal services DLLs, and vSphere Installation Bundles (VIBs). These components persist across reboots, blend into legitimate server traffic, and provide direct OS-level access under the context of the server process account — making them difficult to detect without proper process lineage monitoring and web root integrity controls.

What is T1505 Server Software Component?

Server Software Component (T1505) maps to the Persistence tactic — the adversary is trying to maintain their foothold in MITRE ATT&CK.

This page provides production-ready detection logic for Server Software Component, covering the data sources and telemetry it touches: Process: Process Creation, File: File Creation, Windows Registry: Windows Registry Key Modification, Microsoft Defender for Endpoint. The queries below are rated critical severity at high confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.

MITRE ATT&CK

Tactic
Persistence
Technique
T1505 Server Software Component
Canonical reference
https://attack.mitre.org/techniques/T1505/
Microsoft Sentinel / Defender
kusto
let WebServerProcesses = dynamic(["w3wp.exe","httpd.exe","nginx.exe","tomcat9.exe","tomcat.exe","java.exe","php-cgi.exe","perl.exe","python.exe","ruby.exe","node.exe","gunicorn","uvicorn"]);
let SuspiciousChildren = dynamic(["cmd.exe","powershell.exe","pwsh.exe","wscript.exe","cscript.exe","mshta.exe","rundll32.exe","regsvr32.exe","certutil.exe","bitsadmin.exe","net.exe","net1.exe","whoami.exe","hostname.exe","ipconfig.exe","systeminfo.exe","nltest.exe","arp.exe","curl.exe","wget.exe","ping.exe","tracert.exe","nslookup.exe","sc.exe"]);
let WebRootPaths = dynamic(["\\inetpub\\","\\wwwroot\\","\\htdocs\\","\\webapps\\","\\public_html\\","\\web\\content\\","/var/www/","/srv/www/","/usr/share/nginx/"]);
let WebShellExtensions = dynamic([".aspx",".asp",".php",".jsp",".jspx",".cfm",".shtml",".ashx",".asmx",".phtml"]);
// Signal 1: Web server process spawning command interpreters or OS recon tools (primary web shell execution indicator)
let WebShellExecution = DeviceProcessEvents
| where Timestamp > ago(24h)
| where InitiatingProcessFileName has_any (WebServerProcesses)
| where FileName has_any (SuspiciousChildren)
| extend DetectionType = "WebShell_ChildProcess"
| extend RiskLevel = case(
    FileName in~ ("cmd.exe","powershell.exe","pwsh.exe","wscript.exe","cscript.exe","mshta.exe"), "Critical",
    FileName in~ ("rundll32.exe","regsvr32.exe","certutil.exe","bitsadmin.exe"), "High",
    "Medium"
  )
| project Timestamp, DeviceName, AccountName, DetectedFileName=FileName, ProcessCommandLine,
         ParentProcess=InitiatingProcessFileName, ParentCommandLine=InitiatingProcessCommandLine,
         FolderPath, DetectionType, RiskLevel;
// Signal 2: Suspicious script files written to web-accessible directories by non-deployment processes
let WebFileCreation = DeviceFileEvents
| where Timestamp > ago(24h)
| where ActionType in~ ("FileCreated","FileModified")
| where FolderPath has_any (WebRootPaths)
| where FileName has_any (WebShellExtensions)
| where InitiatingProcessFileName !in~ ("msiexec.exe","setup.exe","install.exe","devenv.exe","code.exe","explorer.exe","robocopy.exe","xcopy.exe","w3wp.exe")
| extend DetectionType = "SuspiciousWebFile_Written"
| extend RiskLevel = "High"
| project Timestamp, DeviceName, AccountName=InitiatingProcessAccountName,
         DetectedFileName=FileName, ProcessCommandLine=InitiatingProcessCommandLine,
         ParentProcess=InitiatingProcessFileName, ParentCommandLine=InitiatingProcessCommandLine,
         FolderPath, DetectionType, RiskLevel;
// Signal 3: Unauthorized IIS native module or ISAPI filter DLL registration via registry
let IISModuleRegistration = DeviceRegistryEvents
| where Timestamp > ago(24h)
| where ActionType in~ ("RegistryValueSet","RegistryKeyCreated")
| where RegistryKey has "SYSTEM\\CurrentControlSet\\Services\\W3SVC"
    or RegistryKey has "SOFTWARE\\Microsoft\\InetStp"
    or RegistryKey has "SYSTEM\\CurrentControlSet\\Services\\WAS"
| where RegistryValueData has ".dll"
| where InitiatingProcessFileName !in~ ("msiexec.exe","TrustedInstaller.exe","wusa.exe")
| extend DetectionType = "IIS_Module_Registered"
| extend RiskLevel = "High"
| project Timestamp, DeviceName, AccountName=InitiatingProcessAccountName,
         DetectedFileName=InitiatingProcessFileName, ProcessCommandLine=InitiatingProcessCommandLine,
         ParentProcess=InitiatingProcessParentFileName, ParentCommandLine=InitiatingProcessCommandLine,
         FolderPath=RegistryKey, DetectionType, RiskLevel;
// Combine all signals
union WebShellExecution, WebFileCreation, IISModuleRegistration
| sort by Timestamp desc

Multi-signal detection covering T1505 parent technique and its primary sub-techniques. Signal 1 identifies web shell execution by detecting web server processes (w3wp.exe, httpd, nginx, tomcat, java, python, node) spawning command interpreters or OS reconnaissance tools — the most reliable runtime indicator of active web shell use. Signal 2 catches web shell deployment by flagging script files (.aspx, .php, .jsp, etc.) written to web-accessible directories by non-installer processes. Signal 3 detects IIS Component abuse (T1505.004) by monitoring unauthorized DLL registration in W3SVC and InetStp registry keys. Together these signals provide layered coverage across the pre-execution (file drop), execution (child process), and persistence (module registration) phases of server software component attacks.

critical severity high confidence

Data Sources

Process: Process Creation File: File Creation Windows Registry: Windows Registry Key Modification Microsoft Defender for Endpoint

Required Tables

DeviceProcessEvents DeviceFileEvents DeviceRegistryEvents

False Positives

  • Java application servers (Tomcat, JBoss, WebLogic) spawning java.exe child processes for legitimate scheduled tasks, diagnostics, or maintenance operations initiated through management interfaces
  • CI/CD pipeline agents deployed on web servers that legitimately invoke cmd.exe or PowerShell during automated build and deployment workflows — typically identifiable by consistent command line patterns and timing aligned with deployment schedules
  • Content management systems (WordPress, Drupal, Joomla) executing PHP scripts that invoke system utilities for image processing, PDF generation, or file archiving via exec() or shell_exec()
  • Web-based server administration panels (WHM/cPanel, Plesk, Webmin, DirectAdmin) that by design execute OS commands via web server worker processes as part of their core functionality
  • IIS application pool identity accounts running legitimate PowerShell deployment scripts triggered by authorized web-based deployment tools (Octopus Deploy, Azure DevOps release pipelines)
  • Developer workstations with IIS Express installed locally where IDEs (Visual Studio, VS Code) write files to web root directories during normal development and compilation workflows

Sigma rule & cross-platform mapping

The detection logic for Server Software Component (T1505) above is provided in a vendor-neutral form so you can deploy it on any SIEM. The same logic is shipped here as native KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the following logsource:

logsource:
  category: process_creation
  product: windows

Browse the community-maintained Sigma rules for this technique:


Testing Methodology

Validate this detection against 5 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Deploy ASPX Web Shell to IIS Default Web Root

    Expected signal: Sysmon Event ID 11: File creation of argus_test_shell.aspx in C:\inetpub\wwwroot\ with Image=powershell.exe. Sysmon Event ID 1: Process Create with ParentImage=w3wp.exe, Image=cmd.exe, CommandLine='/c whoami' when the HTTP request is processed. IIS access log entry: GET request to /argus_test_shell.aspx?cmd=whoami from 127.0.0.1 with status 200. Security Event ID 4688 (if command line auditing enabled) showing cmd.exe with ParentProcessName=w3wp.exe.

  2. Test 2SQL Server xp_cmdshell OS Command Execution via Stored Procedure

    Expected signal: Sysmon Event ID 1: Process Create with ParentImage=sqlservr.exe, Image=cmd.exe, CommandLine='/c whoami /all' and a second instance for 'ipconfig /all'. Security Event ID 4688 (if command line auditing): cmd.exe process creation with parent sqlservr.exe. SQL Server Audit (if enabled): sp_configure modification events and xp_cmdshell execution in the SQL audit log at the configured audit destination. Windows Application Event Log: SQL Server events indicating configuration changes.

  3. Test 3IIS Native Module Registration via AppCmd

    Expected signal: Sysmon Event ID 13 (Registry Value Set): TargetObject containing HKLM\SYSTEM\CurrentControlSet\Services\W3SVC or IIS applicationHost.config path, with Details containing the version.dll path. Sysmon Event ID 1: Process Create for %SystemRoot%\System32\inetsrv\appcmd.exe with CommandLine 'install module /name:ArgusTestModule /image:...'. File Modification: %SystemRoot%\System32\inetsrv\config\applicationHost.config updated to include the new module entry. IIS Event Log: module registration event in Microsoft-Windows-IIS-W3SVC-WP/Operational.

  4. Test 4PHP Web Shell Deployment on Linux Apache/Nginx

    Expected signal: Linux auditd: open/creat syscall creating /var/www/html/argus_test.php. Process creation event: apache2 or php-fpm worker spawning /bin/sh with argument '-c id' (via shell_exec). Apache access log: GET /argus_test.php?cmd=id from 127.0.0.1 with HTTP 200 response. Syslog: process creation by www-data or apache user. If using EDR with Linux support: process creation event with parent=apache2|php-fpm and child=/bin/sh.

  5. Test 5Simulate Exchange Transport Agent Installation

    Expected signal: Sysmon Event ID 1: Process Create for powershell.exe with CommandLine containing 'Install-TransportAgent'. Windows Registry: modification to HKLM\SYSTEM\CurrentControlSet\Services\MSExchangeTransport with new agent entry. Exchange Application Event Log: transport agent registration events in the MSExchangeTransport source. Sysmon Event ID 11: if the DLL is written to disk first. PowerShell ScriptBlock Logging Event ID 4104: full Install-TransportAgent command with assembly path.


Response Playbook

Triage

  1. Identify the web server process involved and its hosting context: for IIS (w3wp.exe), run 'Get-Process w3wp | ForEach-Object { $_.Id + " -> " + (Get-Item IIS:\AppPools\*).Name }' or check IIS Manager to determine which application pool and site the worker serves — this identifies the targeted web application
  2. Examine the child process command line in full: determine if the spawned cmd.exe or PowerShell command performs reconnaissance (whoami, ipconfig, systeminfo, net user /domain), payload staging (certutil -urlcache, bitsadmin /transfer, curl to external IP), or lateral movement (net use, sc create, reg add) — command purpose determines severity and response urgency
  3. Correlate the alert timestamp against IIS access logs (C:\inetpub\logs\LogFiles\W3SVC*\u_ex*.log) or Apache/Nginx logs — search for POST requests to .aspx/.php/.jsp files from external source IPs that returned HTTP 200 around the alert time: 'Select-String -Path C:\inetpub\logs\LogFiles\W3SVC*\*.log -Pattern "POST.*\.aspx.*200"'
  4. If Signal 2 fired (file created in web root), immediately inspect the file content for web shell indicators: 'Get-Content <path> | Select-String -Pattern "Request|Response|exec|system|eval|shell_exec|passthru|proc_open|Runtime\.exec|cmd|ProcessStartInfo"' — also check NTFS timestamps and Zone.Identifier alternate data stream to determine if the file was downloaded
  5. Determine initial access vector: review web application logs for exploitation patterns preceding the shell creation — SQL injection patterns, path traversal attempts, deserialization payloads (gadget chains in JSON/XML), or file upload abuse in the hours/days before the web shell appeared
  6. Check for post-exploitation activity beyond the immediate alert: search DeviceProcessEvents for any additional process creation by w3wp.exe, httpd, or java.exe in the past 72 hours, and review DeviceNetworkEvents for outbound connections from those same processes to external IPs

Containment

  1. Immediately block external network access to the web server at the perimeter firewall or WAF if active web shell exploitation is confirmed — this severs the attacker's access channel while preserving the system for forensic investigation
  2. If lateral movement is evidenced (connections to internal SMB/RDP/WinRM, net use commands, pass-the-hash indicators), escalate to full network isolation via EDR host isolation or emergency VLAN quarantine — do not allow the compromised server to reach internal systems
  3. Delete or rename the identified web shell file to stop further execution: 'Remove-Item C:\inetpub\wwwroot\<shellname>.aspx -Force' — document the full file path, hash (Get-FileHash), and raw content before deletion for forensic preservation
  4. Reset all credentials that ran under the compromised application pool identity and web server service account — enumerate: 'Get-WebConfiguration system.applicationHost/applicationPools/add | Select Name, @{n="User";e={$_.processModel.userName}}' — then reset passwords and revoke active tokens for all identified accounts
  5. Block attacker source IPs identified from web access logs at the WAF and perimeter firewall; also block any C2 domains or external IPs that the web shell contacted — submit indicators to threat intelligence platform for broader organizational blocking
  6. If an IIS module was registered (Signal 3), remove it: '%systemroot%\system32\inetsrv\appcmd.exe list module' to enumerate, then 'appcmd.exe uninstall module /module.name:"<ModuleName>"', followed by 'iisreset /restart' — verify the DLL file on disk has been removed or quarantined

Evidence Collection

  1. IIS access logs — C:\inetpub\logs\LogFiles\W3SVC<site_id>\u_ex<YYYYMMDD>.log — W3C Extended Log Format recording cs-uri-stem (URL path), cs-uri-query (query string with shell commands), c-ip (attacker source IP), sc-status (200=success), cs(User-Agent), and time-taken; collect at minimum 30 days for timeline reconstruction
  2. Web shell file itself — full content, MD5 and SHA256 hashes (Get-FileHash -Algorithm SHA256), NTFS $STANDARD_INFORMATION and $FILE_NAME timestamps via 'fsutil usn readjournal C:' or Autopsy, and Zone.Identifier ADS ('Get-Item <path> -Stream *') indicating if the file was downloaded
  3. IIS worker process memory dump — if the worker process is still running and may contain in-memory payloads: 'procdump.exe -ma <w3wp_pid> w3wp_<pid>.dmp' — may contain decoded web shell code, encryption keys, or staged payloads not visible on disk
  4. Windows Event Logs — collect System, Application, Security (Event IDs 4688 for process creation, 4624/4625 for logon events, 4697/7045 for service installation), and Microsoft-Windows-IIS-W3SVC-WP/Operational logs from the affected server
  5. Sysmon telemetry — Event IDs 1 (process creation with full command lines), 3 (network connections from web server processes), 7 (DLL image loads by w3wp.exe or httpd), 11 (file creation in web roots), 13 (registry modifications to IIS keys), 22 (DNS queries initiated by web server processes)
  6. Prefetch files — C:\Windows\Prefetch\W3WP.EXE-*.pf and CMD.EXE-*.pf — contain execution timestamps and lists of DLLs/files accessed, helping establish timeline and identify additional payloads loaded by the web server process
  7. NTFS MFT and $USN Journal — use MFTECmd.exe or analyzeMFT to enumerate all file creation events in web root directories and correlate timestamps with access log entries to identify web shell drop time precisely

Escalation Criteria

  • ! Web server process spawned cmd.exe or PowerShell AND concurrent outbound network connections to external public IPs were detected from that same process — confirms active C2 channel operating through the web shell
  • ! Evidence of lateral movement originating from the web server: net use or net view commands targeting internal hosts, SMB connections (port 445) to domain controllers or file servers, or RDP/WinRM connections to internal systems from the web server's IP
  • ! Credential-harvesting activity detected: lsass.exe memory access from a web server child process (Sysmon Event ID 10, GrantedAccess 0x1010 or 0x1410), Mimikatz indicators, or comsvcs.dll MiniDump invocation
  • ! HTTP access logs confirm successful exploitation: POST requests to the web shell file returning HTTP 200 with non-trivial response sizes from external IPs — especially if multiple source IPs are observed (shared shell or automated tool)
  • ! Multiple web shells discovered across multiple servers simultaneously, or the same web shell file hash found on more than one host — indicates systematic compromise, automated exploitation toolkit, or insider threat with broad access
  • ! Web shell has been present and active for more than 24 hours before detection — extended dwell time suggests the attacker has had time to complete reconnaissance, establish additional persistence, or exfiltrate data; treat as full incident response engagement

Investigation Guide

Forensic Artifacts

  • > IIS Logs: C:\inetpub\logs\LogFiles\W3SVC<n>\u_ex<YYYYMMDD>.log — W3C Extended Log Format; key fields: date, time, s-ip, cs-method, cs-uri-stem, cs-uri-query, s-port, c-ip, cs(User-Agent), sc-status, sc-bytes, cs-bytes, time-taken
  • > Apache/Nginx Logs: /var/log/apache2/access.log, /var/log/apache2/error.log, /var/log/nginx/access.log — Combined Log Format with request details, response codes, and upstream errors from exploit attempts
  • > Web Shell File: typically in C:\inetpub\wwwroot\ or application subdirectories — inspect for Request/Response object usage (ASP.NET), $_GET/$_POST/$_REQUEST (PHP), Runtime.exec() or ProcessBuilder (JSP), eval()/exec()/system()/passthru() patterns
  • > IIS Configuration: %SystemRoot%\System32\inetsrv\config\applicationHost.config — lists installed modules, handler mappings, application pool identities, and bound sites; baseline deviation reveals unauthorized components
  • > Windows Registry: HKLM\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\Filter DLLs — registered ISAPI filters; HKLM\SOFTWARE\Microsoft\InetStp\Components — installed IIS role services and components
  • > Exchange Transport Agents: HKLM\SYSTEM\CurrentControlSet\Services\MSExchangeTransport — agent configuration; PowerShell 'Get-TransportAgent | Select Name,Enabled,Priority,AssemblyPath' — enumerate and hash all transport agent DLLs
  • > Prefetch: C:\Windows\Prefetch\W3WP.EXE-*.pf — records execution timestamps and all DLLs loaded by IIS worker processes; malicious IIS modules appear as DLL loads from unexpected paths
  • > NTFS MFT: Use MFTECmd.exe to extract all file creation events in web root directories with precise timestamps; cross-reference with IIS access logs to identify the HTTP request that triggered file creation (web-based upload or exploitation)

Tuning Guidance

The primary false positive driver is legitimate server frameworks that spawn OS processes as part of normal operation. Before production deployment, run Signal 1 over 14 days in observation mode and catalog all legitimate web-server-to-child-process patterns in your environment. Build an exclusion table containing: (1) specific application pool names paired with expected child process patterns — e.g., 'DeploymentPool' spawning powershell.exe with a known script path is acceptable; (2) service account names associated with approved administration panels that require OS command execution; (3) Java application server patterns where java.exe spawning java.exe is expected. For Signal 2, exclude known deployment automation accounts and tool paths, and consider narrowing the alert to files created by processes with no legitimate reason to write to web roots (e.g., exclude the application pool identity account itself, which may write temporary files). For Signal 3, build an allowlist of approved IIS module DLL paths and SHA256 hashes from your gold image configuration — only alert on DLL paths or hashes absent from the allowlist. For environments with Python or Node.js APIs running on web servers, consider excluding those specific process names from Signal 1 and instead creating narrower detections focused on their specific child process combinations that would be anomalous (e.g., python.exe spawning nc.exe or bash). Enrich all alerts with IIS site name and application pool identity to provide immediate triage context.


Hunting Queries

Hunt for web server processes initiating outbound connections to public IPs on non-standard ports. Legitimate web servers accept inbound connections — outbound connections from w3wp.exe or httpd to external IPs on unusual ports strongly indicates an active web shell C2 callback, reverse shell, or data exfiltration channel. Focus on ports outside 80/443/8080/8443 to reduce noise from proxied legitimate traffic.

Hunting — KQL
kql
// Hunt for web server processes making outbound connections to public IPs on non-standard ports — C2 via web shell
let WebServerProcesses = dynamic(["w3wp.exe","httpd.exe","nginx.exe","tomcat9.exe","java.exe","php-cgi.exe","python.exe","node.exe","ruby.exe","perl.exe"]);
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName has_any (WebServerProcesses)
| where RemoteIPType == "Public"
| where RemotePort !in (80, 443, 8080, 8443, 25, 587, 465)
| summarize ConnectionCount=count(), UniqueIPs=dcount(RemoteIP), DestPorts=make_set(RemotePort),
           RemoteHosts=make_set(RemoteUrl), FirstSeen=min(Timestamp), LastSeen=max(Timestamp)
           by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine
| sort by ConnectionCount desc
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3 earliest=-7d
(Image="*\\w3wp.exe" OR Image="*\\httpd.exe" OR Image="*\\nginx.exe" OR Image="*\\tomcat*.exe" OR Image="*\\java.exe" OR Image="*\\php-cgi.exe" OR Image="*\\python.exe" OR Image="*\\node.exe")
NOT (DestinationPort=80 OR DestinationPort=443 OR DestinationPort=8080 OR DestinationPort=8443 OR DestinationPort=25 OR DestinationPort=587)
NOT (DestinationIp="10.*" OR DestinationIp="172.16.*" OR DestinationIp="192.168.*" OR DestinationIp="127.*")
| stats count as Connections, dc(DestinationIp) as UniqueIPs, values(DestinationPort) as Ports, values(DestinationHostname) as RemoteHosts, earliest(_time) as FirstSeen, latest(_time) as LastSeen by host, Image, CommandLine
| sort - Connections

Broad 30-day hunt for web-accessible script files created or modified in web root directories. The extended window catches web shells planted days or weeks before activation — a common adversary pattern to avoid temporal correlation. Cross-reference discovered files against deployment records, source control history, and file hash reputation to identify unauthorized additions that did not originate from sanctioned deployment pipelines.

Hunting — KQL
kql
// Hunt for all web-accessible script files created or modified in the past 30 days — identify unauthorized web shells
let WebRootPaths = dynamic(["\\inetpub\\","\\wwwroot\\","\\htdocs\\","\\webapps\\","\\public_html\\","/var/www/"]);
let WebShellExtensions = dynamic([".aspx",".asp",".php",".jsp",".jspx",".cfm",".ashx",".asmx",".phtml",".shtml"]);
DeviceFileEvents
| where Timestamp > ago(30d)
| where ActionType in~ ("FileCreated","FileModified")
| where FolderPath has_any (WebRootPaths)
| where FileName has_any (WebShellExtensions)
| summarize FileCount=count(), FirstSeen=min(Timestamp), LastSeen=max(Timestamp),
           CreatingProcesses=make_set(InitiatingProcessFileName),
           FilePaths=make_set(strcat(FolderPath, "\\", FileName))
           by DeviceName, InitiatingProcessAccountName
| sort by FileCount desc
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=11 earliest=-30d
(TargetFilename="*\\inetpub\\*" OR TargetFilename="*\\wwwroot\\*" OR TargetFilename="*\\htdocs\\*" OR TargetFilename="*\\webapps\\*" OR TargetFilename="*\\public_html\\*")
(TargetFilename="*.aspx" OR TargetFilename="*.asp" OR TargetFilename="*.php" OR TargetFilename="*.jsp" OR TargetFilename="*.jspx" OR TargetFilename="*.cfm" OR TargetFilename="*.ashx" OR TargetFilename="*.phtml")
| stats count as FileCount, earliest(_time) as FirstSeen, latest(_time) as LastSeen, values(Image) as CreatingProcesses, values(TargetFilename) as FilePaths by host, User
| sort - FileCount

Hunt for IIS worker processes (w3wp.exe) loading DLLs from paths outside standard Windows and Program Files directories. Malicious IIS native modules (T1505.004) typically reside in writable directories like Temp, AppData, or custom paths. Rare DLL loads (low count, few devices) from unexpected paths warrant immediate investigation — compare the DLL hash against threat intelligence and verify the file's digital signature and origin.

Hunting — KQL
kql
// Hunt for IIS worker process loading DLLs from unusual or writable paths — malicious IIS module indicator
DeviceImageLoadEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName =~ "w3wp.exe"
| where not(FolderPath has_any (
    @"C:\Windows\System32",
    @"C:\Windows\SysWOW64",
    @"C:\Program Files",
    @"C:\Program Files (x86)",
    @"C:\Windows\assembly",
    @"C:\Windows\Microsoft.NET"
  ))
| where not(SHA256 == "")  // exclude unsigned/unknown
| summarize LoadCount=count(), Devices=dcount(DeviceName), FirstLoad=min(Timestamp), LastLoad=max(Timestamp)
           by FileName, FolderPath, SHA256, InitiatingProcessCommandLine
| sort by LoadCount asc  // rare DLL loads are more suspicious
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=7 earliest=-7d Image="*\\w3wp.exe"
NOT (ImageLoaded="C:\\Windows\\System32\\*" OR ImageLoaded="C:\\Windows\\SysWOW64\\*" OR ImageLoaded="C:\\Program Files\\*" OR ImageLoaded="C:\\Program Files (x86)\\*" OR ImageLoaded="C:\\Windows\\assembly\\*" OR ImageLoaded="C:\\Windows\\Microsoft.NET\\*")
| stats count as LoadCount, dc(host) as Devices, earliest(_time) as FirstLoad, latest(_time) as LastLoad, values(host) as Hosts by ImageLoaded, Hashes
| sort LoadCount asc

Atomic Red Team Tests

Test 1 Deploy ASPX Web Shell to IIS Default Web Root
windows

Writes a minimal ASPX web shell to the IIS default web root directory using PowerShell, then sends an HTTP request to execute the 'whoami' command via the shell. This simulates T1505.003 (Web Shell) — the most common server software component attack — as used by threat groups including HAFNIUM, APT41, and various ransomware operators following web application exploitation. Requires IIS to be running on the test system.

Command

powershell
powershell.exe -Command "Set-Content -Path 'C:\inetpub\wwwroot\argus_test_shell.aspx' -Value '<%@ Page Language=\"C#\" %><%@ Import Namespace=\"System.Diagnostics\" %><% var p=new Process();p.StartInfo.FileName=\"cmd.exe\";p.StartInfo.Arguments=\"/c \"+Request[\"cmd\"];p.StartInfo.UseShellExecute=false;p.StartInfo.RedirectStandardOutput=true;p.Start();Response.Write(p.StandardOutput.ReadToEnd()); %>'" && curl -s "http://localhost/argus_test_shell.aspx?cmd=whoami"

Cleanup

powershell
powershell.exe -Command "Remove-Item -Path 'C:\inetpub\wwwroot\argus_test_shell.aspx' -Force -ErrorAction SilentlyContinue"

Expected Telemetry

Sysmon Event ID 11: File creation of argus_test_shell.aspx in C:\inetpub\wwwroot\ with Image=powershell.exe. Sysmon Event ID 1: Process Create with ParentImage=w3wp.exe, Image=cmd.exe, CommandLine='/c whoami' when the HTTP request is processed. IIS access log entry: GET request to /argus_test_shell.aspx?cmd=whoami from 127.0.0.1 with status 200. Security Event ID 4688 (if command line auditing enabled) showing cmd.exe with ParentProcessName=w3wp.exe.

Expected Detection

KQL Signal 2 (SuspiciousWebFile_Written) fires immediately on file creation — .aspx extension in wwwroot written by powershell.exe (not in exclusion list). KQL Signal 1 (WebShell_ChildProcess) fires when HTTP request executes the shell — w3wp.exe spawning cmd.exe, RiskLevel=Critical. SPL EventCode=11 alert fires on TargetFilename containing wwwroot and .aspx. SPL EventCode=1 alert fires on ParentImage=w3wp.exe with Image=cmd.exe, SeverityRating=Critical.

Test 2 SQL Server xp_cmdshell OS Command Execution via Stored Procedure
windows

Enables the xp_cmdshell extended stored procedure on a local SQL Server instance and executes an OS command, simulating T1505.001 (SQL Stored Procedures). This technique is used by adversaries who gain SQL Server access via SQL injection, stolen credentials, or direct access to execute arbitrary OS commands under the SQL Server service account context. The MSSQL service account often has elevated OS privileges, making this a critical escalation path.

Command

powershell
sqlcmd -S localhost -Q "EXEC sp_configure 'show advanced options', 1; RECONFIGURE WITH OVERRIDE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE WITH OVERRIDE; EXEC xp_cmdshell 'whoami /all'; EXEC xp_cmdshell 'ipconfig /all';"

Cleanup

powershell
sqlcmd -S localhost -Q "EXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE WITH OVERRIDE; EXEC sp_configure 'show advanced options', 0; RECONFIGURE WITH OVERRIDE;"

Expected Telemetry

Sysmon Event ID 1: Process Create with ParentImage=sqlservr.exe, Image=cmd.exe, CommandLine='/c whoami /all' and a second instance for 'ipconfig /all'. Security Event ID 4688 (if command line auditing): cmd.exe process creation with parent sqlservr.exe. SQL Server Audit (if enabled): sp_configure modification events and xp_cmdshell execution in the SQL audit log at the configured audit destination. Windows Application Event Log: SQL Server events indicating configuration changes.

Expected Detection

The default WebServerProcesses list does not include sqlservr.exe — analysts should extend the KQL dynamic array to include 'sqlservr.exe' for SQL Server environments, or create a dedicated detection rule: 'DeviceProcessEvents | where InitiatingProcessFileName =~ "sqlservr.exe" | where FileName has_any (SuspiciousChildren)'. SPL EventCode=1 alert requires adding ParentImage="*\\sqlservr.exe" to the parent image filter. The child process spawning pattern is identical to web shell execution and should be treated with equivalent severity.

Test 3 IIS Native Module Registration via AppCmd
windows

Registers a DLL as a native IIS module using the appcmd.exe IIS administration utility, simulating T1505.004 (IIS Components). Adversaries use this technique to load malicious DLLs into every IIS worker process on startup, providing persistent code execution and HTTP traffic interception capabilities that survive reboots and IIS restarts. A legitimate Windows DLL (version.dll) is used as a safe stand-in for the malicious module.

Command

powershell
%SystemRoot%\System32\inetsrv\appcmd.exe install module /name:"ArgusTestModule" /image:"%SystemRoot%\System32\version.dll" /add:true /lock:false

Cleanup

powershell
%SystemRoot%\System32\inetsrv\appcmd.exe uninstall module /module.name:"ArgusTestModule"

Expected Telemetry

Sysmon Event ID 13 (Registry Value Set): TargetObject containing HKLM\SYSTEM\CurrentControlSet\Services\W3SVC or IIS applicationHost.config path, with Details containing the version.dll path. Sysmon Event ID 1: Process Create for %SystemRoot%\System32\inetsrv\appcmd.exe with CommandLine 'install module /name:ArgusTestModule /image:...'. File Modification: %SystemRoot%\System32\inetsrv\config\applicationHost.config updated to include the new module entry. IIS Event Log: module registration event in Microsoft-Windows-IIS-W3SVC-WP/Operational.

Expected Detection

KQL Signal 3 (IIS_Module_Registered) fires on registry modification to W3SVC key with DLL in RegistryValueData — note appcmd.exe is excluded by default, so for testing purposes remove it from the exclusion list or validate via applicationHost.config monitoring instead. SPL EventCode=13 alert fires on TargetObject containing W3SVC and Details containing .dll. Real adversary module installs often bypass appcmd by making direct registry writes or using WMI, which are NOT excluded and will fire the detection as-is.

Test 4 PHP Web Shell Deployment on Linux Apache/Nginx
linux

Creates a minimal PHP web shell in the Apache or Nginx web root on a Linux system and executes a command through it via HTTP. This covers T1505.003 targeting PHP-based web applications — the most common web stack globally — as exploited against WordPress, Drupal, Laravel, and custom PHP applications. PHP web shells are the most prevalent real-world web shell type seen in incident response engagements.

Command

bash
printf '<?php if(isset($_REQUEST["cmd"])){$cmd=$_REQUEST["cmd"];$output=shell_exec($cmd);echo "<pre>".$output."</pre>";} ?>' > /var/www/html/argus_test.php && curl -s 'http://localhost/argus_test.php?cmd=id'

Cleanup

bash
rm -f /var/www/html/argus_test.php

Expected Telemetry

Linux auditd: open/creat syscall creating /var/www/html/argus_test.php. Process creation event: apache2 or php-fpm worker spawning /bin/sh with argument '-c id' (via shell_exec). Apache access log: GET /argus_test.php?cmd=id from 127.0.0.1 with HTTP 200 response. Syslog: process creation by www-data or apache user. If using EDR with Linux support: process creation event with parent=apache2|php-fpm and child=/bin/sh.

Expected Detection

Linux-platform detection: auditd rule monitoring execve syscalls from processes running as www-data/apache/nginx UIDs where the spawned process is /bin/sh or /bin/bash. Syslog-based SPL: index=syslog OR index=linux_secure with parent process apache2/php-fpm spawning sh/bash. File creation alert: inotify or auditd monitoring /var/www/html for new .php file creation by non-deployment processes. Correlate process execution events from web server UID with file creation timestamps.

Test 5 Simulate Exchange Transport Agent Installation
windows

Registers a malicious transport agent DLL with Microsoft Exchange Server using the Install-TransportAgent PowerShell cmdlet, simulating T1505.002 (Transport Agent). Adversaries use this technique to intercept all email passing through the Exchange server, enabling credential harvesting, email surveillance, and persistent access. Requires Exchange Management Shell and Exchange Server to be present. Uses a placeholder DLL path for safety.

Command

powershell
powershell.exe -Command "Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn -ErrorAction SilentlyContinue; Install-TransportAgent -Name 'ArgusTestAgent' -TransportAgentFactory 'ArgusTest.AgentFactory' -AssemblyPath 'C:\Windows\Temp\argus_test_agent.dll'"

Cleanup

powershell
powershell.exe -Command "Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn -ErrorAction SilentlyContinue; Uninstall-TransportAgent -Name 'ArgusTestAgent' -Confirm:$false"

Expected Telemetry

Sysmon Event ID 1: Process Create for powershell.exe with CommandLine containing 'Install-TransportAgent'. Windows Registry: modification to HKLM\SYSTEM\CurrentControlSet\Services\MSExchangeTransport with new agent entry. Exchange Application Event Log: transport agent registration events in the MSExchangeTransport source. Sysmon Event ID 11: if the DLL is written to disk first. PowerShell ScriptBlock Logging Event ID 4104: full Install-TransportAgent command with assembly path.

Expected Detection

KQL detection for Exchange transport agents requires monitoring DeviceRegistryEvents for modifications to MSExchangeTransport service keys and DeviceProcessEvents for powershell.exe invoking Install-TransportAgent or New-TransportAgentObject. SPL: EventCode=13 with TargetObject containing MSExchangeTransport, or EventCode=1 with CommandLine containing 'Install-TransportAgent'. Consider creating a dedicated detection: 'DeviceProcessEvents | where ProcessCommandLine has_any ("Install-TransportAgent","Enable-TransportAgent") | where InitiatingProcessFileName !in~ ("msiexec.exe","setup.exe")'.

Related Detections