Wazuh Azure - Microsoft Azure Security Monitoring

Wazuh provides security monitoring for Microsoft Azure through the azure-logs module, which collects activity logs, Log Analytics data, and Microsoft Graph API events. The module tracks user actions within Azure subscriptions, resource changes, Microsoft Entra ID authentication events, and data from Azure Blob Storage. This integration delivers a single point of analysis for cloud threats in hybrid environments.

Supported Data Sources

The azure-logs module collects data from three primary sources:

SourceData TypePurpose
Activity LogsSubscription logsResource operations, management actions, diagnostics
Log AnalyticsAnalytical queriesEvent aggregation from various Azure sources
Microsoft Graph APIMicrosoft Entra ID APIAuthentication audit, user management, policies

The module additionally supports:

  • Azure Blob Storage - log collection from Blob Storage containers
  • Microsoft Intune - device management and compliance policy monitoring

Azure AD Application Registration

The module requires a registered application in Microsoft Entra ID (Azure Active Directory) with credentials for API access.

Registration Procedure

  1. Navigate to Microsoft Entra ID - App registrations - New registration
  2. Enter the application name (for example, Wazuh-Azure-Monitor)
  3. Select the supported account types (Single tenant for a single tenant)
  4. Record the following values:
    • Application (client) ID - the application identifier
    • Directory (tenant) ID - the tenant identifier

Creating a Client Secret

  1. Navigate to Certificates & Secrets - New client secret
  2. Provide a description and expiration period
  3. Copy the secret value (displayed only once)

Assigning Permissions

For Log Analytics and Activity Logs:

  • Assign the Reader role at the Azure subscription level

For Microsoft Graph API:

  • Navigate to API permissions - Add a permission - Microsoft Graph
  • Add AuditLog.Read.All and Directory.Read.All permissions (Application type)
  • Grant admin consent

Module Configuration (azure-logs)

The module is configured in ossec.conf on the Wazuh server or agent. Credentials are stored in separate files.

Credential File

Create the file /var/ossec/wodles/credentials/azure_credentials:

application_id = YOUR_APPLICATION_ID
application_key = YOUR_CLIENT_SECRET

For Azure Storage, create a separate file /var/ossec/wodles/credentials/storage_credentials:

account_name = YOUR_STORAGE_ACCOUNT
account_key = YOUR_STORAGE_KEY

Set permissions:

sudo chown root:wazuh /var/ossec/wodles/credentials/azure_credentials
sudo chmod 640 /var/ossec/wodles/credentials/azure_credentials

Log Analytics Configuration

<wodle name="azure-logs">
  <disabled>no</disabled>
  <run_on_start>yes</run_on_start>

  <log_analytics>
    <auth_path>/var/ossec/wodles/credentials/azure_credentials</auth_path>
    <tenantdomain>mycompany.onmicrosoft.com</tenantdomain>
    <request>
      <query>AzureActivity</query>
      <workspace>12345678-90ab-cdef-1234-567890abcdef</workspace>
      <time_offset>1d</time_offset>
    </request>
  </log_analytics>
</wodle>

Microsoft Graph API Configuration

<wodle name="azure-logs">
  <disabled>no</disabled>
  <run_on_start>yes</run_on_start>

  <graph>
    <auth_path>/var/ossec/wodles/credentials/azure_credentials</auth_path>
    <tenantdomain>mycompany.onmicrosoft.com</tenantdomain>
    <request>
      <query>auditLogs/directoryAudits</query>
      <time_offset>1d</time_offset>
    </request>
    <request>
      <query>auditLogs/signIns</query>
      <time_offset>1d</time_offset>
    </request>
  </graph>
</wodle>

Azure Storage Configuration

<wodle name="azure-logs">
  <disabled>no</disabled>
  <run_on_start>yes</run_on_start>

  <storage>
    <auth_path>/var/ossec/wodles/credentials/storage_credentials</auth_path>
    <container name="insights-activity-logs">
      <blobs>.json</blobs>
      <content_type>json_inline</content_type>
      <time_offset>24h</time_offset>
    </container>
  </storage>
</wodle>

Combined Configuration

<wodle name="azure-logs">
  <disabled>no</disabled>
  <run_on_start>yes</run_on_start>

  <log_analytics>
    <auth_path>/var/ossec/wodles/credentials/azure_credentials</auth_path>
    <tenantdomain>mycompany.onmicrosoft.com</tenantdomain>
    <request>
      <query>AzureActivity | where Level == "Error"</query>
      <workspace>12345678-90ab-cdef-1234-567890abcdef</workspace>
      <time_offset>12h</time_offset>
    </request>
  </log_analytics>

  <graph>
    <auth_path>/var/ossec/wodles/credentials/azure_credentials</auth_path>
    <tenantdomain>mycompany.onmicrosoft.com</tenantdomain>
    <request>
      <query>auditLogs/signIns</query>
      <time_offset>1d</time_offset>
    </request>
  </graph>
</wodle>

Module Parameters

ParameterDescription
disabledEnable or disable the module (no/yes)
run_on_startExecute on service startup (yes/no)
auth_pathPath to the credential file
tenantdomainAzure AD tenant domain name
queryLog Analytics query (KQL) or Graph API resource
workspaceLog Analytics workspace identifier
time_offsetTime window for the query (1d, 12h, 1h)
content_typeData format in Blob Storage (json_inline, json_file)

Log Analytics Integration

Azure Log Analytics Workspace aggregates data from various Azure sources. The Wazuh module executes KQL (Kusto Query Language) queries against the workspace to extract events.

Obtaining the Workspace ID

  1. Navigate to Log Analytics workspaces in the Azure portal
  2. Select the workspace
  3. Copy the Workspace ID from the Overview section

Useful KQL Queries

Activity errors query:

AzureActivity | where Level == "Error"

Security events query:

SecurityEvent | where EventID == 4625

Resource changes query:

AzureActivity | where OperationNameValue contains "write" or OperationNameValue contains "delete"

Alert Examples

Suspicious Azure AD Sign-In

{
  "rule": {
    "id": "62503",
    "level": 5,
    "description": "Azure AD: Sign-in from unusual location"
  },
  "data": {
    "azure": {
      "category": "SignInLogs",
      "operationName": "Sign-in activity",
      "properties": {
        "userPrincipalName": "user@company.com",
        "ipAddress": "198.51.100.42",
        "location": {
          "countryOrRegion": "CN"
        },
        "status": {
          "errorCode": 0,
          "additionalDetails": "MFA completed"
        }
      }
    }
  }
}

Critical Resource Modification

{
  "rule": {
    "id": "62510",
    "level": 7,
    "description": "Azure: Critical resource modification detected"
  },
  "data": {
    "azure": {
      "operationName": "Microsoft.Network/networkSecurityGroups/write",
      "category": "Administrative",
      "caller": "admin@company.com",
      "properties": {
        "statusCode": "Created",
        "resource": "production-nsg"
      }
    }
  }
}

Compliance Policy Violation

{
  "rule": {
    "id": "62520",
    "level": 6,
    "description": "Azure Policy: Non-compliant resource detected"
  },
  "data": {
    "azure": {
      "operationName": "Microsoft.Authorization/policyAssignments/write",
      "category": "Policy",
      "properties": {
        "complianceState": "NonCompliant",
        "policyDefinitionName": "require-tag-on-resources"
      }
    }
  }
}

Use Cases

Detecting Suspicious Sign-Ins

  • Sign-ins from atypical geographic locations
  • Multiple failed authentication attempts
  • Sign-ins from anonymous IP addresses (Tor, VPN)
  • Sign-ins from devices without MFA when an MFA policy is active

Monitoring Resource Changes

  • Virtual machine creation or deletion
  • Network Security Group rule modifications
  • Key Vault access policy changes
  • Subscription setting modifications

Compliance Control

  • Tracking resources missing mandatory tags
  • Monitoring unencrypted data stores
  • Controlling privileged Azure RBAC role assignments
  • Tracking Azure Policy deviations

Troubleshooting

Module Cannot Connect to Azure

  • Verify that the Application ID and Client Secret are correct
  • Confirm the secret has not expired
  • Check that the required permissions are assigned to the application
  • Ensure admin consent has been granted

Empty Log Analytics Results

  • Verify the Workspace ID is correct
  • Confirm the workspace contains data for the requested period
  • Test the KQL query in the Azure Portal (Log Analytics - Logs)
  • Check the time_offset value to ensure it covers a period with data

Microsoft Graph Authentication Errors

  • Verify that API permissions are assigned as Application type, not Delegated
  • Confirm admin consent has been granted
  • Check that the tenant domain is specified correctly
  • Review /var/ossec/logs/ossec.log for HTTP error details

Python Dependencies

The module requires Python 3.8-3.13 and additional libraries:

/var/ossec/framework/python/bin/pip3 install azure-storage-blob azure-identity

Related Sections

Last updated on