The Problem: C2 That Looks Like Microsoft 365

Defenders have spent years building perimeter controls around known-bad domains and IP addresses. Sophisticated threat actors have adapted by routing command-and-control through services that defenders cannot block: Microsoft 365, OneDrive, Google Drive, Slack. The Microsoft Graph API is particularly attractive because it is HTTPS-only, uses graph.microsoft.com as the endpoint — a domain that is typically trusted and excluded from SSL inspection — and has a legitimate access pattern that is difficult to distinguish from normal enterprise use without behavioural context.

This technique is well-documented across multiple nation-state groups:

  • Harvester APT uses the Graph API to communicate with a hardcoded Outlook mailbox folder. The GoGra Linux backdoor (identified April 2026) polls a folder named “Zomato Pizza” every two seconds using OData queries for operator commands.
  • APT28 (Fancy Bear) has used Graph API-based implants for exfiltration staging through OneDrive.
  • APT29 (Cozy Bear) incorporated GraphicalProton and similar Graph API malware in post-SolarWinds campaigns.
  • BirdyClient (2024) used OneDrive as a C2 relay through the Graph API.

MITRE ATT&CK maps this to T1102.002 — Web Service: Bidirectional Communication, nested under T1102 — Web Service in the Command and Control tactic.


What the Traffic Looks Like

A Graph API C2 implant typically follows this pattern:

  1. Authentication — The implant authenticates using a registered Entra ID (Azure AD) application with Mail.ReadWrite, Mail.Read, or Files.ReadWrite permissions. The OAuth token request goes to login.microsoftonline.com.
  2. Polling — The implant periodically calls the Graph API to read messages, mail folder contents, or file listings. The polling interval varies by actor but can be as frequent as every 2 seconds (Harvester GoGra).
  3. Task retrieval — Commands left by the operator in a designated mailbox folder or file are read, decoded, and executed.
  4. Exfiltration — Output is written back to a designated folder or mail draft. Exfiltration staging through OneDrive follows the same API but targets file endpoints.

The resulting network traffic consists of HTTPS requests to:

  • login.microsoftonline.com (authentication)
  • graph.microsoft.com (polling and data exchange)

Both domains have universal trust on enterprise networks. Traditional domain-reputation and threat-intel feeds will not flag them.


Detection Strategy

Effective detection requires shifting from network-based indicators to behavioural anomaly detection across three surfaces:

  1. Process → network correlation (endpoint telemetry)
  2. Microsoft Entra ID audit logs (cloud identity)
  3. Microsoft Sentinel / SIEM analytics (cross-signal correlation)

KQL Detection Rules (Microsoft Sentinel)

Rule 1: High-Frequency Graph API Polling from Non-Microsoft Processes

Legitimate user applications do not poll graph.microsoft.com multiple times per minute. This query flags sustained high-frequency Graph API calls from process names that are not in a known allowlist.

DeviceNetworkEvents
| where TimeGenerated > ago(1h)
| where RemoteUrl contains "graph.microsoft.com"
| where InitiatingProcessFileName !in~ (
    "Teams.exe", "Outlook.exe", "OneDrive.exe", "msedge.exe",
    "chrome.exe", "firefox.exe", "thunderbird", "evolution"
  )
| summarize
    call_count = count(),
    first_seen = min(TimeGenerated),
    last_seen = max(TimeGenerated),
    remote_urls = make_set(RemoteUrl, 20)
    by DeviceName, InitiatingProcessFileName, InitiatingProcessFolderPath
| where call_count > 30
| project DeviceName, InitiatingProcessFileName, InitiatingProcessFolderPath,
          call_count, first_seen, last_seen, remote_urls
| order by call_count desc

Tuning notes: Adjust the call_count > 30 threshold based on your environment’s baseline. Add known legitimate applications to the exclusion list. On Linux, the equivalent process check applies to ELF binary names.


Rule 2: OAuth Token Request Followed by Graph API Call — Unexpected Process

This rule detects the authentication step: a process that requests an OAuth token from login.microsoftonline.com and then calls graph.microsoft.com, where the initiating process is not a known M365 application.

let known_apps = dynamic([
    "Teams.exe", "Outlook.exe", "OneDrive.exe", "msedge.exe",
    "chrome.exe", "firefox.exe"
]);
let oauth_events = DeviceNetworkEvents
| where TimeGenerated > ago(2h)
| where RemoteUrl contains "login.microsoftonline.com"
| where InitiatingProcessFileName !in~ (known_apps)
| project DeviceName, ProcessTime = TimeGenerated,
          Process = InitiatingProcessFileName,
          ProcessPath = InitiatingProcessFolderPath;
let graph_events = DeviceNetworkEvents
| where TimeGenerated > ago(2h)
| where RemoteUrl contains "graph.microsoft.com"
| where InitiatingProcessFileName !in~ (known_apps)
| project DeviceName, GraphTime = TimeGenerated,
          Process = InitiatingProcessFileName;
oauth_events
| join kind=inner graph_events on DeviceName, Process
| where GraphTime between (ProcessTime .. (ProcessTime + 5m))
| project DeviceName, Process, ProcessPath, ProcessTime, GraphTime
| distinct DeviceName, Process, ProcessPath

Rule 3: Entra ID App Registration with Mail Permissions — New or Modified

Threat actors must register an Entra ID application to obtain the credentials their implant uses. This rule fires on new app registrations or permission grants involving Mail scopes.

AuditLogs
| where TimeGenerated > ago(24h)
| where OperationName in (
    "Add application",
    "Update application",
    "Add delegated permission grant",
    "Add app role assignment to service principal"
  )
| mv-expand TargetResources
| where TargetResources.type == "Application"
| extend AppDisplayName = tostring(TargetResources.displayName)
| extend ModifiedProperties = TargetResources.modifiedProperties
| mv-expand ModifiedProperties
| where ModifiedProperties.displayName == "RequiredResourceAccess"
| where ModifiedProperties.newValue contains "Mail.ReadWrite"
       or ModifiedProperties.newValue contains "Mail.Read"
       or ModifiedProperties.newValue contains "Files.ReadWrite"
| project TimeGenerated, OperationName, AppDisplayName,
          InitiatedBy = tostring(InitiatedBy.user.userPrincipalName),
          PermissionChange = tostring(ModifiedProperties.newValue)

Investigation pivot: For any app flagged here, check SignInLogs for token requests from that app’s client ID. An app registration followed by immediate sign-in activity from an unexpected IP or user agent warrants urgent investigation.


Rule 4: Linux — ELF Binary Spawning Unexpected HTTPS to Graph Endpoint

On Linux-based SIEM agents (Sysmon for Linux or auditd + network logging), flag ELF binaries in unexpected paths making HTTPS connections to Microsoft endpoints.

DeviceNetworkEvents
| where TimeGenerated > ago(4h)
| where OSFamily == "Linux"
| where RemoteUrl contains "graph.microsoft.com"
       or RemoteUrl contains "login.microsoftonline.com"
| where InitiatingProcessFolderPath !startswith "/usr/"
       and InitiatingProcessFolderPath !startswith "/opt/"
       and InitiatingProcessFolderPath !startswith "/snap/"
| project TimeGenerated, DeviceName, InitiatingProcessFileName,
          InitiatingProcessFolderPath, RemoteUrl, RemoteIP
| order by TimeGenerated desc

Sigma Rule: Graph API Polling Behaviour

For SIEM environments not running Sentinel, or for endpoint telemetry sources, this Sigma rule detects the Harvester GoGra polling pattern.

title: Suspicious Microsoft Graph API Polling from Non-Standard Process
id: a4e2f1c0-8b3d-4a7e-9c6f-1d2e3b4a5c6d
status: experimental
description: Detects high-frequency polling of Microsoft Graph API from processes
  not belonging to known Microsoft 365 or browser applications — consistent with
  GoGra (Harvester APT), BirdyClient, and similar cloud C2 implants.
references:
  - https://thehackernews.com/2026/04/harvester-deploys-linux-gogra-backdoor.html
  - https://www.security.com/threat-intelligence/harvester-new-linux-backdoor-gogra
author: SOC Analyst Hub
date: 2026-06-03
tags:
  - attack.command_and_control
  - attack.t1102.002
logsource:
  category: network_connection
  product: windows
detection:
  selection:
    Initiated: 'true'
    DestinationHostname|contains:
      - 'graph.microsoft.com'
      - 'login.microsoftonline.com'
  filter_known_apps:
    Image|endswith:
      - '\Teams.exe'
      - '\Outlook.exe'
      - '\OneDrive.exe'
      - '\msedge.exe'
      - '\chrome.exe'
      - '\firefox.exe'
      - '\msedgewebview2.exe'
      - '\SearchApp.exe'
  condition: selection and not filter_known_apps
falsepositives:
  - Third-party apps integrating with Microsoft 365 APIs
  - Enterprise applications using Graph API for legitimate purposes
  - Custom scripts or automation tools using Graph API
level: medium
---
title: Suspicious Graph API Polling on Linux Host
id: b5f3a2d1-9c4e-5b8f-0d7g-2e3f4c5b6d7e
status: experimental
description: Detects ELF binaries making connections to Microsoft Graph API from
  non-standard filesystem paths on Linux hosts.
author: SOC Analyst Hub
date: 2026-06-03
tags:
  - attack.command_and_control
  - attack.t1102.002
logsource:
  category: network_connection
  product: linux
detection:
  selection:
    DestinationHostname|contains:
      - 'graph.microsoft.com'
  filter_standard_paths:
    Image|startswith:
      - '/usr/'
      - '/opt/'
      - '/snap/'
      - '/bin/'
      - '/sbin/'
  condition: selection and not filter_standard_paths
level: high

Hunting Guidance

When triaging alerts from the above rules, pivot to these questions:

1. What is the process making Graph API calls? Identify the binary path. If it is in a user’s home directory (~/.cache/, ~/Downloads/, /tmp/), a world-writable path, or disguised as a document (e.g., report.pdf that is actually an ELF binary), this is high-confidence malicious.

2. When did it first appear? Check process creation events, file creation timestamps, and scheduled task or cron job entries. GoGra-style implants often persist via cron on Linux or scheduled tasks on Windows.

3. What Entra app is it using? Decode the OAuth token requests to identify the client_id being used. Query Entra ID audit logs to identify when and by whom that application was registered. If the app was registered outside normal IT processes, this is a strong indicator of attacker infrastructure.

4. What mailbox folder is it polling? If you can access the Outlook mailbox referenced in the implant’s code or configuration (from memory forensics or network capture), the folder name (Harvester GoGra used “Zomato Pizza”) will be consistent across infections and can serve as a high-confidence IOC.

5. What are the lateral movement and persistence artifacts? Graph API C2 is typically deployed after initial access — focus on establishing the full intrusion timeline. Look for process injection, scheduled task creation, and SSH key additions (on Linux) around the same timeframe.


Defensive Posture

Beyond detection, several controls reduce the attack surface for Graph API C2:

  • Conditional Access policies: Restrict Entra ID app registrations to approved IT personnel. Require approval workflows for apps requesting Mail scopes.
  • Application permission governance: Regularly audit registered applications in Entra ID for Mail.ReadWrite or similar permissions. Revoke unused or unrecognised applications.
  • Network proxy inspection: Where SSL inspection is technically feasible and legally permitted for Microsoft 365 traffic, inspection of Graph API calls provides an additional detection layer — though this is operationally complex and may not be viable for many organisations.
  • Linux endpoint monitoring: Deploy Sysmon for Linux or an equivalent EDR agent on Linux server infrastructure. Graph API C2 targeting Linux (as with Harvester’s GoGra Linux) relies on the assumption that Linux hosts have less visibility than Windows endpoints.