← All hunts high TLP:CLEAR Part 2 of 2

Microsoft Graph and Cloud Application Exfiltration

An adversary is using automated Graph API tools to enumerate organizational resources and exfiltrate SharePoint/OneDrive data after obtaining a cloud session via passkey-themed social engineering.

Based on research by Microsoft 2026-09-20 10 steps · 4 queries T1041 T1078

Brief

Why this hunt matters

Microsoft recently published research titled "Passkey-themed social engineering leads to identity and cloud compromise" (https://www.microsoft.com/en-us/security/blog/2026/09/09/passkey-themed-social-engineering-leads-identity-cloud-compromise/) which highlights a shift in adversary tactics. Attackers now bypass MFA by using passkey-themed lures to steal active sessions. Once inside, they do not just browse; they use automated tools to scrape the tenant. This hunt focuses on that transition from a successful login to the automated exfiltration of documents.

How the hunt flows

The first phase scopes the environment. The hunt queries software inventory to identify hosts running Microsoft 365 or Office suites. This narrows the focus to users with the relevant productivity software and access permissions. The second phase runs three parallel evidence-gathering queries. The first query monitors sign-ins to specific identity and management portals such as My Apps, My Profile, and My SignIns. A single account accessing multiple portals in a tight sequence suggests an actor mapping out their new environment. The second parallel query targets automated Graph API activity. We look for a high variety of unique API paths originating from a single user context within a short window. Legitimate users typically interact with a limited set of Graph endpoints, whereas automated discovery tools like Node.js scripts touch many distinct resources to find document libraries. The third parallel query identifies high-volume file access in SharePoint and OneDrive. We stack-count unique file paths per user and day. If an account touches more than fifty unique files in twenty-four hours, and this exceeds their normal baseline, it indicates potential exfiltration. Finally, an analyst or automated agent triages these combined signals. We look for the correlation: did the portal reconnaissance precede the Graph API variety and the file access spike? This sequence confirms a malicious takeover rather than isolated benign events.

Blind spots and limitations

The hunt has two primary blind spots. First, Microsoft 365 audit logs often have a delay of several hours. This latency means an adversary might complete their exfiltration before the hunt observes the activity. Second, we lack visibility into personal mobile devices. The initial phishing link is often accessed on a non-managed phone, making the earliest attack markers invisible to our endpoint telemetry.

How to run the hunt

This hunt is provided as an open hunt.md playbook. It is a structured, machine-readable file that you can import into Huntbase or any other hunt.md-aware runtime. By using this format, you can automate the data collection and correlation across your estate while maintaining a clear audit trail of the hunting logic.

Steps

  1. Scope to Microsoft 365 environments

    Query · scoping

    Identify hosts that have Microsoft 365 or Office software installed to narrow the hunt scope.

    reads hb_software_inventorysql
    SELECT DISTINCT device_hostname FROM hb_software_inventory WHERE (LOWER(package_name) LIKE '%microsoft 365%' OR LOWER(package_name) LIKE '%office%' OR LOWER(package_name) LIKE '%outlook%')

    What a hit looks like. A list of hosts with the targeted productivity software. Silence indicates no such software was found in the inventory.

  2. Identity portal reconnaissance

    Query · detection candidate

    Identify successful sign-ins to portals used to discover applications and organizational info.

    reads hb_auth_signinsql
    SELECT actor_user_name, src_endpoint_ip, dst_endpoint_name, time FROM hb_auth_signin WHERE status_id = 1 AND instr(',' || '{{targeted_apps}}' || ',', ',' || dst_endpoint_name || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days') ORDER BY time ASC

    What a hit looks like. Signs of a single user account accessing multiple identity and management portals in a tight sequence. Silence indicates no portal access was logged.

  3. Automated Graph API reconnaissance

    Query · enrichment

    Find high-variety calls to the Microsoft Graph API indicating automated discovery tools.

    reads hb_http_activitysql
    SELECT actor_user_name, device_hostname, COUNT(DISTINCT url_path) as unique_paths, COUNT(*) as total_requests, MIN(time) as start, MAX(time) as end FROM hb_http_activity WHERE url_hostname = 'graph.microsoft.com' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY actor_user_name, device_hostname HAVING unique_paths > 10 ORDER BY unique_paths DESC

    What a hit looks like. A single context making many distinct Graph API requests in a short window. Silence proves no automated Graph tools were detected.

  4. High-volume M365 exfiltration

    Query · baseline

    Stack-count file touches to find accounts exceeding typical daily document access volumes.

    reads hb_file_activitysql
    SELECT actor_user_name, device_hostname, strftime('%Y-%m-%d', time) as day, COUNT(DISTINCT file_path) as file_count FROM hb_file_activity WHERE provider = 'm365' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY actor_user_name, device_hostname, day HAVING file_count > 50 ORDER BY file_count DESC

    What a hit looks like. An account accessing more than 50 unique SharePoint/OneDrive files in a day. Silence indicates no account reached this baseline threshold.

  5. Triage session activity

    Agent triage

    Synthesize sign-ins, Graph API variety, and file volume to confirm a malicious takeover.

  6. Route on verdict

    Decision

    Route the workflow based on the agent's verdict.

  7. Revoke sessions and isolate

    Response action

    Stop ongoing exfiltration by terminating the session.

  8. Manual incident review

    Analyst task

    Verify the impact and assess the data exfiltrated.

  9. Close out

    Analyst task

    Finalize findings and documentation.

Coverage

Scenario coverage

StageCoveredHow, or why not
Cloud application and identity reconnaissance
T1078
Yes portal-recon-lead, graph-api-recon
Data enumeration and exfiltration
T1041 · T1078
Yes high-volume-file-exfil
Passkey-themed phishing domains
T1566
Out of scope Belongs to another part of the 'Passkey-themed social engineering leads to identity and cloud compromise' series.
Identity compromise via AiTM or Device Code
T1078 · T1090.003
Out of scope Belongs to another part of the 'Passkey-themed social engineering leads to identity and cloud compromise' series.
MFA method registration for persistence
T1078
Out of scope Belongs to another part of the 'Passkey-themed social engineering leads to identity and cloud compromise' series.

Blind spots

  • Needs Real-time M365 audit streaming. M365 audit logs often have a delay of several hours, meaning the exfiltration may be complete before the hunt observes the activity. It would answer whether exfiltration is currently occurring.
  • Needs Endpoint telemetry on non-managed mobile devices. The initial social engineering phase targets personal mobile devices that are not enrolled, making the early attack markers invisible. It would answer whether the phishing link was accessed on a mobile phone.

Parameters & data

Parameters

ParameterTypeDefaultWhat it is
lookback_daysnumber14Days of history to examine.
scope_hostslist[host]Optional: Limit the hunt to these hostnames; leave empty to hunt across the estate.
targeted_appslist[string]OfficeHome, My Apps, My Profile, My SignIns, Microsoft Account Controls V2, Microsoft Approval Management, OCaaS, M365ChatClient, OwaDownloadAttachmentsIdentity and management portals targeted during reconnaissance.

Telemetry

SourceCategoryTelemetry
Endpoint telemetry (hb_ surfaces)endpointendpoint
Identity / sign-in telemetryidentityidentity
Web server / proxy logssiemnetwork

Source

Download hunt.md Definition (JSON) An open hunt.md file; it runs anywhere that reads the format.
---
analysis: A single rule might alert on a login to 'My Apps', but this hunt connects
  that signal to automated Graph API variety and high-volume file counts that exceed
  a user's unique daily baseline.
blind_spots:
- id: m365-audit-latency
  question: whether exfiltration is currently occurring
  requires: Real-time M365 audit streaming
  risk: M365 audit logs often have a delay of several hours, meaning the exfiltration
    may be complete before the hunt observes the activity.
  stage: data-enumeration-exfiltration
- id: personal-mobile-visibility
  question: whether the phishing link was accessed on a mobile phone
  requires: Endpoint telemetry on non-managed mobile devices
  risk: The initial social engineering phase targets personal mobile devices that
    are not enrolled, making the early attack markers invisible.
  stage: cloud-application-reconnaissance
coverage:
- stage: cloud-application-reconnaissance
  status: covered
  steps:
  - portal-recon-lead
  - graph-api-recon
- stage: data-enumeration-exfiltration
  status: covered
  steps:
  - high-volume-file-exfil
- reason: Belongs to another part of the 'Passkey-themed social engineering leads
    to identity and cloud compromise' series.
  stage: passkey-themed-phishing
  status: out_of_scope
- reason: Belongs to another part of the 'Passkey-themed social engineering leads
    to identity and cloud compromise' series.
  stage: identity-compromise-aitm
  status: out_of_scope
- reason: Belongs to another part of the 'Passkey-themed social engineering leads
    to identity and cloud compromise' series.
  stage: mfa-persistence-registration
  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 bypassing modern MFA through passkey-themed lures;
    a negative result confirms that these lures did not lead to data theft within
    the lookback window.
  methodology: model-assisted
  trigger: intel-report
hypothesis: An adversary is using automated Graph API tools to enumerate organizational
  resources and exfiltrate SharePoint/OneDrive data after obtaining a cloud session
  via passkey-themed social engineering.
labels:
- hunt
- attack.t1041
- attack.t1078
name: Microsoft Graph and Cloud Application Exfiltration
parameters:
  lookback_days:
    default: '14'
    description: Days of history to examine.
    from:
      kind: manual
      observed: '2026-09-09'
      ref: default
    type: number
  scope_hosts:
    default: []
    description: 'Optional: Limit the hunt to these hostnames; leave empty to hunt
      across the estate.'
    from:
      kind: manual
      observed: '2026-09-09'
      ref: default
    type: list[host]
  targeted_apps:
    default:
    - OfficeHome
    - My Apps
    - My Profile
    - My SignIns
    - Microsoft Account Controls V2
    - Microsoft Approval Management
    - OCaaS
    - M365ChatClient
    - OwaDownloadAttachments
    description: Identity and management portals targeted during reconnaissance.
    from:
      kind: article
      observed: '2026-09-09'
      ref: msrc-blog-2026-09-09
    type: list[string]
provenance:
  authors:
  - name: Huntbase hunt generation
    org: huntbase.io
  generated:
    by: huntbase-hunt-generation
    from: https://www.microsoft.com/en-us/security/blog/2026/09/09/passkey-themed-social-engineering-leads-identity-cloud-compromise/
    gates:
    - dry-run
    - lint
    model: hb_google/gemini-3-flash-preview
rationale: Target hosts running Microsoft 365 or Office suites as they are the primary
  targets for this campaign's exfiltration phase. Prioritize any users who have reported
  suspicious IT helpdesk calls or SMS lures.
references:
- name: "MSRC \u2014 Passkey-themed social engineering leads to identity and cloud\
    \ compromise"
  url: https://www.microsoft.com/en-us/security/blog/2026/09/09/passkey-themed-social-engineering-leads-identity-cloud-compromise/
related:
- hunt: mfa-persistence-registration-hunt
  reason: Detection of unauthorized MFA factor addition is a persistent persistence
    mechanism handled in a sibling hunt.
  relation: out-of-scope-alternative
scenario:
  stages:
  - name: Passkey-themed phishing domains
    observables:
    - company-name.integratedsso.com
    - company-name.secure-passkey.com
    - companyname.maliciousdomain.com
    - contoso.add-passkey.com
    - passkeyhelpdesk.com
    - secure-passkey.com
    - setupmypasskey.com
    - add-passkey.com
    - integratedsso.com
    - oktasession.com
    - keysyncos.com
    - oskeysync.com
    - oskeysetup.com
    - oskeyregister.com
    - syncmykey.com
    - myconnectkey.com
    - oskeyconnect.com
    - validationsetupac.com
    - portalsetuphub.com
    slug: passkey-themed-phishing
    tactic: initial-access
    techniques:
    - T1566
  - name: Identity compromise via AiTM or Device Code
    observables:
    - Anomalous sign-in to OfficeHome from unmanaged context
    - Sign-in error 50074 (MFA required)
    - Sign-in error 50140 (Keep-me-signed-in interruption)
    - Device code flow authentication
    - Chrome user agent in anomalous session
    slug: identity-compromise-aitm
    tactic: initial-access
    techniques:
    - T1078
    - T1090.003
  - name: MFA method registration for persistence
    observables:
    - New phone number registration
    - New authenticator application registration
    - Registration of software-based OTP token
    - Update user events with StrongAuthenticationPhoneAppOTP
    slug: mfa-persistence-registration
    tactic: persistence
    techniques:
    - T1078
  - name: Cloud application and identity reconnaissance
    observables:
    - Access to My Apps application store
    - Access to My Profile organizational info
    - Access to Microsoft Approval Management
    - Access to Microsoft Account Controls V2
    - Access to My SignIns security information
    - Access to OCaaS application catalogue
    slug: cloud-application-reconnaissance
    tactic: discovery
    techniques:
    - T1078
  - name: Data enumeration and exfiltration
    observables:
    - SharePoint Online site and document requests
    - OneDrive file enumeration via Graph API
    - Outlook Web mailbox services access
    - OwaDownloadAttachments requests
    - M365ChatClient access
    - High-volume Microsoft Graph activity
    slug: data-enumeration-exfiltration
    tactic: exfiltration
    techniques:
    - T1041
    - T1078
  summary: Threat actors use passkey-themed social engineering via vishing and SMS
    to lure users to AiTM phishing sites or device-code authentication flows. Following
    compromise, the actors establish MFA persistence by registering new authentication
    factors and conduct extensive cloud reconnaissance and data exfiltration from
    SharePoint, OneDrive, and Exchange using the Microsoft Graph API.
series:
  index: 2
  slug: passkey-themed-social-engineering-leads-to-identity-and-cloud-compromise
  title: Passkey-themed social engineering leads to identity and cloud compromise
  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
  identity:
    category: identity
    name: Identity / sign-in telemetry
    telemetry:
    - identity
  web:
    category: siem
    name: Web server / proxy logs
    telemetry:
    - network
tlp: clear
type: investigation
---


# Microsoft Graph and Cloud Application Exfiltration

This hunt identifies post-compromise activity following passkey-themed social engineering. It focuses on the specific sequence of discovery where an actor accesses identity portals (My Apps, My SignIns) and then uses automated systems (Node.js/Microsoft Graph) to enumerate document libraries and download content. By correlating portal sign-ins with high-volume Graph API traffic and file access counts that deviate from a user's normal baseline, the hunt distinguishes targeted exfiltration from legitimate cloud usage.

## identify-vulnerable-scope
<!-- Scope to Microsoft 365 environments -->
Identify hosts that have Microsoft 365 or Office software installed to narrow the hunt scope.

```sqlite target=endpoint role=scoping
~~~yaml
expected: A list of hosts with the targeted productivity software. Silence indicates
  no such software was found in the inventory.
reads:
- device_hostname
- package_name
silence: not_evidence_of_absence
source: hb_software_inventory
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT DISTINCT device_hostname FROM hb_software_inventory WHERE (LOWER(package_name) LIKE '%microsoft 365%' OR LOWER(package_name) LIKE '%office%' OR LOWER(package_name) LIKE '%outlook%')
```

## fan-out-evidence
<!-- Fan-out evidence gathering -->
parallel:
- → portal-recon-lead
- → graph-api-recon
- → high-volume-file-exfil
join: → triage-agent

## portal-recon-lead
<!-- Identity portal reconnaissance -->
Identify successful sign-ins to portals used to discover applications and organizational info.

```sqlite target=identity role=detection-candidate params=(targeted_apps=targeted_apps, lookback_days=lookback_days)
~~~yaml
expected: Signs of a single user account accessing multiple identity and management
  portals in a tight sequence. Silence indicates no portal access was logged.
reads:
- actor_user_name
- src_endpoint_ip
- dst_endpoint_name
- time
- status_id
silence: 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, time FROM hb_auth_signin WHERE status_id = 1 AND instr(',' || '{{targeted_apps}}' || ',', ',' || dst_endpoint_name || ',') > 0 AND time >= datetime('now', '-{{lookback_days}} days') ORDER BY time ASC
```

## graph-api-recon
<!-- Automated Graph API reconnaissance -->
Find high-variety calls to the Microsoft Graph API indicating automated discovery tools.

```sqlite target=web role=enrichment params=(scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
expected: A single context making many distinct Graph API requests in a short window.
  Silence proves no automated Graph tools were detected.
reads:
- actor_user_name
- device_hostname
- url_hostname
- url_path
- time
silence: evidence_of_absence
source: hb_http_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT actor_user_name, device_hostname, COUNT(DISTINCT url_path) as unique_paths, COUNT(*) as total_requests, MIN(time) as start, MAX(time) as end FROM hb_http_activity WHERE url_hostname = 'graph.microsoft.com' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY actor_user_name, device_hostname HAVING unique_paths > 10 ORDER BY unique_paths DESC
```

## high-volume-file-exfil
<!-- High-volume M365 exfiltration -->
Stack-count file touches to find accounts exceeding typical daily document access volumes.

```sqlite target=endpoint role=baseline params=(scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
baseline:
  compare: new_this_window
  window: '{{lookback_days}}d'
expected: An account accessing more than 50 unique SharePoint/OneDrive files in a
  day. Silence indicates no account reached this baseline threshold.
prevalence:
  by: device_hostname
  key:
  - actor_user_name
  rare_below: 3
reads:
- actor_user_name
- device_hostname
- file_path
- provider
- time
silence: evidence_of_absence
source: hb_file_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT actor_user_name, device_hostname, strftime('%Y-%m-%d', time) as day, COUNT(DISTINCT file_path) as file_count FROM hb_file_activity WHERE provider = 'm365' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY actor_user_name, device_hostname, day HAVING file_count > 50 ORDER BY file_count DESC
```

## triage-agent
<!-- Triage session activity -->
```agent target=hunter
cite: required
context:
- portal-recon-lead
- graph-api-recon
- high-volume-file-exfil
max_iterations: 5
objective: Determine if any user account shows a sign-in sequence to identity portals
  followed by automated Graph discovery and high-volume file exfiltration.
success_criteria: A per-user verdict of malicious | suspicious | benign citing specific
  portal access times and file counts.
tools:
- endpoint
- identity
- web
```

## route-on-verdict
<!-- Route on verdict -->
if~: "the triage-agent verdict is malicious for at least one user" (confidence: high, judge=hunter)
then: → isolate-and-revoke
indeterminate: → manual-incident-review
unavailable: → manual-incident-review (blind_spot: m365-audit-latency)
else: → close-out

## isolate-and-revoke
<!-- Revoke sessions and isolate -->
```action target=identity
~~~yaml
approval: required
~~~
Revoke all active sessions and refresh tokens for the identified users; initiate a password reset and review recently added MFA factors.
```
→ manual-incident-review

## manual-incident-review
<!-- Manual incident review -->
```manual target=analyst
Examine the specific file paths in hb_file_activity to determine content sensitivity. Check the source IP reputation for proxy or TOR associations. Verify if the Graph API activity indicates enumeration of the entire tenant directory.
```
→ close-out

## close-out
<!-- Close out -->
```manual target=analyst
Record the total number of accounts reviewed and the volume of baseline activity. Summarize confirmed compromises or negative results for the security leadership report.
```
→ 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.