Suspicious Perimeter Reconnaissance and Web Exploitation
An intruder is using automated agentic tools to identify exposed secrets on public-facing assets and is exploiting web vulnerabilities via command injection in user-agent headers to gain initial access.
Based on research by Microsoft 2026-11-06 9 steps · 3 queries T1071 T1090.003 T1190 T1566
Brief
Why now
Adversaries now use agentic AI tools to find and abuse exposed secrets with speed that traditional detection cycles cannot match. A report by MSRC — Threat actors use agentic AI tooling to find and abuse exposed secrets details how actors identify leaked credentials and immediately pivot to web exploitation. This hunt specifically targets the ARTEX framework's behavior, where attackers inject shell commands into User-Agent headers to compromise cloud-facing applications.
How the hunt flows
The first phase scopes the environment using hb_vulnerability_finding. We query for any cloud resources or hosts already flagged by scanners for having exposed secrets, API keys, or credentials in configuration files. This narrow list of assets becomes the primary focus for subsequent traffic analysis.
Next, the hunt fans out into two parallel queries on hb_http_activity. The first query performs a prevalence stack-count on User-Agent strings. It looks for rare strings—appearing on three or fewer hosts—that contain shell commands like bash, /bin/, curl, or python. The second query looks for any inbound traffic originating from the specific IP addresses associated with ARTEX reconnaissance.
Finally, the hunt joins these results for triage. We examine if the rare, command-laden User-Agents or the malicious IPs targeted the same hosts identified in the scoping phase. If the activity aligns, we escalate to isolate the affected web server and audit for sign-in activity using any compromised credentials.
What the hunt cannot see
This hunt has two primary blind spots. First, it lacks visibility into HTTP POST bodies. While we catch injection attempts in headers, any payload delivered inside the request body remains hidden in standard surface logging. Second, we cannot see the adversary's search activity on external platforms like GitHub. We only observe the exposure once a scanner flags it or the abuse once it reaches our perimeter.
In this series
Steps
-
Resources with exposed secret findings
Query · scopingIdentify hosts or resources already flagged by scanners for having exposed secrets or credentials to narrow the search area.
reads hb_vulnerability_findingsqlSELECT resource_uid, title, severity, status, first_seen FROM hb_vulnerability_finding WHERE (LOWER(title) LIKE '%secret%' OR LOWER(title) LIKE '%credential%' OR LOWER(title) LIKE '%api key%') AND status != 'suppressed'What a hit looks like. A list of cloud resources (ARNs, instance IDs, or hostnames) where secrets were found in source code or configuration. Silence means no known exposures exist.
-
Prevalence of suspicious User-Agents
Query · detection candidateStack-count User-Agent strings containing shell commands across the fleet to identify rare exploitation attempts.
reads hb_http_activitysqlSELECT user_agent, COUNT(DISTINCT device_hostname) AS hosts, MIN(time) AS first_seen, MAX(time) AS last_seen FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND (LOWER(user_agent) LIKE '%bash%' OR LOWER(user_agent) LIKE '%/bin/%' OR LOWER(user_agent) LIKE '%curl%' OR LOWER(user_agent) LIKE '%wget%' OR LOWER(user_agent) LIKE '%python%') AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY user_agent HAVING hosts <= 3 ORDER BY hosts ASCWhat a hit looks like. Rare User-Agents (seen on < 3 hosts) that contain shell commands. Common browsers are ignored by the stack-count.
-
HTTP activity from malicious origin IPs
Query · enrichmentIdentify inbound requests to scoped hosts originating from IP addresses named in the ARTEX report.
reads hb_http_activitysqlSELECT device_hostname, src_endpoint_ip, url_full, user_agent, status_code, time FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND instr(',' || '{{malicious_ips}}' || ',', ',' || src_endpoint_ip || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days')What a hit looks like. Specific requests from the reported IPs, showing which assets are being probed or exploited. Silence means the adversary is using different infrastructure.
-
Triage reconnaissance and exploitation evidence
Agent triageDetermine if the rare User-Agents and malicious IP activity constitute a confirmed exploitation attempt against vulnerable assets.
-
Decide on containment
DecisionRoute the hunt to immediate host isolation if the triage confirms active exploitation from malicious infrastructure.
-
Isolate affected web server
Response actionHalt active exploitation by isolating the compromised web application host.
-
Credential rotation and audit
Analyst taskEnsure any secrets known to be exposed on the targeted host are rotated and invalidated.
-
Final hunt closure
Analyst taskDocument findings and update perimeter scanning policies.
Coverage
Scenario coverage
| Stage | Covered | How, or why not |
|---|---|---|
| Secret Exposure in Public Repositories T1190 |
Yes | vulnerable-secret-exposure, triage-recon-activity |
| Embedded Shell Command Injection T1190 |
Yes | suspicious-user-agent-prevalence, malicious-ip-recon, triage-recon-activity |
| Credential Abuse via Entra ID T1078 |
Out of scope | Belongs to another part of the 'Threat actors use agentic AI tooling to find and abuse exposed secrets' series. |
| Automated Cloud Reconnaissance T1071 |
Out of scope | Belongs to another part of the 'Threat actors use agentic AI tooling to find and abuse exposed secrets' series. |
| Adaptive API Troubleshooting T1071 |
Out of scope | Belongs to another part of the 'Threat actors use agentic AI tooling to find and abuse exposed secrets' series. |
| Cloud Data Exfiltration T1041 |
Out of scope | Belongs to another part of the 'Threat actors use agentic AI tooling to find and abuse exposed secrets' series. |
Blind spots
- Needs hb_http_activity with request_body column. While user-agent injection is visible, injection payloads in the HTTP POST body are not captured by standard surface logging. It would answer What were the full payloads sent in POST requests?. Remediation: Enable WAF logging for POST request bodies on high-value web applications.
- Needs GitHub Enterprise Audit Log. Adversary search activity on the GitHub platform itself is only visible to GitHub; we can only see the exposure (vulnerability scan) or the abuse (sign-in logs). It would answer Which external IPs searched for our organization's code in public repositories?. Remediation: Configure GitHub Secret Scanning and Push Protection to alert on leaks before commits.
Parameters & data
Parameters
| Parameter | Type | Default | What it is |
|---|---|---|---|
lookback_days | number | 14 | Days of historical telemetry to examine. |
malicious_ips | list[ip] | 65.87.223.26, 199.19.77.84, 199.19.77.18, 157.22.126.128 | IP addresses associated with ARTEX reconnaissance and exploitation. |
scope_hosts | list[host] | — | Hostnames identified in the scoping step as having exposed secret vulnerabilities. |
Telemetry
| Source | Category | Telemetry |
|---|---|---|
| Endpoint telemetry (hb_ surfaces) | endpoint | endpoint |
| Web server / proxy logs | siem | network |
Source
---
analysis: A simple rule might catch the IPs, but this hunt pivots between static vulnerability
findings and behavioral HTTP traffic. The use of prevalence stack-counting for User-Agents
ensures that even if IPs rotate, the tool-based injection patterns remain visible
against a baseline of legitimate browser traffic.
blind_spots:
- id: no-http-body-telemetry
owner: Network Security Team
question: What were the full payloads sent in POST requests?
remediation: Enable WAF logging for POST request bodies on high-value web applications.
requires: hb_http_activity with request_body column
risk: While user-agent injection is visible, injection payloads in the HTTP POST
body are not captured by standard surface logging.
stage: web-vulnerability-exploitation
- id: no-github-platform-audit
owner: AppSec Team
question: Which external IPs searched for our organization's code in public repositories?
remediation: Configure GitHub Secret Scanning and Push Protection to alert on leaks
before commits.
requires: GitHub Enterprise Audit Log
risk: Adversary search activity on the GitHub platform itself is only visible to
GitHub; we can only see the exposure (vulnerability scan) or the abuse (sign-in
logs).
stage: initial-secret-exposure
coverage:
- stage: initial-secret-exposure
status: covered
steps:
- vulnerable-secret-exposure
- triage-recon-activity
- stage: web-vulnerability-exploitation
status: covered
steps:
- suspicious-user-agent-prevalence
- malicious-ip-recon
- triage-recon-activity
- reason: Belongs to another part of the 'Threat actors use agentic AI tooling to
find and abuse exposed secrets' series.
stage: service-principal-compromise
status: out_of_scope
- reason: Belongs to another part of the 'Threat actors use agentic AI tooling to
find and abuse exposed secrets' series.
stage: cloud-resource-discovery
status: out_of_scope
- reason: Belongs to another part of the 'Threat actors use agentic AI tooling to
find and abuse exposed secrets' series.
stage: adaptive-api-probing
status: out_of_scope
- reason: Belongs to another part of the 'Threat actors use agentic AI tooling to
find and abuse exposed secrets' series.
stage: credential-and-data-exfiltration
status: out_of_scope
guardrails:
claims: no_unsupported
evidence: citation_required
missing_data: not_benign
telemetry: untrusted
hunt:
applicability: campaign-specific
handoff: promote-to-detection
justification: Adversaries are using AI agents to shrink the window between secret
exposure and cloud compromise to minutes; identifying reconnaissance against vulnerable
assets is the only way to prevent full tenant takeovers.
methodology: model-assisted
trigger: intel-report
hypothesis: An intruder is using automated agentic tools to identify exposed secrets
on public-facing assets and is exploiting web vulnerabilities via command injection
in user-agent headers to gain initial access.
labels:
- hunt
- attack.t1190
- attack.t1071
- attack.t1090.003
- attack.t1566
- defense evasion
- discovery
- exfiltration
- initial access
name: Suspicious Perimeter Reconnaissance and Web Exploitation
parameters:
lookback_days:
default: '14'
description: Days of historical telemetry to examine.
from:
kind: manual
observed: '2026-11-05'
ref: hunt-standard
type: number
malicious_ips:
default:
- 65.87.223.26
- 199.19.77.84
- 199.19.77.18
- 157.22.126.128
description: IP addresses associated with ARTEX reconnaissance and exploitation.
from:
kind: article
observed: '2026-10-28'
ref: msrc-blog
type: list[ip]
scope_hosts:
default: []
description: Hostnames identified in the scoping step as having exposed secret
vulnerabilities.
from:
kind: manual
observed: '2026-11-05'
ref: hunt-standard
type: list[host]
provenance:
authors:
- name: Huntbase hunt generation
org: huntbase.io
generated:
by: huntbase-hunt-generation
from: https://www.microsoft.com/en-us/security/blog/2026/11/05/threat-actors-use-agentic-ai-tooling-to-find-and-abuse-exposed-secrets/
gates:
- dry-run
- lint
model: hb_google/gemini-3-flash-preview
rationale: Scope the hunt to hosts with vulnerability findings mentioning 'secret',
'credential', or 'api key'. Analysts should populate scope_hosts with the hostnames
mapped from those vulnerable resources.
references:
- name: "MSRC \u2014 Threat actors use agentic AI tooling to find and abuse exposed\
\ secrets"
url: https://www.microsoft.com/en-us/security/blog/2026/11/05/threat-actors-use-agentic-ai-tooling-to-find-and-abuse-exposed-secrets/
related:
- hunt: cloud-api-abuse-from-malicious-ips
reason: Once initial access is confirmed via this hunt, a second hunt should track
the subsequent ARM and Graph API abuse.
relation: follows
- hunt: agentic-ai-cloud-resource-abuse
relation: follows
scenario:
stages:
- name: Secret Exposure in Public Repositories
observables:
- GitHub repositories containing OAuth client secrets
- Azure API keys
- AI inference-related API keys
- ARTEX offensive framework scanning patterns
slug: initial-secret-exposure
tactic: initial-access
techniques:
- T1190
- name: Credential Abuse via Entra ID
observables:
- IP address 199.19.77.84
- IP address 199.19.77.18
- Service principal sign-ins for multitenant applications
- Logins from Tor exit nodes
slug: service-principal-compromise
tactic: initial-access
techniques:
- T1078
- name: Automated Cloud Reconnaissance
observables:
- Enumeration of Azure subscriptions
- Enumeration of resource groups
- Mapping of AI model deployments
- Graph API search requests for sensitive content
slug: cloud-resource-discovery
tactic: discovery
techniques:
- T1071
- name: Adaptive API Troubleshooting
observables:
- ARM requests returning HTTP 400 followed by HTTP 200 within 30-60 seconds
- Rapid changes to api-version parameters (e.g., switching to 2023-07-01)
- Switching between HTTP methods (GET/POST) after failure
- Mixing Key Vault data-plane and control-plane API versions
slug: adaptive-api-probing
tactic: defense-evasion
techniques:
- T1071
- name: Cloud Data Exfiltration
observables:
- Retrieval of Storage Account keys
- Accessing Azure Key Vault secrets and metadata
- SharePoint and OneDrive file downloads
- Mailbox item access
- Downloading App Service publishing credentials
slug: credential-and-data-exfiltration
tactic: exfiltration
techniques:
- T1041
- name: Embedded Shell Command Injection
observables:
- IP address 65.87.223.26
- Shell commands embedded in HTTP User-Agent headers
- Attempts to obtain App Service authentication tokens
slug: web-vulnerability-exploitation
tactic: initial-access
techniques:
- T1190
summary: Threat actors use the ARTEX agentic AI framework to harvest exposed secrets
from GitHub and automate the compromise of Entra ID service principals. Once authenticated,
the AI agents perform cloud resource discovery and adaptive API troubleshooting
to exfiltrate sensitive data from Azure Key Vault, Storage Accounts, and Microsoft
365 environments.
series:
index: 2
slug: threat-actors-use-agentic-ai-tooling-to-find-and-abuse-exposed-secrets
title: Threat actors use agentic AI tooling to find and abuse exposed secrets
total: 2
severity: high
targets:
analyst:
name: Tier-2 analyst
role: analyst
endpoint:
category: endpoint
name: Endpoint telemetry (hb_ surfaces)
telemetry:
- endpoint
hunter:
agent: true
name: Hunt agent
web:
category: siem
name: Web server / proxy logs
telemetry:
- network
tlp: clear
type: investigation
---
# Suspicious Perimeter Reconnaissance and Web Exploitation
This hunt targets the early stages of an AI-driven attack chain, specifically focusing on the discovery of exposed secrets and the exploitation of web applications. It first scopes the estate for resources with known secret-related vulnerabilities. It then fanned out to identify rare, high-risk User-Agent strings containing shell commands (a technique linked to the ARTEX framework) and monitors for inbound traffic from known malicious reconnaissance IPs. An agent triages the combined evidence to identify targeted exploitation attempts against vulnerable infrastructure.
## vulnerable-secret-exposure
<!-- Resources with exposed secret findings -->
Identify hosts or resources already flagged by scanners for having exposed secrets or credentials to narrow the search area.
```sqlite target=endpoint role=scoping
~~~yaml
expected: A list of cloud resources (ARNs, instance IDs, or hostnames) where secrets
were found in source code or configuration. Silence means no known exposures exist.
reads:
- resource_uid
- title
- severity
- status
- first_seen
silence: not_evidence_of_absence
source: hb_vulnerability_finding
verified: dry-run
verified_at: '2026-11-06'
~~~
SELECT resource_uid, title, severity, status, first_seen FROM hb_vulnerability_finding WHERE (LOWER(title) LIKE '%secret%' OR LOWER(title) LIKE '%credential%' OR LOWER(title) LIKE '%api key%') AND status != 'suppressed'
```
## reconnaissance-fan-out
<!-- Parallel reconnaissance and exploitation check -->
parallel:
- → suspicious-user-agent-prevalence
- → malicious-ip-recon
join: → triage-recon-activity
## suspicious-user-agent-prevalence
<!-- Prevalence of suspicious User-Agents -->
Stack-count User-Agent strings containing shell commands across the fleet to identify rare exploitation attempts.
```sqlite target=web role=detection-candidate params=(lookback_days=lookback_days, scope_hosts=scope_hosts)
~~~yaml
baseline:
compare: first_seen
window: '{{lookback_days}}d'
expected: Rare User-Agents (seen on < 3 hosts) that contain shell commands. Common
browsers are ignored by the stack-count.
prevalence:
by: device_hostname
key:
- user_agent
rare_below: 3
reads:
- user_agent
- device_hostname
- time
silence: not_evidence_of_absence
source: hb_http_activity
verified: dry-run
verified_at: '2026-11-06'
~~~
SELECT user_agent, COUNT(DISTINCT device_hostname) AS hosts, MIN(time) AS first_seen, MAX(time) AS last_seen FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND (LOWER(user_agent) LIKE '%bash%' OR LOWER(user_agent) LIKE '%/bin/%' OR LOWER(user_agent) LIKE '%curl%' OR LOWER(user_agent) LIKE '%wget%' OR LOWER(user_agent) LIKE '%python%') AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY user_agent HAVING hosts <= 3 ORDER BY hosts ASC
```
## malicious-ip-recon
<!-- HTTP activity from malicious origin IPs -->
Identify inbound requests to scoped hosts originating from IP addresses named in the ARTEX report.
```sqlite target=web role=enrichment params=(lookback_days=lookback_days, malicious_ips=malicious_ips, scope_hosts=scope_hosts)
~~~yaml
expected: Specific requests from the reported IPs, showing which assets are being
probed or exploited. Silence means the adversary is using different infrastructure.
reads:
- device_hostname
- src_endpoint_ip
- url_full
- user_agent
- status_code
- time
silence: not_evidence_of_absence
source: hb_http_activity
verified: dry-run
verified_at: '2026-11-06'
~~~
SELECT device_hostname, src_endpoint_ip, url_full, user_agent, status_code, time FROM hb_http_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND instr(',' || '{{malicious_ips}}' || ',', ',' || src_endpoint_ip || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days')
```
## triage-recon-activity
<!-- Triage reconnaissance and exploitation evidence -->
```agent target=hunter
cite: required
context:
- vulnerable-secret-exposure
- suspicious-user-agent-prevalence
- malicious-ip-recon
max_iterations: 4
objective: Review the parallel query results and verify if the suspicious User-Agents
or malicious IP requests were directed at hosts previously identified as having
secret-related vulnerabilities. Assess if the user-agents contain valid shell commands
targeting App Service tokens or environment variables.
success_criteria: A detailed verdict per host, citing the User-Agent string, source
IP, and the target vulnerability identifier.
tools:
- endpoint
- web
```
## recon-decision
<!-- Decide on containment -->
if~: "the triage-recon-activity verdict is malicious for at least one host, indicating confirmed command injection or targeted probing from the malicious_ips." (confidence: high, judge=hunter)
then: → isolate-affected-host
indeterminate: → credential-rotation-audit
unavailable: → credential-rotation-audit (blind_spot: no-http-body-telemetry)
else: → final-hunt-closure
## isolate-affected-host
<!-- Isolate affected web server -->
```action target=endpoint
~~~yaml
approval: required
~~~
Isolate the hosts identified by the triage verdict to prevent further command execution or credential scraping.
```
→ credential-rotation-audit
## credential-rotation-audit
<!-- Credential rotation and audit -->
```manual target=analyst
Verify if the secrets listed in the scoping step have been rotated. Check for sign-in activity (hb_auth_signin) using the compromised application IDs from the malicious_ips.
```
→ final-hunt-closure
## final-hunt-closure
<!-- Final hunt closure -->
```manual target=analyst
Document whether the reconnaissance was generic or targeted based on the scoping results. Provide a list of identified rare user-agents to the detection engineering team.
```
→ end
Run it
Take this hunt into your environment.
Open it in Huntbase to run every step against your own connections, with Scout weighing the evidence and your analysts in command. Or take the open hunt.md file anywhere that reads the format.
Machine-drafted by huntbase-hunt-generation using hb_google/gemini-3-flash-preview, gated by dry-run, lint, then reviewed by a person.