Persistence
T1505 — Server Software Component
Adversaries may abuse legitimate extensible development features of servers to establish persistent access to systems. Enterprise server applications may include features that allow developers to write and install software or scripts to extend the functionality of the main application. Adversaries may install malicious components to extend and abuse server applications.
Investigate Server Software Component activity in the context of Persistence: confirm scope, affected host/identity, and whether it matches expected administrative behaviour before deciding this is benign.
Platforms
Windows, Linux, macOS, Network Devices, ESXi
Priority / status
high / draft
Evidence to collect
- Host or resource affected
- Account or identity involved
- Timestamp of the activity
- Related process, file, or network artifact
- Any preceding or follow-on alerts
D3-EHB · detect
Endpoint Health Beacon
Monitor for Endpoint Health Beacon indicators relevant to this technique.
Tooling: Defender for Endpoint
D3-FE · harden
File Encryption
Apply File Encryption to reduce this technique's viability before an incident occurs.
Tooling: Defender for Endpoint
D3-FEV · evict
File Eviction
Use File Eviction to remove the adversary's foothold once this technique is confirmed.
Tooling: Defender for Endpoint
D3-SCF · isolate
System Call Filtering
Apply System Call Filtering to contain the blast radius once this technique is observed.
Tooling: Defender for Endpoint
| ATT&CK Technique | D3FEND Technique | Practical SOC Action | Tooling |
|---|---|---|---|
| T1505 Server Software Component | Endpoint Health Beacon | Monitor for Endpoint Health Beacon indicators relevant to this technique. | Defender for Endpoint |
| T1505 Server Software Component | File Encryption | Apply File Encryption to reduce this technique's viability before an incident occurs. | Defender for Endpoint |
| T1505 Server Software Component | File Eviction | Use File Eviction to remove the adversary's foothold once this technique is confirmed. | Defender for Endpoint |
| T1505 Server Software Component | System Call Filtering | Apply System Call Filtering to contain the blast radius once this technique is observed. | Defender for Endpoint |
T1505 Server Software Component → D3FEND → SOC action
Investigation steps — Microsoft
- Review Defender for Endpoint / Defender XDR alerts and timeline for the affected host or identity.
- Check Sentinel analytics rules and incidents correlated with this technique.
- Review Entra ID sign-in and audit logs if the technique involves an identity or cloud resource.
Investigation steps — generic
- Confirm whether the observed server software component activity matches expected administrative or application behaviour.
- Identify the host, account, or resource where the activity occurred and its business criticality.
- Check for related alerts before and after this activity to reconstruct the broader intrusion timeline.
- Real detection reference: "Web Shell Installed on Web Server" -- Flags a web-accessible script file (.php/.aspx/.asp/.jsp/etc.) written to a web-accessible path by the web server process or into an upload directory - web shells must never be legitimately written this way. Zero tolerance.
Response actions
| Action | Risk | Automation safe | Approval required |
|---|---|---|---|
| Contain the affected host or account | Medium | No | Yes |
| Collect and preserve evidence | Low | Yes | No |
KQL
GEN-PS-004 — Web Shell Installed on Web Server
DeviceFileEvents
| where TimeGenerated >= ago(5m)
| where ActionType == "FileCreated"
| where FileName has_any (".php", ".aspx", ".asp", ".jsp", ".cfm", ".shtml", ".ashx", ".asmx", ".axd")
| where FolderPath has_any (
"wwwroot", "inetpub", "htdocs", "public_html", "webroot", "www",
"upload", "uploads", "files", "images", "assets", "static", "media", "content"
)
| where InitiatingProcessFileName in~ (
"w3wp.exe", "httpd.exe", "nginx.exe", "php-cgi.exe", "tomcat.exe", "java.exe",
"apache.exe", "lighttpd.exe"
)
or FolderPath has_any ("upload", "uploads", "user-content", "media")
| project
TimeGenerated, DeviceName, FileName, FolderPath, SHA256,
InitiatingProcessFileName, InitiatingProcessAccountName
| extend timestamp = TimeGenerated,
HostCustomEntity = DeviceName,
AccountCustomEntity = InitiatingProcessAccountName
| order by TimeGenerated desc GEN-IA-008 — Public-Facing App Webshell File Write
let lookback = 1h;
let correlationWindow = 15m;
let webRoots = dynamic(["\\inetpub\\wwwroot", "\\wwwroot", "\\public_html", "\\htdocs", "\\site\\wwwroot"]);
let suspiciousExtensions = dynamic(["aspx", "ashx", "asmx", "jsp", "jspx", "php", "phtml", "pl", "py", "ps1", "cmd"]);
let suspiciousNames = dynamic(["shell", "cmd", "upload", "webadmin", "backdoor", "wso", "c99", "r57", "regeorg", "tunnel"]);
let approvedDeploymentTools = dynamic(["msdeploy.exe", "git.exe", "runner.exe", "octopus.tentacle.exe", "kudu.exe", "zipdeploy.exe"]);
let fileEventsSource =
union isfuzzy=true DeviceFileEvents,
(datatable(TimeGenerated:datetime, ActionType:string, DeviceId:string, DeviceName:string, FolderPath:string, FileName:string, SHA256:string, InitiatingProcessFileName:string, InitiatingProcessCommandLine:string, InitiatingProcessAccountName:string)[]);
let iisLogsSource =
union isfuzzy=true W3CIISLog,
(datatable(TimeGenerated:datetime, sComputerName:string, cIP:string, csMethod:string, csUriStem:string, csUserName:string, scStatus:int, csUserAgent:string)[]);
let suspiciousFileWrites =
fileEventsSource
| where TimeGenerated >= ago(lookback)
| where ActionType in~ ("FileCreated", "FileModified", "FileRenamed")
| where FolderPath has_any (webRoots)
| extend FileExtension = tolower(tostring(split(FileName, ".")[-1])),
FileNameLower = tolower(FileName),
InitiatingProcessFileName = tostring(InitiatingProcessFileName)
| where FileExtension in (suspiciousExtensions) or FileNameLower has_any (suspiciousNames)
| where InitiatingProcessFileName !in~ (approvedDeploymentTools)
| project WriteTime = TimeGenerated, DeviceId, DeviceName, FolderPath, FileName, FileExtension, SHA256,
InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName;
let inboundWrites =
iisLogsSource
| where TimeGenerated >= ago(lookback)
| where csMethod in~ ("POST", "PUT", "PATCH")
| where csUriStem has_any ("/upload", "/admin", "/editor", "/api", "/wp-admin", "/owa", "/ecp")
| project RequestTime = TimeGenerated, DeviceName = sComputerName, SrcIP = cIP, csMethod, csUriStem, csUserName, scStatus, csUserAgent;
suspiciousFileWrites
| join kind=leftouter inboundWrites on DeviceName
| where isnull(RequestTime) or abs(datetime_diff("minute", WriteTime, RequestTime)) <= toint(correlationWindow / 1m)
| extend CorrelatedInboundRequest = isnotempty(RequestTime)
| project
TimeGenerated = coalesce(RequestTime, WriteTime),
WriteTime,
RequestTime,
DeviceId,
DeviceName,
FolderPath,
FileName,
FileExtension,
SHA256,
InitiatingProcessFileName,
InitiatingProcessCommandLine,
InitiatingProcessAccountName,
CorrelatedInboundRequest,
SrcIP,
csMethod,
csUriStem,
csUserName,
scStatus,
csUserAgent
| extend timestamp = TimeGenerated,
HostCustomEntity = DeviceName,
AccountCustomEntity = InitiatingProcessAccountName,
IPCustomEntity = SrcIP
| order by TimeGenerated desc 30206b45-75d2-4c6a-87c5-f0861c1f2870 — CYFIRMA - Attack Surface - Configuration High Rule
// High Severity - Attack Surface - Misconfiguration Detected
let timeFrame = 5m;
CyfirmaASConfigurationAlerts_CL
| where severity == 'Critical' and TimeGenerated between (ago(timeFrame) .. now())
| extend
Description=description,
FirstSeen=first_seen,
LastSeen=last_seen,
RiskScore=risk_score,
Domain=sub_domain,
TopDomain=top_domain,
NetworkIP=ip,
AlertUID=alert_uid,
UID=uid,
Softwares=software,
WebAppFirewall=web_app_firewall,
ClickJackingDefence=click_jacking_defence,
ContentSecurityPolicy=content_security_policy,
CookieXssProtection=cookie_xss_protection,
DataInjectionDefence=data_injection_defence,
DomainStatus=domain_status,
MissingEPPCodes=missing_epp_codes,
SecureCookie=secure_cookie,
SetCookieHttpsOnly=set_cookie_https_only,
XFrameOptions=x_frame_options,
X_XssProtection=x_xss_protection,
ProviderName='CYFIRMA',
ProductName='DeCYFIR/DeTCT'
| project
TimeGenerated,
Description,
Domain,
TopDomain,
RiskScore,
FirstSeen,
LastSeen,
NetworkIP,
AlertUID,
UID,
Softwares,
WebAppFirewall,
ClickJackingDefence,
ContentSecurityPolicy,
CookieXssProtection,
DataInjectionDefence,
DomainStatus,
MissingEPPCodes,
SecureCookie,
SetCookieHttpsOnly,
XFrameOptions,
X_XssProtection,
ProviderName,
ProductName Escalation criteria
- Server Software Component activity observed on a privileged account or critical system.
- Activity follows or precedes other suspicious behaviour in the same investigation.
- Automated triage cannot confidently rule out malicious intent.
False positive considerations
- Legitimate administrative or maintenance activity matching this pattern.
- Approved security testing or red team exercise.
- Known benign software producing similar telemetry.
# T1505 - Server Software Component
## SOC Recommendation
Investigate Server Software Component activity in the context of Persistence: confirm scope, affected host/identity, and whether it matches expected administrative behaviour before deciding this is benign.
## D3FEND Mappings
| D3FEND Technique | Relationship | Practical SOC Action |
|---|---|---|
| Endpoint Health Beacon | Detect | Monitor for Endpoint Health Beacon indicators relevant to this technique. |
| File Encryption | Harden | Apply File Encryption to reduce this technique's viability before an incident occurs. |
| File Eviction | Evict | Use File Eviction to remove the adversary's foothold once this technique is confirmed. |
| System Call Filtering | Isolate | Apply System Call Filtering to contain the blast radius once this technique is observed. |
## Investigation Steps
1. Review Defender for Endpoint / Defender XDR alerts and timeline for the affected host or identity.
2. Check Sentinel analytics rules and incidents correlated with this technique.
3. Review Entra ID sign-in and audit logs if the technique involves an identity or cloud resource.
## Evidence to Collect
- Host or resource affected
- Account or identity involved
- Timestamp of the activity
- Related process, file, or network artifact
- Any preceding or follow-on alerts
## Response Actions
| Action | Risk | Automation Safe | Approval Required |
|---|---|---|---|
| Contain the affected host or account | Medium | No | Yes |
| Collect and preserve evidence | Low | Yes | No |
## KQL
```kql
DeviceFileEvents
| where TimeGenerated >= ago(5m)
| where ActionType == "FileCreated"
| where FileName has_any (".php", ".aspx", ".asp", ".jsp", ".cfm", ".shtml", ".ashx", ".asmx", ".axd")
| where FolderPath has_any (
"wwwroot", "inetpub", "htdocs", "public_html", "webroot", "www",
"upload", "uploads", "files", "images", "assets", "static", "media", "content"
)
| where InitiatingProcessFileName in~ (
"w3wp.exe", "httpd.exe", "nginx.exe", "php-cgi.exe", "tomcat.exe", "java.exe",
"apache.exe", "lighttpd.exe"
)
or FolderPath has_any ("upload", "uploads", "user-content", "media")
| project
TimeGenerated, DeviceName, FileName, FolderPath, SHA256,
InitiatingProcessFileName, InitiatingProcessAccountName
| extend timestamp = TimeGenerated,
HostCustomEntity = DeviceName,
AccountCustomEntity = InitiatingProcessAccountName
| order by TimeGenerated desc
```
```kql
let lookback = 1h;
let correlationWindow = 15m;
let webRoots = dynamic(["\\inetpub\\wwwroot", "\\wwwroot", "\\public_html", "\\htdocs", "\\site\\wwwroot"]);
let suspiciousExtensions = dynamic(["aspx", "ashx", "asmx", "jsp", "jspx", "php", "phtml", "pl", "py", "ps1", "cmd"]);
let suspiciousNames = dynamic(["shell", "cmd", "upload", "webadmin", "backdoor", "wso", "c99", "r57", "regeorg", "tunnel"]);
let approvedDeploymentTools = dynamic(["msdeploy.exe", "git.exe", "runner.exe", "octopus.tentacle.exe", "kudu.exe", "zipdeploy.exe"]);
let fileEventsSource =
union isfuzzy=true DeviceFileEvents,
(datatable(TimeGenerated:datetime, ActionType:string, DeviceId:string, DeviceName:string, FolderPath:string, FileName:string, SHA256:string, InitiatingProcessFileName:string, InitiatingProcessCommandLine:string, InitiatingProcessAccountName:string)[]);
let iisLogsSource =
union isfuzzy=true W3CIISLog,
(datatable(TimeGenerated:datetime, sComputerName:string, cIP:string, csMethod:string, csUriStem:string, csUserName:string, scStatus:int, csUserAgent:string)[]);
let suspiciousFileWrites =
fileEventsSource
| where TimeGenerated >= ago(lookback)
| where ActionType in~ ("FileCreated", "FileModified", "FileRenamed")
| where FolderPath has_any (webRoots)
| extend FileExtension = tolower(tostring(split(FileName, ".")[-1])),
FileNameLower = tolower(FileName),
InitiatingProcessFileName = tostring(InitiatingProcessFileName)
| where FileExtension in (suspiciousExtensions) or FileNameLower has_any (suspiciousNames)
| where InitiatingProcessFileName !in~ (approvedDeploymentTools)
| project WriteTime = TimeGenerated, DeviceId, DeviceName, FolderPath, FileName, FileExtension, SHA256,
InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName;
let inboundWrites =
iisLogsSource
| where TimeGenerated >= ago(lookback)
| where csMethod in~ ("POST", "PUT", "PATCH")
| where csUriStem has_any ("/upload", "/admin", "/editor", "/api", "/wp-admin", "/owa", "/ecp")
| project RequestTime = TimeGenerated, DeviceName = sComputerName, SrcIP = cIP, csMethod, csUriStem, csUserName, scStatus, csUserAgent;
suspiciousFileWrites
| join kind=leftouter inboundWrites on DeviceName
| where isnull(RequestTime) or abs(datetime_diff("minute", WriteTime, RequestTime)) <= toint(correlationWindow / 1m)
| extend CorrelatedInboundRequest = isnotempty(RequestTime)
| project
TimeGenerated = coalesce(RequestTime, WriteTime),
WriteTime,
RequestTime,
DeviceId,
DeviceName,
FolderPath,
FileName,
FileExtension,
SHA256,
InitiatingProcessFileName,
InitiatingProcessCommandLine,
InitiatingProcessAccountName,
CorrelatedInboundRequest,
SrcIP,
csMethod,
csUriStem,
csUserName,
scStatus,
csUserAgent
| extend timestamp = TimeGenerated,
HostCustomEntity = DeviceName,
AccountCustomEntity = InitiatingProcessAccountName,
IPCustomEntity = SrcIP
| order by TimeGenerated desc
```
```kql
// High Severity - Attack Surface - Misconfiguration Detected
let timeFrame = 5m;
CyfirmaASConfigurationAlerts_CL
| where severity == 'Critical' and TimeGenerated between (ago(timeFrame) .. now())
| extend
Description=description,
FirstSeen=first_seen,
LastSeen=last_seen,
RiskScore=risk_score,
Domain=sub_domain,
TopDomain=top_domain,
NetworkIP=ip,
AlertUID=alert_uid,
UID=uid,
Softwares=software,
WebAppFirewall=web_app_firewall,
ClickJackingDefence=click_jacking_defence,
ContentSecurityPolicy=content_security_policy,
CookieXssProtection=cookie_xss_protection,
DataInjectionDefence=data_injection_defence,
DomainStatus=domain_status,
MissingEPPCodes=missing_epp_codes,
SecureCookie=secure_cookie,
SetCookieHttpsOnly=set_cookie_https_only,
XFrameOptions=x_frame_options,
X_XssProtection=x_xss_protection,
ProviderName='CYFIRMA',
ProductName='DeCYFIR/DeTCT'
| project
TimeGenerated,
Description,
Domain,
TopDomain,
RiskScore,
FirstSeen,
LastSeen,
NetworkIP,
AlertUID,
UID,
Softwares,
WebAppFirewall,
ClickJackingDefence,
ContentSecurityPolicy,
CookieXssProtection,
DataInjectionDefence,
DomainStatus,
MissingEPPCodes,
SecureCookie,
SetCookieHttpsOnly,
XFrameOptions,
X_XssProtection,
ProviderName,
ProductName
```
## Escalation Criteria
- Server Software Component activity observed on a privileged account or critical system.
- Activity follows or precedes other suspicious behaviour in the same investigation.
- Automated triage cannot confidently rule out malicious intent.
## False Positive Considerations
- Legitimate administrative or maintenance activity matching this pattern.
- Approved security testing or red team exercise.
- Known benign software producing similar telemetry.
Generated by SOC Response Atlas by Basyrix.
Want to push this directly to Confluence? Upgrade to Basyrix Pro.
- /api/techniques/T1505.json
- /api/recommendations/T1505.json
- /api/d3fend/T1505.json
- /api/mappings/T1505.json
- /api/confluence/T1505.md
Example curl:
curl https://atlas.basyrix.com/api/recommendations/T1505.json Response:
{
"technique_id": "T1505",
"name": "Server Software Component",
"priority": "high",
"status": "draft",
"version": "0.1.0",
"last_reviewed": "2026-07-23",
"generated_by": "SOC Response Atlas by Basyrix",
"tactics": [
"Persistence"
],
"platforms": [
"Windows",
"Linux",
"macOS",
"Network Devices",
"ESXi"
],
"summary": "Adversaries may abuse legitimate extensible development features of servers to establish persistent access to systems. Enterprise server applications may include features that allow developers to write and install software or scripts to extend the functionality of the main application. Adversaries may install malicious components to extend and abuse server applications.",
"soc_recommendation": "Investigate Server Software Component activity in the context of Persistence: confirm scope, affected host/identity, and whether it matches expected administrative behaviour before deciding this is benign.",
"d3fend_mappings": [
{
"id": "D3-EHB",
"name": "Endpoint Health Beacon",
"relationship": "detect",
"practical_action": "Monitor for Endpoint Health Beacon indicators relevant to this technique.",
"tooling": [
"Defender for Endpoint"
]
},
{
"id": "D3-FE",
"name": "File Encryption",
"relationship": "harden",
"practical_action": "Apply File Encryption to reduce this technique's viability before an incident occurs.",
"tooling": [
"Defender for Endpoint"
]
},
{
"id": "D3-FEV",
"name": "File Eviction",
"relationship": "evict",
"practical_action": "Use File Eviction to remove the adversary's foothold once this technique is confirmed.",
"tooling": [
"Defender for Endpoint"
]
},
{
"id": "D3-SCF",
"name": "System Call Filtering",
"relationship": "isolate",
"practical_action": "Apply System Call Filtering to contain the blast radius once this technique is observed.",
"tooling": [
"Defender for Endpoint"
]
}
],
"investigation_steps": {
"microsoft": [
"Review Defender for Endpoint / Defender XDR alerts and timeline for the affected host or identity.",
"Check Sentinel analytics rules and incidents correlated with this technique.",
"Review Entra ID sign-in and audit logs if the technique involves an identity or cloud resource."
],
"generic": [
"Confirm whether the observed server software component activity matches expected administrative or application behaviour.",
"Identify the host, account, or resource where the activity occurred and its business criticality.",
"Check for related alerts before and after this activity to reconstruct the broader intrusion timeline.",
"Real detection reference: \"Web Shell Installed on Web Server\" -- Flags a web-accessible script file (.php/.aspx/.asp/.jsp/etc.) written to a web-accessible path by the web server process or into an upload directory - web shells must never be legitimately written this way. Zero tolerance."
]
},
"evidence_to_collect": [
"Host or resource affected",
"Account or identity involved",
"Timestamp of the activity",
"Related process, file, or network artifact",
"Any preceding or follow-on alerts"
],
"response_actions": [
{
"name": "Contain the affected host or account",
"category": "Containment",
"risk": "Medium",
"automation_safe": false,
"approval_required": true,
"tool": "Defender for Endpoint / Entra ID",
"notes": "Requires approval -- confirm malicious intent before isolating a host or disabling an account."
},
{
"name": "Collect and preserve evidence",
"category": "Investigation",
"risk": "Low",
"automation_safe": true,
"approval_required": false,
"tool": "Defender for Endpoint",
"notes": "Safe -- read-only evidence collection."
}
],
"queries": {
"kql": [
{
"name": "GEN-PS-004 — Web Shell Installed on Web Server",
"description": "Flags a web-accessible script file (.php/.aspx/.asp/.jsp/etc.) written to a web-accessible path by the web server process or into an upload directory - web shells must never be legitimately written this way. Zero tolerance. (Source: Bell Integration baseline detection library, mapped via sub-technique T1505.003.)",
"query": "DeviceFileEvents\n| where TimeGenerated >= ago(5m)\n| where ActionType == \"FileCreated\"\n| where FileName has_any (\".php\", \".aspx\", \".asp\", \".jsp\", \".cfm\", \".shtml\", \".ashx\", \".asmx\", \".axd\")\n| where FolderPath has_any (\n \"wwwroot\", \"inetpub\", \"htdocs\", \"public_html\", \"webroot\", \"www\",\n \"upload\", \"uploads\", \"files\", \"images\", \"assets\", \"static\", \"media\", \"content\"\n)\n| where InitiatingProcessFileName in~ (\n \"w3wp.exe\", \"httpd.exe\", \"nginx.exe\", \"php-cgi.exe\", \"tomcat.exe\", \"java.exe\",\n \"apache.exe\", \"lighttpd.exe\"\n)\n or FolderPath has_any (\"upload\", \"uploads\", \"user-content\", \"media\")\n| project\n TimeGenerated, DeviceName, FileName, FolderPath, SHA256,\n InitiatingProcessFileName, InitiatingProcessAccountName\n| extend timestamp = TimeGenerated,\n HostCustomEntity = DeviceName,\n AccountCustomEntity = InitiatingProcessAccountName\n| order by TimeGenerated desc"
},
{
"name": "GEN-IA-008 — Public-Facing App Webshell File Write",
"description": "Replaces the stale March 2021 ProxyLogon IOC feed rule with a behavior-based detector for webshell-like files written under public web roots, optionally correlated with recent inbound upload/admin requests. (Source: Bell Integration baseline detection library, mapped via sub-technique T1505.003.)",
"query": "let lookback = 1h;\nlet correlationWindow = 15m;\nlet webRoots = dynamic([\"\\\\inetpub\\\\wwwroot\", \"\\\\wwwroot\", \"\\\\public_html\", \"\\\\htdocs\", \"\\\\site\\\\wwwroot\"]);\nlet suspiciousExtensions = dynamic([\"aspx\", \"ashx\", \"asmx\", \"jsp\", \"jspx\", \"php\", \"phtml\", \"pl\", \"py\", \"ps1\", \"cmd\"]);\nlet suspiciousNames = dynamic([\"shell\", \"cmd\", \"upload\", \"webadmin\", \"backdoor\", \"wso\", \"c99\", \"r57\", \"regeorg\", \"tunnel\"]);\nlet approvedDeploymentTools = dynamic([\"msdeploy.exe\", \"git.exe\", \"runner.exe\", \"octopus.tentacle.exe\", \"kudu.exe\", \"zipdeploy.exe\"]);\nlet fileEventsSource =\n union isfuzzy=true DeviceFileEvents,\n (datatable(TimeGenerated:datetime, ActionType:string, DeviceId:string, DeviceName:string, FolderPath:string, FileName:string, SHA256:string, InitiatingProcessFileName:string, InitiatingProcessCommandLine:string, InitiatingProcessAccountName:string)[]);\nlet iisLogsSource =\n union isfuzzy=true W3CIISLog,\n (datatable(TimeGenerated:datetime, sComputerName:string, cIP:string, csMethod:string, csUriStem:string, csUserName:string, scStatus:int, csUserAgent:string)[]);\nlet suspiciousFileWrites =\n fileEventsSource\n | where TimeGenerated >= ago(lookback)\n | where ActionType in~ (\"FileCreated\", \"FileModified\", \"FileRenamed\")\n | where FolderPath has_any (webRoots)\n | extend FileExtension = tolower(tostring(split(FileName, \".\")[-1])),\n FileNameLower = tolower(FileName),\n InitiatingProcessFileName = tostring(InitiatingProcessFileName)\n | where FileExtension in (suspiciousExtensions) or FileNameLower has_any (suspiciousNames)\n | where InitiatingProcessFileName !in~ (approvedDeploymentTools)\n | project WriteTime = TimeGenerated, DeviceId, DeviceName, FolderPath, FileName, FileExtension, SHA256,\n InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName;\nlet inboundWrites =\n iisLogsSource\n | where TimeGenerated >= ago(lookback)\n | where csMethod in~ (\"POST\", \"PUT\", \"PATCH\")\n | where csUriStem has_any (\"/upload\", \"/admin\", \"/editor\", \"/api\", \"/wp-admin\", \"/owa\", \"/ecp\")\n | project RequestTime = TimeGenerated, DeviceName = sComputerName, SrcIP = cIP, csMethod, csUriStem, csUserName, scStatus, csUserAgent;\nsuspiciousFileWrites\n| join kind=leftouter inboundWrites on DeviceName\n| where isnull(RequestTime) or abs(datetime_diff(\"minute\", WriteTime, RequestTime)) <= toint(correlationWindow / 1m)\n| extend CorrelatedInboundRequest = isnotempty(RequestTime)\n| project\n TimeGenerated = coalesce(RequestTime, WriteTime),\n WriteTime,\n RequestTime,\n DeviceId,\n DeviceName,\n FolderPath,\n FileName,\n FileExtension,\n SHA256,\n InitiatingProcessFileName,\n InitiatingProcessCommandLine,\n InitiatingProcessAccountName,\n CorrelatedInboundRequest,\n SrcIP,\n csMethod,\n csUriStem,\n csUserName,\n scStatus,\n csUserAgent\n| extend timestamp = TimeGenerated,\n HostCustomEntity = DeviceName,\n AccountCustomEntity = InitiatingProcessAccountName,\n IPCustomEntity = SrcIP\n| order by TimeGenerated desc"
},
{
"name": "30206b45-75d2-4c6a-87c5-f0861c1f2870 — CYFIRMA - Attack Surface - Configuration High Rule",
"description": "This alert is generated when CYFIRMA detects a critical misconfiguration in a public-facing asset or service. Such misconfigurations may include exposed admin interfaces, default credentials, open directory listings, or insecure protocols, which significantly increase the attack surface.\" (Source: Microsoft's official Azure-Sentinel Detections (MIT licensed).)",
"query": "// High Severity - Attack Surface - Misconfiguration Detected\nlet timeFrame = 5m;\nCyfirmaASConfigurationAlerts_CL\n| where severity == 'Critical' and TimeGenerated between (ago(timeFrame) .. now())\n| extend\n Description=description,\n FirstSeen=first_seen,\n LastSeen=last_seen,\n RiskScore=risk_score,\n Domain=sub_domain,\n TopDomain=top_domain,\n NetworkIP=ip,\n AlertUID=alert_uid,\n UID=uid,\n Softwares=software,\n WebAppFirewall=web_app_firewall,\n ClickJackingDefence=click_jacking_defence,\n ContentSecurityPolicy=content_security_policy,\n CookieXssProtection=cookie_xss_protection,\n DataInjectionDefence=data_injection_defence,\n DomainStatus=domain_status,\n MissingEPPCodes=missing_epp_codes,\n SecureCookie=secure_cookie,\n SetCookieHttpsOnly=set_cookie_https_only,\n XFrameOptions=x_frame_options,\n X_XssProtection=x_xss_protection,\n ProviderName='CYFIRMA',\n ProductName='DeCYFIR/DeTCT'\n| project\n TimeGenerated,\n Description,\n Domain,\n TopDomain,\n RiskScore,\n FirstSeen,\n LastSeen,\n NetworkIP,\n AlertUID,\n UID,\n Softwares,\n WebAppFirewall,\n ClickJackingDefence,\n ContentSecurityPolicy,\n CookieXssProtection,\n DataInjectionDefence,\n DomainStatus,\n MissingEPPCodes,\n SecureCookie,\n SetCookieHttpsOnly,\n XFrameOptions,\n X_XssProtection,\n ProviderName,\n ProductName"
}
],
"spl": [],
"esql": [
{
"name": "f3ac6734-7e52-4a0d-90b7-6847bf4308f2 — Web Server Potential Command Injection Request",
"description": "(ESQL) This rule detects potential command injection attempts via web server requests by identifying URLs that contain suspicious patterns commonly associated with command execution payloads. Attackers may exploit vulnerabilities in web applications to inject and execute arbitrary commands on the server, often using interpreters like Python, Perl, Ruby, PHP, or shell commands... (Source: Elastic's official detection-rules repository (Elastic License v2).)",
"query": "from logs-nginx.access-*, logs-apache.access-*, logs-apache_tomcat.access-*, logs-iis.access-*, logs-traefik.access-*\n| where\n // Limit to 200 response code to reduce noise\n http.response.status_code == 200\n\n| eval Esql.url_original_to_lower = to_lower(url.original)\n\n| eval Esql.contains_interpreter = case(Esql.url_original_to_lower like \"*python* -c*\" or Esql.url_original_to_lower like \"*perl* -e*\" or Esql.url_original_to_lower like \"*ruby* -e*\" or Esql.url_original_to_lower like \"*ruby* -rsocket*\" or Esql.url_original_to_lower like \"*lua* -e*\" or Esql.url_original_to_lower like \"*php* -r*\" or Esql.url_original_to_lower like \"*node* -e*\", 1, 0)\n| eval Esql.contains_shell = case(Esql.url_original_to_lower like \"*/bin/bash*\" or Esql.url_original_to_lower like \"*bash*-c*\" or Esql.url_original_to_lower like \"*/bin/sh*\" or Esql.url_original_to_lower rlike \"*sh.{1,2}-c*\", 1, 0)\n| eval Esql.contains_nc = case(Esql.url_original_to_lower like \"*netcat*\" or Esql.url_original_to_lower like \"*ncat*\" or Esql.url_original_to_lower rlike \"\"\".*nc.{1,2}[0-9]{1,3}(\\.[0-9]{1,3}){3}.{1,2}[0-9]{1,5}.*\"\"\" or Esql.url_original_to_lower like \"*nc.openbsd*\" or Esql.url_original_to_lower like \"*nc.traditional*\" or Esql.url_original_to_lower like \"*socat*\", 1, 0)\n| eval Esql.contains_devtcp = case(Esql.url_original_to_lower like \"*/dev/tcp/*\" or Esql.url_original_to_lower like \"*/dev/udp/*\", 1, 0)\n| eval Esql.contains_helpers = case((Esql.url_original_to_lower like \"*/bin/*\" or Esql.url_original_to_lower like \"*/usr/bin/*\") and (Esql.url_original_to_lower like \"*mkfifo*\" or Esql.url_original_to_lower like \"*nohup*\" or Esql.url_original_to_lower like \"*setsid*\" or Esql.url_original_to_lower like \"*busybox*\"), 1, 0)\n| eval Esql.contains_sus_cli = case(Esql.url_original_to_lower like \"*import*pty*spawn*\" or Esql.url_original_to_lower like \"*import*subprocess*call*\" or Esql.url_original_to_lower like \"*tcpsocket.new*\" or Esql.url_original_to_lower like \"*tcpsocket.open*\" or Esql.url_original_to_lower like \"*io.popen*\" or Esql.url_original_to_lower like \"*os.execute*\" or Esql.url_original_to_lower like \"*fsockopen*\", 1, 0)\n| eval Esql.contains_privileges = case(Esql.url_original_to_lower like \"*chmod*+x\", 1, 0)\n| eval Esql.contains_downloader = case(Esql.url_original_to_lower like \"*curl *\" or Esql.url_original_to_lower like \"*wget *\" , 1, 0)\n| eval Esql.contains_file_read_keywords = case(Esql.url_original_to_lower like \"*/etc/shadow*\" or Esql.url_original_to_lower like \"*/etc/passwd*\" or Esql.url_original_to_lower like \"*/root/.ssh/*\" or Esql.url_original_to_lower like \"*/home/*/.ssh/*\" or Esql.url_original_to_lower like \"*~/.ssh/*\" or Esql.url_original_to_lower like \"*/proc/self/environ*\", 1, 0)\n| eval Esql.contains_base64_cmd = case(Esql.url_original_to_lower like \"*base64*-d*\" or Esql.url_original_to_lower like \"*echo*|*base64*\", 1, 0)\n| eval Esql.contains_suspicious_path = case(Esql.url_original_to_lower like \"*/tmp/*\" or Esql.url_original_to_lower like \"*/var/tmp/*\" or Esql.url_original_to_lower like \"*/dev/shm/*\" or Esql.url_original_to_lower like \"*/root/*\" or Esql.url_original_to_lower like \"*/home/*/*\" or Esql.url_original_to_lower like \"*/var/www/*\" or Esql.url_original_to_lower like \"*/etc/cron.*/*\", 1, 0)\n\n| eval Esql.any_payload_keyword = case(\n Esql.contains_interpreter == 1 or Esql.contains_shell == 1 or Esql.contains_nc == 1 or Esql.contains_devtcp == 1 or\n Esql.contains_helpers == 1 or Esql.contains_sus_cli == 1 or Esql.contains_privileges == 1 or Esql.contains_downloader == 1 or\n Esql.contains_file_read_keywords == 1 or Esql.contains_base64_cmd == 1 or Esql.contains_suspicious_path == 1, 1, 0)\n\n| keep\n @timestamp,\n Esql.url_original_to_lower,\n Esql.any_payload_keyword,\n Esql.contains_interpreter,\n Esql.contains_shell,\n Esql.contains_nc,\n Esql.contains_devtcp,\n Esql.contains_helpers,\n Esql.contains_sus_cli,\n Esql.contains_privileges,\n Esql.contains_downloader,\n Esql.contains_file_read_keywords,\n Esql.contains_base64_cmd,\n Esql.contains_suspicious_path,\n source.ip,\n destination.ip,\n agent.id,\n http.request.method,\n http.response.status_code,\n user_agent.original,\n agent.name,\n data_stream.dataset,\n data_stream.namespace\n\n| stats\n Esql.event_count = count(),\n Esql.url_path_count_distinct = count_distinct(Esql.url_original_to_lower),\n\n // General fields\n\n Esql.agent_name_values = values(agent.name),\n Esql.agent_id_values = values(agent.id),\n Esql.url_path_values = values(Esql.url_original_to_lower),\n Esql.http.response.status_code_values = values(http.response.status_code),\n Esql.user_agent_original_values = values(user_agent.original),\n Esql.data_stream_dataset_values = values(data_stream.dataset),\n Esql.data_stream_namespace_values = values(data_stream.namespace),\n\n // Rule Specific fields\n Esql.any_payload_keyword_max = max(Esql.any_payload_keyword),\n Esql.contains_interpreter_values = values(Esql.contains_interpreter),\n Esql.contains_shell_values = values(Esql.contains_shell),\n Esql.contains_nc_values = values(Esql.contains_nc),\n Esql.contains_devtcp_values = values(Esql.contains_devtcp),\n Esql.contains_helpers_values = values(Esql.contains_helpers),\n Esql.contains_sus_cli_values = values(Esql.contains_sus_cli),\n Esql.contains_privileges_values = values(Esql.contains_privileges),\n Esql.contains_downloader_values = values(Esql.contains_downloader),\n Esql.contains_file_read_keywords_values = values(Esql.contains_file_read_keywords),\n Esql.contains_base64_cmd_values = values(Esql.contains_base64_cmd),\n Esql.contains_suspicious_path_values = values(Esql.contains_suspicious_path)\n\n by source.ip, agent.id\n\n| where\n // Filter for potential command injection attempts with low event counts to reduce false positives\n Esql.any_payload_keyword_max == 1 and Esql.event_count < 5"
},
{
"name": "f7d588ba-e4b0-442e-879d-7ec39fbd69c5 — Potential SAP NetWeaver WebShell Creation",
"description": "(EQL) Identifies suspicious Java file creation in the IRJ directory of the SAP NetWeaver application. This may indicate an attempt to deploy a webshell. (Source: Elastic's official detection-rules repository (Elastic License v2).)",
"query": "file where host.os.type in (\"linux\", \"windows\") and event.action == \"creation\" and\n file.extension : (\"jsp\", \"java\", \"class\") and\n file.path : (\"/*/sap.com/*/servlet_jsp/irj/root/*\",\n \"/*/sap.com/*/servlet_jsp/irj/work/*\",\n \"?:\\\\*\\\\sap.com\\\\*\\\\servlet_jsp\\\\irj\\\\root\\\\*\",\n \"?:\\\\*\\\\sap.com\\\\*\\\\servlet_jsp\\\\irj\\\\work\\\\*\")"
}
]
},
"automation": {
"safe": [
"Add recommendation as Sentinel incident comment.",
"Run enrichment queries.",
"Create ServiceNow SecOps task."
],
"approval_required": [
"Contain or disable the affected host/account.",
"Any change to production configuration."
]
},
"escalation_criteria": [
"Server Software Component activity observed on a privileged account or critical system.",
"Activity follows or precedes other suspicious behaviour in the same investigation.",
"Automated triage cannot confidently rule out malicious intent."
],
"false_positive_considerations": [
"Legitimate administrative or maintenance activity matching this pattern.",
"Approved security testing or red team exercise.",
"Known benign software producing similar telemetry."
],
"confluence": {
"title": "T1505 - Server Software Component Response Guidance",
"labels": [
"mitre",
"attack",
"d3fend",
"secops",
"basyrix"
],
"sections": [
"summary",
"d3fend_mappings",
"investigation_steps",
"response_actions",
"queries",
"automation",
"escalation_criteria",
"false_positive_considerations"
]
}
}