Detection rules › Splunk
Cisco SA - Automated Web Reconnaissance via HTTP Access Errors
This analytic detects probable automated web reconnaissance using Cisco Secure Access proxy telemetry. A high volume of HTTP client errors (401/403/404/etc) across many unique URLs in a short window is consistent with directory/file enumeration behavior generated by tools such as Gobuster, DirBuster, ffuf, or Burp Intruder. Detecting this pattern helps identify pre-exploitation scanning activity, insider reconnaissance, compromised endpoints performing discovery, and attempts to find hidden administrative paths, APIs, backups, and exposed application files.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Reconnaissance | T1595 Active Scanning |
Rule body splunk
name: Cisco SA - Automated Web Reconnaissance via HTTP Access Errors
id: 4cd44520-d404-4ca8-b736-c9d6b86ecf31
version: 2
creation_date: '2026-05-08'
modification_date: '2026-06-09'
author: Mahamudul Chowdhury, Bhavin Patel, Splunk
status: production
type: Anomaly
description: |
This analytic detects probable automated web reconnaissance using Cisco Secure Access proxy telemetry.
A high volume of HTTP client errors (401/403/404/etc) across many unique URLs in a short window is consistent with directory/file enumeration behavior generated by tools such as Gobuster, DirBuster, ffuf, or Burp Intruder.
Detecting this pattern helps identify pre-exploitation scanning activity, insider reconnaissance, compromised endpoints performing discovery, and attempts to find hidden administrative paths, APIs, backups, and exposed application files.
data_source:
- Cisco Secure Access Proxy
search: |-
`cisco_secure_access_proxy`
| eval src_ip=coalesce(src_ip, src)
| eval host=coalesce(hostname, host)
| eval user=coalesce(user, identities)
| eval status=tonumber(status)
| eval domain=replace(url, "^https?://([^/]+).*$", "\\1")
| eval user_agent=coalesce(http_user_agent, user_agent)
| where status IN (400, 401, 403, 404, 405, 407, 414, 429, 431)
| bucket _time span=10m
| stats count as errors dc(url) as unique_urls values(status) as statuses values(user_agent) as user_agent values(host) as host values(user) as user by src_ip domain _time
| where errors > 100 AND unique_urls > 50
| eval firstTime=_time, lastTime=_time
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `cisco_sa___automated_web_reconnaissance_via_http_access_errors_filter`
how_to_implement: |
Ingest Cisco Secure Access proxy logs into Splunk using the Splunk Add-on for Cisco Security Cloud.
Update the `cisco_secure_access_proxy` macro so it resolves to the index, source, and sourcetype values used in your deployment.
known_false_positives: |
Aggressive web vulnerability scanners, QA automation, uptime monitoring, and authorized security assessments can generate high HTTP error volumes with large URL diversity.
Tune by allow-listing known scanner hosts, user agents, test domains, and approved assessment windows using the filter macro.
references:
- https://attack.mitre.org/techniques/T1595/
drilldown_searches:
- name: View the detection results for - "$src_ip$"
search: '%original_detection_search% | search src_ip = "$src_ip$"'
earliest_offset: $info_min_time$
latest_offset: $info_max_time$
- name: View risk events for the last 7 days for - "$src_ip$"
search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$src_ip$") | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`'
earliest_offset: 7d
latest_offset: "0"
intermediate_findings:
entities:
- field: user
type: user
score: 20
message: Source $src_ip$ triggered probable automated web reconnaissance on $domain$ with $errors$ HTTP access errors across $unique_urls$ unique URLs.
threat_objects:
- field: domain
type: domain
- field: src_ip
type: ip_address
analytic_story:
- Cisco Secure Access Analytics
asset_type: Endpoint
mitre_attack_id:
- T1595
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
category: network
security_domain: threat
tests:
- name: Cisco Secure Access Proxy True Positive Test
attack_data:
- data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/cisco_secure_access/proxy/automated_web_recon_http_errors.log
source: cisco_cloud_security_addon
sourcetype: cisco:cloud_security:proxy
test_type: unit
Stages and Predicates
Stage 1: search
`cisco_secure_access_proxy`
Stage 2: eval
| eval src_ip=coalesce(src_ip, src)
Stage 3: eval
| eval host=coalesce(hostname, host)
Stage 4: eval
| eval user=coalesce(user, identities)
Stage 5: eval
| eval status=tonumber(status)
Stage 6: eval
| eval domain=replace(url, "^https?://([^/]+).*$", "\\1")
Stage 7: eval
| eval user_agent=coalesce(http_user_agent, user_agent)
Stage 8: where
| where status IN (400, 401, 403, 404, 405, 407, 414, 429, 431)
Stage 9: bucket
| bucket _time span=10m
Stage 10: stats
| stats count as errors dc(url) as unique_urls values(status) as statuses values(user_agent) as user_agent values(host) as host values(user) as user by src_ip domain _time
Stage 11: where
| where errors > 100 AND unique_urls > 50
Stage 12: eval
| eval firstTime=_time, lastTime=_time
Stage 13: search
| `security_content_ctime(firstTime)`
Stage 14: search
| `security_content_ctime(lastTime)`
Stage 15: search
| `cisco_sa___automated_web_reconnaissance_via_http_access_errors_filter`
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
errors | gt |
|
sourcetype | eq |
|
status | in |
|
unique_urls | gt |
|