Skip to content

Sigma CLI Kusto output not directly usable in Microsoft Sentinel (AWS S3 rule) #5876

@William1998

Description

@William1998

Sigma CLI Kusto output not directly usable in Microsoft Sentinel (AWS S3 rule)

Hi team, I am new to Sigma and currently testing AWS S3 detections with the Microsoft Sentinel (kusto) backend.

I noticed that the Sigma CLI output was not plug-and-play in Sentinel for this case, and I had to rewrite the generated query significantly before it would run.

Rule Used

title: AWS S3 C13 - Unauthorized External Bucket Access
id: 31c84e85-6e51-5005-bfdf-0b31c4fc8077
status: experimental
description: Detects S3 data events to external buckets that are not in approved account and bucket allowlists.
author: will
date: 2026-02-15
tags:
  - will.aws.s3
  - will.control.s3.c13
logsource:
  product: aws
  service: cloudtrail
detection:
  selection:
    eventSource: s3.amazonaws.com
    resources.accountId|exists: true
    resources.ARN|exists: true
  filter_authorized_accounts:
    resources.accountId:
      - "<authorized_external_account_id_1>"
      - "<authorized_external_account_id_2>"
  filter_authorized_buckets:
    resources.ARN|contains:
      - "arn:aws:s3:::<authorized_external_bucket_1>"
      - "arn:aws:s3:::<authorized_external_bucket_2>"
  condition: selection and (not filter_authorized_accounts or not filter_authorized_buckets)
falsepositives:
  - Newly approved external accounts or buckets that were not added to allowlists.
level: Medium

Sigma CLI Output (kusto backend)

(eventSource =~ "s3.amazonaws.com" and eventName =~ "PutObject") and ('requestParameters.bucketName' in~ ("<external_bucket_1>", "<external_bucket_2>")) and isnotempty('requestParameters.x-amz-acl') and (not('requestParameters.bucketName' =~ "<bucket_with_object_ownership_handover>"))

Problem

This query failed in Microsoft Sentinel.

Image

Manually Edited Query (works)

Image
AWSCloudTrail
| where TimeGenerated > ago(24h)
| extend _raw = parse_json(coalesce(column_ifexists("RawData", ""), column_ifexists("RawEventData", ""), "{}"))
| extend eventSource_v = coalesce(tostring(column_ifexists("eventSource", "")), tostring(_raw.eventSource))
| where eventSource_v =~ "s3.amazonaws.com"
| extend resources_v = coalesce(todynamic(column_ifexists("resources", dynamic([]))), todynamic(_raw.resources))
| mv-expand r = resources_v
| extend resourceAccountId = tostring(coalesce(r.accountId, r.AccountId))
| extend resourceArn = tostring(coalesce(r.ARN, r.arn))
| where isnotempty(resourceAccountId) and isnotempty(resourceArn)
| where resourceAccountId !in~ ("<authorized_external_account_id_1>", "<authorized_external_account_id_2>")
    or (
        resourceArn !contains "arn:aws:s3:::<authorized_external_bucket_1>"
        and resourceArn !contains "arn:aws:s3:::<authorized_external_bucket_2>"
    )
| project TimeGenerated, eventSource_v, resourceAccountId, resourceArn

Question

Is this expected behavior for the Sentinel/Kusto backend, or could this be a translation gap for nested CloudTrail fields (especially resources.*) that should be handled by Sigma CLI?

Reproduction Steps

  1. Create or use the Sigma rule shown above (AWS S3 C13 - Unauthorized External Bucket Access).
  2. Convert it to Kusto using Sigma CLI and the Sentinel/Kusto backend.
  3. Run the generated Kusto query in Microsoft Sentinel against AWSCloudTrail.
  4. Observe query failure in Sentinel.
  5. Replace it with the manually edited query above and re-run.
  6. Confirm the manual query runs successfully.

Expected Behavior

The Sigma-generated Kusto query should execute successfully in Sentinel without requiring significant manual rewrite (or even better, just plug and play).

Actual Behavior

The generated query fails in Sentinel and the eventual working version differs from the Sigma converted version significantly.

Follow-up Questions

  1. Is it expected that Sigma-to-backend conversion usually requires manual tweaks, or is there a recommended approach to get Sentinel output close to plug-and-play for this type of rule?
  2. I also tested multiple Kusto backend pipelines and got errors about missing values like query_table (see the following section). Is there a recommended Sentinel pipeline/configuration for this use case?
Error while converting: Unable to determine table name from rule. The query table is determined in the following order of priority:
  1) The value provided to processing pipeline's query_table parameter, if using a Python script.
  2) If the query_table is already set in the pipeline state, such as from a custom user-defined pipeline if using sigma-cli.
  3) If the rule's logsource category is present in the pipeline's category_to_table_mappings dictionary in mappings.py, use that value.
  4) If the rule has an EventID, use the table name from the pipeline's eventid_to_table_mappings dictionary in mappings.py.
For more details, see https://github.com/AttackIQ/pySigma-backend-kusto/blob/main/README.md#%EF%B8%8F-custom-table-names-new-in-030-beta.

Thank you very much!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions