New Project CAV3RN module abuses Outlook calendar events for C2 and DNS AAAA records for configuration recovery
Project CAV3RN abuses Outlook calendar events for C2 and DNS AAAA records for config recovery.
Summary
Kaspersky GReAT researchers have detailed a new module for Project CAV3RN, a sophisticated cyberespionage framework. This module, AzureCommunication.dll, leverages Outlook calendar events via Microsoft Graph for command and control (C2) communication. As a fallback, it uses DNS AAAA records to retrieve configuration data if Microsoft Graph authentication fails.
Full text
Table of Contents IntroductionTechnical detailsC2 communication moduleOutlook calendar events as a C2 channelReceiving a commandInbound command decryptionSending command outputHeartbeat handlingDNS AAAA configuration recovery mechanismDetermining the field length through .p. queriesRetrieving configuration data through .q. queriesFailure handling and the sentinel AAAA responseInfrastructureAttributionConclusionsIndicators of compromiseFile hashesDomains and IPs Authors GReAT Introduction In June 2026, as part of our Kaspersky Threat Intelligence Reporting service, we published extensive research on Project CAV3RN, a sophisticated modular framework used for cyberespionage activity against targets in Israel. We have been tracking this cluster since December 2025, and in late April 2026 we observed a major architectural shift: the developers moved from a three-component framework consisting of a downloader, executor, and uploader to a controller-based architecture with a dedicated WebSocket-enabled C2 communication component and a more extensible plugin system designed to support modular post-exploitation capabilities. Subsequently, Check Point Research publicly reported on the same controller-based architecture in July 2026. However, neither our previous research nor the subsequent public reporting covered the latest communication component analyzed in this report. Following our June 2026 publication, we identified a .NET Native AOT communication module that is apparently designed to replace the previous HTTP/WebSocket component. It exchanges commands and results through Outlook calendar events accessed via Microsoft Graph. If Microsoft Graph authentication or tenant validation fails, the module attempts to retrieve replacement connection settings through DNS AAAA responses. Module network communication architecture During the preparation of this report, additional public research covering this communication component became available. The research presented in our article is based on our independent analysis and includes several additional implementation details that complement the existing public reporting. Technical details The previously reported controller-based CAV3RN architecture separates C2 communication from command execution. The controller, uxtheme.dll, generates and maintains the seven-character Agent ID, manages the polling loop, processes built-in commands, and dispatches other tasks or commands to separate plugins. The previously used communication component, n-HTCommp.dll, retrieved commands and transmitted execution results over HTTP/WebSocket. Project CAV3RN architecture (April 2026) The module performs the same communication role but uses Outlook calendar events accessed through Microsoft Graph. Similarly to the previous version, its get and send interface and use of the same controller-generated Agent ID suggest that it was designed to replace the previous communication component. However, because the corresponding updated controller was not recovered, this replacement role is assessed rather than directly observed. C2 communication module The communication module, AzureCommunication.dll, is a DLL compiled with .NET Native AOT, consistent with several other components of the Project CAV3RN framework that are publicly documented. Such a compilation method turns the managed application into native machine code and removes most of the metadata and intermediate language that normally make .NET assemblies straightforward to analyze. The module exposes its functionality through a single export named QueryInterface. We expect an updated controller to load the DLL, resolve this export, and pass it a null-terminated UTF-16 string. The accepted input format closely follows the interface used by the previously documented CAV3RN controller. get_;;_<agent-id>_,_<legacy-url> send_;;_<agent-id>_,_<legacy-url>_,_<result> 12 get_;;_<agent-id>_,_<legacy-url> send_;;_<agent-id>_,_<legacy-url>_,_<result> The _;;_ delimiter separates the operation from its arguments, while _,_ separates the arguments. For get, the module only uses the first argument as the Agent ID. For send, it uses only the Agent ID and the result. In both cases, the additional legacy URL is ignored. It remains part of the interface for compatibility with the controller, even though the new module obtains its destination and credentials from its own Microsoft Graph configuration. Outlook calendar events as a C2 channel The DLL contains a complete default configuration, including the Microsoft Entra tenant ID, application credentials, target mailbox, DNS bootstrap host, and cryptographic keys required to establish communication. Before processing either get or send operation, the module looks for a relative file named logAzure.txt. Because the code supplies only a filename, Windows resolves it against the current working directory of the process hosting the DLL. If logAzure.txt exists, the module reads and deserializes it. If it is absent, the module builds the configuration from the hardcoded values and writes the complete object to disk with the following structure: { "TenantId": "******-****-****-****-**********", // Microsoft Entra tenant ID "ClientId": "********-****-****-****-************", // application/client ID "ClientSecret": "********************************************", "UserEmail": "***@*********.co.il", // Compromised target Microsoft 365 mailbox "Host": "cloudlanecdn[.]com", // DNS bootstrap domain "PublicKey": "-----BEGIN RSA PUBLIC KEY-----\r\n[omitted]\r\n-----END RSA PUBLIC KEY-----", // outbound encryption public key "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\r\n[omitted]\r\n-----END RSA PRIVATE KEY-----" // inbound decryption private key } 123456789 { "TenantId": "******-****-****-****-**********", // Microsoft Entra tenant ID "ClientId": "********-****-****-****-************", // application/client ID "ClientSecret": "********************************************", "UserEmail": "***@*********.co.il", // Compromised target Microsoft 365 mailbox "Host": "cloudlanecdn[.]com", // DNS bootstrap domain "PublicKey": "-----BEGIN RSA PUBLIC KEY-----\r\n[omitted]\r\n-----END RSA PUBLIC KEY-----", // outbound encryption public key "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\r\n[omitted]\r\n-----END RSA PRIVATE KEY-----" // inbound decryption private key} Using the resulting configuration, the module creates a Microsoft Graph client and validates access by requesting the tenant’s organization record through a GET request to https://graph.microsoft.com/v1.0/organization. Attempting this request causes the Azure Identity library to obtain an OAuth application token: POST https://login.microsoftonline.com/<TenantId>/oauth2/v2.0/token client_id=<ClientId> client_secret=<ClientSecret> scope=https://graph.microsoft.com/.default grant_type=client_credentials 12345 POST https://login.microsoftonline.com/<TenantId>/oauth2/v2.0/tokenclient_id=<ClientId>client_secret=<ClientSecret>scope=https://graph.microsoft.com/.defaultgrant_type=client_credentials After successful authentication, the module includes the token in subsequent Graph requests using the Authorization: Bearer <access-token> header. The module uses the default calendar of the configured mailbox as a dead-drop channel. Commands, heartbeats, and results all occupy the same fixed one-hour window 2050-05-13 22:00–23:00 UTC. Scheduling the events for 2050 makes them unlikely to appear in ordinary calendar views. The calendar event subject identifies each event’s purpose and associated Agent ID. Heartbeat and result subjects append the fixed suffix 1500 to this value; the suffix is not part of the Agent ID. Subject format Purpose Module behavior Event ID: <agent-id> Operator-to-agent command Searches for the event, downloads its attachments, and deletes it after consumption Boss update ID: <agent-id>1500 Agent heartbeat Deletes the previous heartbeat event and creates a replacement Boss Report ID: <agent-id>1500 Agent-
Indicators of Compromise
- mitre_attack — T1071.004
- mitre_attack — T1071.001
- mitre_attack — T1105
- mitre_attack — T1041
- mitre_attack — T1095
- mitre_attack — T1573.002
- mitre_attack — T1026
- mitre_attack — T1071
- mitre_attack — T1573