---
analysis: While a detection rule might fire on a shell, it lacks the context of identity
  role drift. This hunt correlates vulnerability data, successful HTTP exploitation,
  and IAM sign-in context to evaluate behavior against a host's functional profile.
blind_spots:
- id: no-http-body-telemetry
  question: whether the specific payload in a successful POST request was malicious
  requires: WAF or local server logs with body content
  risk: hb_http_activity lacks request bodies, making it hard to distinguish between
    legitimate API usage and exploitation on success.
  stage: exploit-public-application
- id: no-endpoint-telemetry
  question: whether a shell was spawned on a host missing the telemetry agent
  requires: hb_process_activity from an endpoint agent
  risk: A host without an agent provides no process or script visibility, leaving
    the hunt blind to the follow-on execution.
  stage: client-side-execution
coverage:
- stage: exploit-public-application
  status: covered
  steps:
  - high-risk-vulnerable-hosts
  - web-exploitation-indicators
- stage: client-side-execution
  status: covered
  steps:
  - suspicious-shell-spawns
  - encoded-script-execution
- reason: 'Belongs to another part of the ''Unmasking Cloud Identities: From Behavioral
    Clustering to Automated Detection'' series.'
  stage: cloud-identity-authentication
  status: out_of_scope
- reason: 'Belongs to another part of the ''Unmasking Cloud Identities: From Behavioral
    Clustering to Automated Detection'' series.'
  stage: cloud-resource-discovery
  status: out_of_scope
- reason: 'Belongs to another part of the ''Unmasking Cloud Identities: From Behavioral
    Clustering to Automated Detection'' series.'
  stage: multi-hop-proxy-obfuscation
  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: Exploitation of public-facing applications is the primary entry point
    for gaining the identities needed for cloud intrusions. A negative result validates
    the organization's perimeter integrity and the stability of its service identities.
  methodology: model-assisted
  trigger: intel-report
hypothesis: An adversary has exploited a public-facing application on a cloud instance
  to obtain its identity, which is now being used for activity that deviates from
  the host's established behavioral profile.
labels:
- hunt
- attack.t1190
- attack.t1204.002
- attack.t1078.004
name: Public app exploitation and cloud identity drift
parameters:
  lookback_days:
    default: '14'
    description: Days of history to examine for active behavior.
    type: number
  scope_hosts:
    default: []
    description: Hostnames derived from the scoping step; leave empty to scan the
      full estate.
    type: list[host]
  sensitive_paths:
    default:
    - /etc/passwd
    - /etc/shadow
    - /wp-admin/
    - /cgi-bin/
    - /.env
    - /config.php
    - /aws/config
    - /metadata/latest/
    description: Web paths frequently targeted by directory traversal or cloud metadata
      theft.
    type: list[string]
  shell_processes:
    default:
    - cmd.exe
    - powershell.exe
    - pwsh.exe
    - sh
    - bash
    - nc
    - curl
    - wget
    description: Shells and network tools that indicate post-exploitation activity.
    type: list[string]
  web_parent_processes:
    default:
    - httpd
    - nginx
    - w3wp.exe
    - apache2
    - php-fpm
    - chrome.exe
    - msedge.exe
    - outlook.exe
    description: Parent processes commonly exploited or used to launch malicious payloads.
    type: list[string]
provenance:
  authors:
  - name: Huntbase hunt generation
    org: huntbase.io
  generated:
    by: huntbase-hunt-generation
    from: https://unit42.paloaltonetworks.com/behavioral-clustering-map-to-cloud-identities/
    gates:
    - dry-run
    - lint
    model: hb_google/gemini-3-flash-preview
rationale: Focus on cloud instances with High or Critical vulnerabilities first. The
  scoping query uses a join to provide hostnames for the scope_hosts parameter. If
  no vulnerabilities are reported, widen the scope to all hosts with internet exposure
  found in hb_exposed_assets.
references:
- name: "Unit 42 \u2014 Unmasking Cloud Identities: From Behavioral Clustering to\
    \ Automated Detection"
  url: https://unit42.paloaltonetworks.com/behavioral-clustering-map-to-cloud-identities/
related:
- hunt: cloud-identity-behavioral-anomaly
  reason: This hunt identifies the initial compromise; the follow-on hunt examines
    broader identity misuse within the cloud control plane.
  relation: follows
scenario:
  stages:
  - name: Exploitation of Public-Facing Application
    observables:
    - Inbound exploitation attempts against internet-facing web servers
    - Unauthorized HTTP POST requests to vulnerable endpoints
    slug: exploit-public-application
    tactic: initial-access
    techniques:
    - T1190
  - name: User Execution of Malicious File
    observables:
    - Execution of downloaded suspicious documents or binaries
    - Process spawning from browser or email client
    - Malicious file creation in temporary directories
    slug: client-side-execution
    tactic: execution
    techniques:
    - T1204.002
  - name: Cloud Identity Authentication
    observables:
    - ConsoleLogin events
    - GetSigninToken activity
    - Identity naming patterns containing 'admin'
    - AWSReservedSSO_AdministratorAccess_ prefix usage
    slug: cloud-identity-authentication
    tactic: initial-access
  - name: Cloud Resource Discovery
    observables:
    - ListBuckets
    - ListRoles
    - ListNotificationHubs
    - GetCostAndUsage
    - GetCostForecast
    slug: cloud-resource-discovery
    tactic: discovery
  - name: Multi-hop Proxy Obfuscation
    observables:
    - Sign-in activity from known Tor exit nodes
    - Network connections to multi-hop VPS or ORB networks
    - Anomalous source IP addresses for administrative sessions
    slug: multi-hop-proxy-obfuscation
    tactic: command-and-control
    techniques:
    - T1090.003
  summary: Attackers leverage exploited applications or social engineering to gain
    access to over-privileged cloud identities, which are then used to perform resource
    enumeration and discovery within AWS Management Console. To evade detection, actors
    masquerade using benign permission profiles and mask their activity source through
    multi-hop proxies or Tor, requiring behavioral clustering to distinguish malicious
    reconnaissance from legitimate administrative activity.
series:
  index: 1
  slug: unmasking-cloud-identities-from-behavioral-clustering-to-automated-detection
  title: 'Unmasking Cloud Identities: From Behavioral Clustering to Automated Detection'
  total: 2
severity: medium
targets:
  analyst:
    name: Tier-2 analyst
    role: analyst
  endpoint:
    category: endpoint
    name: Endpoint telemetry (hb_ surfaces)
    telemetry:
    - endpoint
  hunter:
    agent: true
    name: Hunt agent
  identity:
    category: identity
    name: Identity / sign-in telemetry
    telemetry:
    - identity
  web:
    category: siem
    name: Web server / proxy logs
    telemetry:
    - network
tlp: clear
type: investigation
---


# Public app exploitation and cloud identity drift

This hunt identifies the initial entry points of a cloud-focused intrusion by examining internet-exposed hosts for vulnerabilities, successful web exploitation, and follow-on shell activity. Building on Unit 42 research regarding behavioral clustering of cloud identities, the hunt evaluates whether the activity observed on a compromised host aligns with its functional role. By correlating HTTP traffic, anomalous process execution, and the underlying IAM identity, analysts can detect when a service role has been co-opted for malicious discovery or lateral movement.

## high-risk-vulnerable-hosts
<!-- Identify vulnerable internet-facing hosts -->
Focus the hunt on instances with known high or critical vulnerabilities by joining vulnerability findings with device inventory to get hostnames.

```sqlite target=endpoint role=scoping
~~~yaml
expected: A list of hostnames for cloud instances with critical vulnerabilities. If
  empty, the estate has no current high-risk exposures to focus on.
reads:
- v.device_uid
- d.device_uid
- d.hostname
- v.severity_id
- v.resource_type
- v.status
- v.provider
- d.provider
silence: not_evidence_of_absence
source: hb_vulnerability_finding
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT DISTINCT d.hostname AS device_hostname, v.cve_uid, v.title FROM hb_vulnerability_finding v JOIN hb_devices d ON v.device_uid = d.device_uid WHERE v.severity_id >= 4 AND v.resource_type = 'instance' AND v.status != 'suppressed' AND v.provider = d.provider
```

## exploitation-fan-out
<!-- Analyze traffic and execution in parallel -->
parallel:
- → web-exploitation-indicators
- → suspicious-shell-spawns
- → encoded-script-execution
- → host-identity-context
join: → triage-compromise

## web-exploitation-indicators
<!-- Successful web application exploitation -->
Identify successful HTTP requests to sensitive paths or those resulting in errors that suggest attempts to exploit web vulnerabilities.

```sqlite target=web role=triage params=(sensitive_paths=sensitive_paths, scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
expected: Requests resulting in status 200 for sensitive system files or cloud metadata,
  indicating potential successful exploitation.
reads:
- device_hostname
- url_path
- status_code
- src_endpoint_ip
- time
silence: not_evidence_of_absence
source: hb_http_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, url_path, status_code, src_endpoint_ip, COUNT(*) as total_requests FROM hb_http_activity WHERE (status_code = 200 OR status_code >= 400) AND (instr(',' || '{{sensitive_paths}}' || ',', ',' || LOWER(url_path) || ',') > 0) AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY device_hostname, url_path, status_code, src_endpoint_ip
```

## suspicious-shell-spawns
<!-- Anomalous shell spawns from web processes -->
Detect successful exploitation by finding shells spawned by web servers or other user-facing applications.

```sqlite target=endpoint role=detection-candidate params=(web_parent_processes=web_parent_processes, shell_processes=shell_processes, scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
expected: A shell running under a web server context (e.g., www-data) following a
  web request.
reads:
- device_hostname
- process_name
- process_cmd_line
- parent_process_name
- user_name
- time
silence: not_evidence_of_absence
source: hb_process_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, process_name, process_cmd_line, parent_process_name, user_name, time FROM hb_process_activity WHERE (instr(',' || '{{web_parent_processes}}' || ',', ',' || LOWER(parent_process_name) || ',') > 0) AND (instr(',' || '{{shell_processes}}' || ',', ',' || LOWER(process_name) || ',') > 0) AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```

## encoded-script-execution
<!-- In-memory or encoded script activity -->
Capture encoded or in-memory execution which frequently follows initial exploitation to obfuscate post-compromise activity.

```sqlite target=endpoint role=triage params=(scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
expected: Encoded script blocks or suspicious PowerShell/Shell script content on potentially
  compromised hosts.
reads:
- device_hostname
- script_name
- script_content
- actor_user_name
- time
silence: not_evidence_of_absence
source: hb_script_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, script_name, script_content, actor_user_name, time FROM hb_script_activity WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```

## host-identity-context
<!-- Identify host-associated cloud identities -->
Identify the IAM role or user associated with the scoped hosts to look for signs of identity drift.

```sqlite target=identity role=enrichment params=(scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
expected: The IAM identities used by or signing into the target hosts, providing context
  for behavioral role analysis.
reads:
- actor_user_name
- src_endpoint_ip
- dst_endpoint_name
- auth_protocol
- time
silence: not_evidence_of_absence
source: hb_auth_signin
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT actor_user_name, src_endpoint_ip, dst_endpoint_name, auth_protocol, time FROM hb_auth_signin WHERE ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || dst_endpoint_name || ',') > 0 OR instr(',' || '{{scope_hosts}}' || ',', ',' || src_endpoint_ip || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```

## triage-compromise
<!-- Weigh compromise evidence and identity drift -->
```agent target=hunter
cite: required
context:
- high-risk-vulnerable-hosts
- web-exploitation-indicators
- suspicious-shell-spawns
- encoded-script-execution
- host-identity-context
max_iterations: 5
objective: "Determine if any vulnerable host shows signs of successful exploitation.\
  \ Explicitly look for 'identity role drift'\u2014comparing the actions taken by\
  \ the compromised host's IAM role (found in host-identity-context) against its typical\
  \ activity profile (e.g., a backup service suddenly spawning shells or a developer\
  \ role accessing restricted web paths)."
success_criteria: A detailed verdict citing specific HTTP requests and shell commands
  for each host, highlighting drift from the identity's known role.
tools:
- endpoint
- identity
- web
```

## route-on-compromise
<!-- Route based on compromise verdict -->
if~: "the triage verdict is malicious for at least one host showing overlapping signals of exploitation and identity drift" (confidence: high, judge=hunter)
then: → isolate-compromised-host
indeterminate: → manual-investigation
unavailable: → manual-investigation (blind_spot: no-endpoint-telemetry)
else: → close-out-investigation

## isolate-compromised-host
<!-- Isolate host and revoke sessions -->
```action target=endpoint
~~~yaml
approval: required
~~~
Isolate the host at the network level and terminate all active user sessions associated with its identity profile.
```
→ manual-investigation

## manual-investigation
<!-- Analyze forensic evidence and identity logs -->
```manual target=analyst
Examine the host's activity in AWS CloudTrail to verify if it performed operations outside of its established behavioral cluster.
```
→ close-out-investigation

## close-out-investigation
<!-- Close out and remediate vulnerabilities -->
```manual target=analyst
Patch the vulnerable application and document the behavioral indicators observed for future tuning of the identity clustering model.
```
→ end
