On this page

Microsoft published its technical analysis of GigaWiper on July 9, 2026. Microsoft describes it as a modular backdoor with destructive capabilities, including scheduled-task persistence, RabbitMQ-over-AMQP command C2, Redis status and output reporting, potential file transfer to remote storage through the MinIO client, interactive system management, event-log clearing, fake ransomware, and several ways to make a Windows device unrecoverable.

Three days earlier, Microsoft updated its Sentinel Repositories documentation with a capability of direct interest to detection engineers: Defender XDR custom detection rules as code. The preview uses the Microsoft Security Bicep extension and the new Microsoft.Security/detectionRules@2026-06-01-preview resource.

The documentation update and threat-research post arrived close enough together to support a focused validation exercise.

How quickly can a SOC turn new Microsoft threat intelligence into a reviewed, tested, version-controlled Defender detection?

That workflow is the focus of this post. GigaWiper is the case study, and detection as code is the reusable capability.

Results at a glance

Path or evidenceResult
Native Sentinel Repository synchronizationFailed. The preview provider returned an internal error; the root cause remains unconfirmed.
Graph fallbackSix exact objects were created or updated and read back. No alerts are attributed to them.
Portal-native validationExactly three custom alerts—from NLS-GW-LIVE-001, NLS-GW-LIVE-003, and NLS-GW-LIVE-004—were correlated into incident 628.
GigaWiper executedNo. The lab generated bounded benign telemetry only.
Recovery and boot behaviorNLS-GW-002 was validated with synthetic fixtures only.
.candy ruleNLS-GW-005 matched live telemetry; no saved portal rule or alert is claimed.

Companion lab: The complete Bicep pack, KQL hunts, GitHub Actions workflows, safe telemetry generator, synthetic fixtures, and evidence ledger are in j-dahl7/gigawiper-detection-as-code.

Every screenshot and diagram below links to its original-resolution file. On a phone, tap a dense figure to inspect its labels at full size.

Detection-as-code architecture separating the observed native Sentinel Repositories result, a bounded manual GitHub OIDC to Microsoft Graph fallback, and portal-native alert validation
The intended native Repository branch returned an internal preview-provider error whose root cause remains unconfirmed. A separate, manual, Graph-only GitHub OIDC workflow deployed the six validation-revision exact IDs without stored secrets, Azure RBAC, deletion, or response actions. The diagram keeps those outcomes separate and records that later query hardening was not redeployed.

Where custom detections fit

Microsoft already lists Defender protection for GigaWiper and related activity, including malware-family detections and ransomware behavior alerts. These organization-owned rules complement Microsoft-managed protection; they are not presented as a prerequisite for GigaWiper coverage.

Microsoft-managed detections provide vendor threat intelligence, signatures, behavior models, and broadly distributed protection. Organization-owned detections address a complementary need:

  • the query logic is visible and reviewable;
  • environmental context can be added;
  • rule changes go through pull requests;
  • stable identifiers support auditability;
  • property changes can be rolled back with a Git revert followed by the configured deployment path; rule deletion remains a separate exact-ID operation because the Graph fallback deliberately does not prune removed files;
  • related tools can be detected even when they do not match the exact known sample;
  • a SOC can document exactly what it tested and what it did not.

The custom rules here are behavioral guardrails and detection-engineering examples. A match is an investigation signal, not automatic attribution to GigaWiper.

What changed in July: custom detections join Sentinel Repositories

Sentinel Repositories already supported analytics rules, automation rules, hunting queries, parsers, playbooks, and workbooks. The July preview adds Defender XDR custom detection rules through a different Bicep extension and resource provider.

The root configuration loads the Microsoft Security extension:

{
  "extensions": {
    "MicrosoftSecurity": "br:mcr.microsoft.com/bicep/extensions/microsoftsecurity:v1.0.1"
  }
}

A custom rule then uses the preview resource:

extension MicrosoftSecurity

resource detectionRule 'Microsoft.Security/detectionRules@2026-06-01-preview' = {
  id: 'nls-gw-003-event-log-destruction'
  displayName: 'NLS-GW-003 - Windows Event Log Destruction'
  status: 'enabled'
  queryCondition: {
    queryText: '''
DeviceProcessEvents
| where FileName =~ "wevtutil.exe"
| where ProcessCommandLine has_any (" cl ", " clear-log ")
| project Timestamp, DeviceId, ReportId, DeviceName, FileName, FolderPath, ProcessCommandLine
'''
  }
  schedule: {
    frequency: 'PT1H'
  }
  detectionAction: {
    alertTemplate: {
      title: 'Windows event log clearing observed on {{DeviceName}}'
      description: 'Validate the target log and administrator intent.'
      severity: 'high'
      tactics: [
        {
          tactic: 'DefenseEvasion'
          techniques: [
            { technique: 'T1070.001' }
          ]
        }
      ]
      entityMappings: {
        hosts: [
          { id: 'device', deviceIdColumn: 'DeviceId' }
        ]
      }
    }
  }
}

ATT&CK taxonomy note: During this validation, the live Microsoft custom-detection service accepted the legacy T1070.001 mapping shown above. The current MITRE ATT&CK catalog identifies Clear Windows Event Logs as T1685.005. This records taxonomy and platform drift; it does not imply that the current preview provider accepts the newer mapping.

The preview requires Microsoft 365 E5 or an equivalent license that includes Defender XDR and a Sentinel workspace onboarded to the Defender portal. The standard GitHub Repository prerequisites still apply: collaborator access to the repository, GitHub Actions enabled, and Owner on the resource group to create the connection. Portal-native custom-detection creation is limited to the tenant’s primary Sentinel workspace and separately requires the applicable Defender or Sentinel management permissions plus access to the selected device scope.

The Repository/Bicep preview currently limits custom details and custom frequency for Sentinel-only data. The general portal experience supports those capabilities, so this limitation is deployment-path specific. A custom rule can generate at most 150 alerts each time it runs. In this tenant during the July 11–12 validation window, the service accepted only one MITRE tactic per custom detection even though the public Graph model represents tactics as an array. The native-path provider response described below was a separate result.

Observed Preview Contract

Validation window: July 11–12, 2026
Resource API: 2026-06-01-preview
Bicep extension: v1.0.1
Portal: Microsoft Defender portal
Status: Preview

Treat every field and limitation as versioned. Preview behavior can change after this post is published.

A rule-ID constraint discovered during preview deployment

The first canary used a conventional GUID as its rule ID. Bicep compiled it successfully. The live Microsoft Security provider returned a validation error because the GUID began with a number.

In this deployment, the provider error was precise: a rule ID must be numeric, or it must begin with a letter and then contain only letters, numbers, dashes, and underscores. The maximum length reported by that live error was 100 characters. This is an observed preview-provider contract, not a regex currently published in the public Graph schema.

That matters because the same Microsoft documentation page also contains general Sentinel Bicep guidance to remove exported ARM id properties. Those instructions apply to a different content implementation. A Defender XDR custom detection using Microsoft.Security/detectionRules explicitly requires its own stable ID.

The lab now uses readable IDs such as:

nls-gw-001-onedrive-persistence
nls-gw-002-recovery-boot-tampering
nls-gw-003-event-log-destruction

A disabled canary provides an early validation point in a preview deployment. Its impossible-match query and disabled status prevented it from generating an alert while still exercising compilation and provider validation. That surfaced the contract before the same invalid ID pattern spread across the full pack.

Separating tactic validation from the native provider response

Two initial rules declared two tactics each: Persistence plus Defense Evasion for the scheduled-task chain, and Impact plus Defense Evasion for recovery tampering. Every template compiled, and the Repository workflow authenticated. The live deployment returned InvalidTemplateDeployment, while direct Bicep returned a generic provider error.

Submitting the same rule body to the documented Microsoft Graph custom-detection API returned a more specific service constraint:

InvalidInput - Only one tactic is currently supported.

The Graph response isolated the validation result to tactic metadata rather than Bicep compilation or KQL parsing; it did not by itself validate detection quality. During this validation, the preview service accepted a narrower tactic shape than the public Graph model represents. I kept the primary tactic on each rule—Persistence for the OneDrive-lookalike chain and Impact for recovery tampering—and added a CI guard that permits one tactic: block per rule before merge.

That Graph response is distinct from the later native Repository result. Graph returned an actionable InvalidInput response for the multi-tactic body. After that body was adjusted and all six rules were accepted directly, the native Repository path returned outer InvalidTemplateDeployment and inner ProviderError: Encountered internal server error for every exact template. The first was a specific content-validation response; the second was a non-specific native-path response with no confirmed root cause.

The detection-as-code lesson is that compiler success establishes schema shape, not service acceptance. A canary plus an API-level validation path can translate a non-specific deployment response into a testable repository contract.

Analytics rules and custom detections use different contracts

QuestionSentinel analytics ruleDefender XDR custom detection
Primary query surfaceLog Analytics and Sentinel tablesAdvanced Hunting plus supported Sentinel data
Typical resource familyMicrosoft.SecurityInsights/alertRulesMicrosoft.Security/detectionRules
ID behaviorExported ARM properties may need removal during Bicep conversionExplicit stable rule ID is required
Deployment ownershipPortal, API, IaC, or Sentinel RepositoriesPortal, Graph API, direct Bicep, or the new Repository preview
Response modelSentinel incidents and automationDefender alerts and supported response actions
Columns enforced by this labDepends on rule and entity mappingThis pack’s endpoint-query contract requires Timestamp, DeviceId, and ReportId from the relevant event

The distinction matters when converting an existing Sentinel lab. Rather than wrapping existing analytics-rule JSON in Bicep, this post builds native Defender XDR custom detections against Advanced Hunting tables. The three-column check is deliberately scoped to this pack’s Device* queries and host mapping; it is not a claim that every custom-detection query in every supported data source has one universal column contract.

From a malware report to a behavior map

Microsoft documented 20 backdoor commands. I did not turn all 20 into alerts. More rules do not automatically create better coverage.

The lab selects five behaviors for its defensive scope and separates pre-impact or impact-adjacent signals from an impact-stage rename signal. Microsoft presents the backdoor commands as flexible, on-demand capabilities; this map does not assert a fixed execution order.

Non-directional GigaWiper behavior coverage map showing five independent Defender XDR detection opportunities across flexible on-demand commands
The desired-state pack defines five enabled behavior rules covering independent command behaviors, not a documented chain. A sixth resource—the disabled deployment canary—sits outside the map. The first four rules target signals that can occur before or near impact; the .candy rule detects an impact-stage rename burst but does not by itself establish encryption or data loss. This is a coverage map, not a deployment-state claim: the current NLS-GW-001 and NLS-GW-005 queries were revalidated read-only but were not redeployed to the retained Graph objects.
RuleBehaviorTable designEvidence method
NLS-GW-001OneDrive Update task plus TaskCache or matching OneDrive registry activityDeviceProcessEvents joined with DeviceRegistryEvents, then deduplicated after correlationObserved benign telemetry plus a portal-native scheduled alert from the validation revision
NLS-GW-002Recovery and boot tampering commandsDeviceProcessEventsSynthetic only
NLS-GW-003wevtutil log clearingDeviceProcessEventsCustom lab-log telemetry plus a portal-native scheduled alert
NLS-GW-004MinIO client transfer-oriented executionDeviceProcessEventsFilename-only safe emulator plus a portal-native NRT alert
NLS-GW-005Burst of .candy file renamesOptimized five-minute time-key window joinLive query results plus synthetic validation; no portal rule claimed

NLS-GW-003 intentionally follows the command-line wevtutil behavior Microsoft reports for GigaWiper. Process and filename matching can miss renamed or wrapped tooling, direct Windows Event Log API use, or direct .evtx deletion. Security event 1102 and log-file tampering signals are useful defense-in-depth; this rule is not presented as exhaustive event-log-clearing coverage.

Why the network hunt is scoped to infrastructure and behavior

GigaWiper uses RabbitMQ over AMQP for commands and Redis for status and output. DeviceNetworkEvents can show the remote address, port, protocol, initiating process, path, hash, and command line. Those fields do not establish that an arbitrary TCP connection contains RabbitMQ or Redis application traffic.

The companion hunt therefore has two layers:

  1. an IOC hunt for the infrastructure Microsoft published;
  2. a behavioral hunt for rare executable-to-destination combinations involving the observed ports.

Neither is described as application-protocol inspection.

Continuous detection versus scheduled correlation

Microsoft’s continuous near-real-time custom detections have specific query constraints. A continuous query must use one supported table and cannot use joins or unions.

That divides this pack naturally:

DetectionDesign decision
Event-log clearingPotential single-table NRT candidate after replacing operators outside the NRT-supported subset; no NRT rewrite was saved or validated in this lab
Recovery and boot tamperingPotential single-table NRT candidate after a compatible rewrite; no NRT rewrite was saved or validated in this lab
MinIO mc.exe executionThe portal accepted the exact single-table query as Continuous in this tenant, but its has_any operator is not in Microsoft’s linked NRT operator list; revalidate or rewrite it before reuse
.candy rename burstScheduled only as written; its multi-record aggregation is not NRT-compatible
Task plus registry persistenceMulti-table scheduled correlation

All checked-in templates use the hourly frequency: PT1H contract. The live objects also exposed deprecated runtime and schedule fields, including lastRunDetails and nextRunDateTime, that Microsoft plans to remove on October 1, 2026. Automation should treat frequency as the durable schedule field. Accordingly, this article labels a rule NRT only where the exact preview behavior was deployed and observed.

GitHub validation, the native preview result, and a bounded Graph fallback

The pull-request validation workflow has no Azure or Graph deployment credentials. It performs only deterministic validation:

permissions:
  contents: read

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
      - run: az bicep install --version v0.45.6
      - shell: pwsh
        run: ./scripts/Test-Lab.ps1

The PowerShell test enforces eight core content contracts:

  1. all six expected templates exist;
  2. every Bicep file compiles;
  3. rule IDs satisfy the live provider format;
  4. IDs and display names are unique;
  5. this pack’s endpoint queries return Timestamp, DeviceId, and ReportId;
  6. each preview rule declares only one MITRE tactic;
  7. no automatic response action or prohibited destructive operation is present;
  8. normalized exact-query fixtures cover all five behavior rules with one positive and one negative case each.

The intended post-merge path was native Sentinel Repository synchronization. The connection configuration was accepted: it targeted main, selected CustomDetection, created the expected OIDC workflow, and provisioned the documented Microsoft Graph application permission. A token-safe diagnostic showed that the connection identity held CustomDetection.ReadWrite.All and could read a custom rule by exact ID.

Repeated generated Repository workflow attempts returned InvalidTemplateDeployment with an inner ProviderError: Encountered internal server error for all six corrected templates. The same content compiled, direct delegated Bicep reached the service, and direct Graph operations accepted and read the rules. The documented Owner prerequisite for creating the connection was already satisfied. A temporary Azure Security Admin assignment did not change the native deployment result and was removed. No additional documented provider-path role was identified. These observations locate the stage where native processing stopped; the root cause remains unconfirmed.

The connection-generated native workflow and helper used during validation are retained outside .github/workflows as non-reusable evidence artifacts, so they cannot run from the public repository. Merging to main validates content but does not retry the native path. A future native test requires a new Repository connection and freshly generated files; before use, those files must be reviewed, confirmation-gated, serialized against the Graph fallback, and authorized only after ownership is deliberately transferred.

Microsoft Defender Sentinel Repositories page showing the GigaWiper GitHub connection on main in a Failed state
The Defender portal records the native Repository connection on main as Failed. The workflow evidence ledger preserves the nested InvalidTemplateDeployment and provider error; this list view shows only the terminal state.

To keep the native and fallback outcomes distinct, I added a bounded fallback for this preview-era lab. The fallback:

  • uses a dedicated Entra application with only CustomDetection.ReadWrite.All;
  • exchanges GitHub OIDC for an app-only token, with no stored client secret;
  • has zero Azure RBAC assignments;
  • applies changes manually from main only after the exact confirmation DEPLOY_PREVIEW_FALLBACK; its separate inspection mode is read-only and uses exact-ID GETs;
  • compiles the same checked-in Bicep before extracting the rule body;
  • performs an exact-ID GET followed only by POST or PATCH;
  • never deletes, prunes, or adopts a differently identified rule;
  • reads every exact ID back and verifies status, schedule, KQL, alert metadata, MITRE mapping, entity mapping, and zero response actions.

GitHub Actions run 29180593038 completed successfully on July 12, 2026. All six stable IDs returned HTTP 200 on update and passed read-back validation: nls-gw-000-canary remained disabled, and NLS-GW-001 through NLS-GW-005 remained enabled. Those retained Graph objects contain the validation revisions deployed by that run. The later hardened NLS-GW-001 query and optimized NLS-GW-005 query were independently re-run read-only against retained live telemetry, but neither current revision was applied to the retained Graph objects and no new alert is attributed to either one.

Read-only exact-ID inspection runs 29193356536 and 29193929962 confirmed hourly scheduler metadata and zero current or deprecated response actions. After the safe events arrived, all five enabled rules showed lastRunDateTime 2026-07-12T13:09:25.6533333Z and nextRunDateTime 2026-07-12T14:09:25.6533333Z, with empty last-run status, error-code, and failure-reason fields. Those timestamps establish service scheduling only; no alert is attributed to the Graph-fallback objects.

Successful read-only GitHub Actions inspection showing the five enabled GigaWiper custom detections on hourly schedules with post-telemetry last-run and next-run timestamps
The post-telemetry inspector read the six exact Graph IDs without changing them. The five behavior rules show hourly schedules, a common 13:09:25Z last run, and a 14:09:25Z next run; the complete job summary also records zero response actions. Scheduler metadata is not alert attribution.
Successful manually triggered GitHub Actions Graph fallback deployment with exact rule IDs, HTTP 200 responses, rule status, and zero response actions
The manually dispatched Graph fallback succeeded. All six exact-ID updates are visible with HTTP 200, the canary disabled, five behavior rules enabled, and zero recorded response actions. The later read-only inspector separately checked both the current and deprecated action models and confirmed zero actions.

This fallback is separate from native Repository synchronization and is not presented as a general replacement for Sentinel Repositories. Microsoft documents beta APIs as unsuitable for production use, and this create/update path is currently available only in the Global service, not US Government L4, US Government L5 (DOD), or China operated by 21Vianet. CustomDetection.ReadWrite.All is the API’s least-privileged write permission, but it can write all custom detections in the tenant. The dedicated app, OIDC federation, environment restrictions, and zero Azure RBAC are therefore essential controls for this bounded fallback. It should remain mutually exclusive with a working native synchronization path.

Before the three separately created portal-native validation rules were added, the portal-list check did not satisfy the Graph-object visibility gate. The unified Detection Rules page returned no NLS-GW rows even though Microsoft Graph continued to read all six exact fallback objects successfully. The later portal-native rows do not establish visibility or alert attribution for those six different IDs. Their portal visibility therefore remains pending, and the evidence does not yet distinguish preview replication behavior from portal authorization or UI filtering.

Microsoft Defender Custom detection rules page returning zero items for an NLS-GW search
At this point in the validation sequence, an exact NLS-GW search returned zero rows even though Microsoft Graph continued to read all six fallback objects by exact ID. The later, separately created portal-native rules do not change the scope of this historical observation.

Safe telemetry that exercises the detection path

The endpoint test script performs four bounded actions on a disposable, MDE-onboarded Windows VM.

Endpoint readiness requires separate checks. The extension can report onboarding success, SENSE can be running, and the registry can show onboarding state 1 while the tenant-level Defender for Endpoint service is still activating. In this lab, the machine API initially returned Account mode is inactive even though LastConnected was current. Microsoft documents that onboarding Defender for Endpoint through Defender for Cloud for the first subscription in a tenant can take up to 12 hours; later machines and subscriptions can take up to one hour. I waited until the machine API reported the endpoint Onboarded and Active, and until Advanced Hunting returned its DeviceInfo, before generating telemetry; local sensor health alone is not collection evidence.

1. Persistence correlation

It creates:

  • HKU\S-1-5-18\SOFTWARE\OneDrive\Environment when the Azure Run Command executes as SYSTEM, or HKCU\SOFTWARE\OneDrive\Environment in an interactive elevated run, with a value explicitly labeled SAFE-TELEMETRY-ONLY;
  • a scheduled task named OneDrive Update whose action is only the inert, ownership-marked command cmd.exe /c rem NLS-GigaWiper-SafeTelemetry.

The query correlates the process event with either the matching OneDrive registry activity or Windows’ own TaskCache\Tree\OneDrive Update registration. Live Server 2022 telemetry reliably surfaced the TaskCache entry but did not surface the harmless lab registry marker, so the checked-in rule preserves both paths because collection differs between these registry locations. The task does not run hidden, repeat every minute, download anything, or persist malicious code.

2. Event-log clearing

The script creates its own NLS-GigaWiper-Lab event log, writes one marker, and clears only that custom log. It never clears Security, System, Application, Setup, or ForwardedEvents.

3. MinIO filename simulation

The script copies cmd.exe into the lab directory as mc.exe and invokes it only to print a safe marker containing a transfer keyword. This validates filename and command-line telemetry. It does not validate MinIO client execution, network transfer, or exfiltration.

Microsoft Defender Advanced Hunting returning two safe mc.exe process telemetry rows from the disposable GigaWiper lab endpoint
A device-scoped 12-hour recheck of the checked-in DeviceProcessEvents logic returned two mc.exe rows from nls-gw-lab. Both were bounded marker commands with no network transfer. These are telemetry matches, not custom alerts.

4. .candy decoys

Eight inert copies of the lab VM’s %SystemRoot%\System32\cmd.exe are renamed from .tmp to .candy in Public Documents. They are never executed as .candy; no content is encrypted, deleted, or made unrecoverable. Two small text-file variants initially surfaced only their directory creation. The copy-plus-move variant arrived later: seven FileRenamed rows became visible after an ingestion delay, and the exact NLS-GW-005 query returned one seven-file burst. That historical ad-hoc run used public-*.candy, which is why the evidence graphic carries that label; the reproducible checked-in harness uses decoy-##.candy in the same observed Public Documents path.

The recovery and boot rule remains synthetic-only. The lab never executes reagentc /disable, boot-policy-changing bcdedit commands, permission changes against boot files, raw-disk operations, or wiping routines.

The exact checked-in queries returned Advanced Hunting matches for NLS-GW-001, NLS-GW-003, NLS-GW-004, and NLS-GW-005. Only the recovery and boot rule, NLS-GW-002, remains synthetic-only in this validation record.

Advanced Hunting evidence summary showing four safe KQL query matches, not custom alerts, with recovery tampering explicitly labeled synthetic-only
Rendered from live Microsoft Graph Advanced Hunting results for the disposable endpoint. Query matches are not custom alerts: this summary records that safe telemetry reached the checked-in KQL, while the separately scoped portal-native alert validations appear below.

Three portal-native rules validate the scoped alerting paths

The Graph fallback confirmed that Microsoft Graph accepted and read back the six exact rule objects, but those objects did not appear in the unified Detection Rules page during validation. Their later scheduler metadata was not alert evidence. I therefore created three separate portal-native, alert-only custom detections to test the live evaluator without attributing those alerts to the native Repository connection or to Graph-created objects that were not visible in that page.

Each validation rule used the then-current checked-in query for its numbered detection and had zero response actions. Defender recorded all three as Custom detection alerts from Microsoft Defender for Endpoint, with each alert tied to the same onboarded nls-gw-lab device:

Portal ruleConfigurationPortal-native alert evidence
NLS-GW-LIVE-001High, Persistence, scheduled; created July 12 at 09:39:42 in the portal’s UTC-5 viewInitial evaluation completed and linked alert ede0f56adf-2532-41c2-98a8-ac08a2481201_aml to incident 628 at 09:46:42
NLS-GW-LIVE-003High, Defense Evasion, scheduled; created July 12 at 09:53:08 in the portal’s UTC-5 viewInitial evaluation completed and linked alert ed1f17e8f7-3600-4c97-867e-b6bd1c987c37_aml to incident 628 at 10:00:38
NLS-GW-LIVE-004Medium, Exfiltration, Continuous (NRT)Alert eda016b9bd-4631-44d3-baa6-314b4f7ed032_aml appeared after a new post-creation marker, included it as last activity, and linked to incident 628

The alert-detail view records incident 628 at High severity with three active alerts out of three.

The NLS-GW-LIVE-001 and NLS-GW-LIVE-003 alerts were generated when Defender ran each new scheduled rule’s documented initial evaluation over prior benign endpoint telemetry. Microsoft says a newly saved custom detection checks up to 30 days of existing data before following its configured frequency. These were service-generated alerts from initial evaluation rather than synthetic datatable() results; the historical activity preceded rule creation. NLS-GW-LIVE-004 provides complementary evidence: the service-generated NRT alert incorporated a matching event after the rule was enabled. Because its first activity predates rule creation, I do not attribute the alert solely to the post-rule marker.

For NLS-GW-LIVE-004, the safe harness generated a new mc.exe marker only after the rule was active. It completed at 2026-07-12 12:30:45Z with NetworkTransfer=False, and Defender added the medium-severity custom alert to incident 628 at approximately 12:33Z. Its first activity was an earlier safe query match, while its last activity was the post-creation marker at 12:30:45Z. The portal accepted this exact query in this tenant even though its has_any operator is not in Microsoft’s linked NRT operator list; treat that as observed service behavior and revalidate or rewrite the query before reuse.

Medium-severity NLS-GW-LIVE-004 custom detection alert for nls-gw-lab showing its device entity and no response actions taken
The NLS-GW-LIVE-004 medium-severity custom alert mapped the nls-gw-lab device and explicitly recorded that no actions were taken in response. The marker remained telemetry-only: it did not transfer data or trigger containment.
Microsoft Defender incident 628 Alerts-tab capture showing exactly NLS-GW-LIVE-004, NLS-GW-LIVE-003, and NLS-GW-LIVE-001 as three active alerts on nls-gw-lab
Tightly cropped Microsoft Defender incident 628 Alerts-tab capture. It shows the High, Active incident with exactly three alerts—NLS-GW-LIVE-004, NLS-GW-LIVE-003, and NLS-GW-LIVE-001—and each row maps to nls-gw-lab. The crop removes the global portal header and account or tenant identifiers; it does not alter the incident or alert rows. These are the separately created portal-native LIVE rules, not the six Graph-fallback objects.
Microsoft Defender incident 628 for the NLS-GW-LIVE-004 safe MinIO marker with one active alert and mapped device, process, and file entities
Historical first-alert snapshot captured when NLS-GW-LIVE-004 was the only custom alert in incident 628. It shows one active alert plus mapped device, process, and file context; the incident later reached High severity with three active alerts out of three after the two scheduled-rule alerts were added.

Evidence established: the three query revisions checked in during validation matched MDE-ingested telemetry; Defender’s scheduled and Continuous evaluators produced three portal-native custom alerts; all three were correlated into incident 628 on the same device; and zero response actions ran. NLS-GW-LIVE-001 and NLS-GW-LIVE-003 demonstrate initial scheduled evaluation over prior benign telemetry, while NLS-GW-LIVE-004 demonstrates that the NRT alert incorporated a new post-rule event as its last activity. A later audit hardened NLS-GW-001’s post-correlation deduplication; that current revision independently re-matched the retained live telemetry but was not deployed to the retained Graph or portal rules and is not attributed a new alert.

Evidence boundaries: this does not establish native Sentinel Repository synchronization, alert attribution to the six Graph-fallback objects, or execution of GigaWiper or destructive activity. The native connection remains in the portal’s Failed state, and the three attributed alerts belong only to the separately created portal-native validation rules.

NLS-GW-005 remains an explicit boundary. The exact optimized time-window query returned one seven-file match, and a representative raw-row query returned live DeviceFileEvents results. However, repeated attempts in fresh unified custom-detection wizards returned Supported entities could not be loaded and left Add assets disabled. Because that control remained unavailable, no NLS-GW-005 portal rule or custom alert is claimed. I record this as an observed wizard outcome with no assigned root cause, not as evidence that aggregate custom detections or NLS-GW-005 are unsupported. Its evidence remains live query validation, not alert validation.

Three evidence levels

These levels distinguish query behavior, sensor collection, and alert generation.

Observed benign telemetry

The endpoint performs the bounded action, Defender collects it, and the result appears in Advanced Hunting.

Synthetic query fixtures

datatable() rows exercise the KQL logic for actions that must not be performed. The fixture now embeds normalized exact copies of all five current behavior queries and checks five positive plus five negative cases, including the multi-process persistence regression and a .candy burst that crosses a clock boundary. The local validator prevents fixture/query drift, and the separate read-only runner executed all ten rows successfully through Advanced Hunting. A passing synthetic query shows query behavior against those rows. It does not establish sensor collection, scheduler operation, alert generation, or Defender protection.

Live deployment evidence

This level records what the control plane and service did, including paths that did not complete and their returned errors. In this validation window, Bicep compilation passed; native Repository synchronization returned InvalidTemplateDeployment and inner ProviderError; manual Graph fallback run 29180593038 updated and read back all six exact IDs; the deployment canary was disabled; and five behavior rules were enabled. Read-only inspection runs 29193356536 and 29193929962 returned hourly scheduler metadata for those five enabled rules—including a post-telemetry run at 13:09:25Z—and counted zero current or deprecated response actions across all six objects, but they did not attribute an alert to them. Safe telemetry reached Advanced Hunting. Separately, the portal-native NLS-GW-LIVE-001, NLS-GW-LIVE-003, and NLS-GW-LIVE-004 rules used the then-current checked-in queries and generated three portal-native custom alerts in incident 628 with zero response actions.

The repository’s evidence ledger records each claim. The three LIVE rules validate only their scoped alerting paths—scheduled for NLS-GW-LIVE-001 and NLS-GW-LIVE-003, and NRT for NLS-GW-LIVE-004. Native synchronization, Graph-object portal visibility, and the NLS-GW-005 wizard remain open validation items; Graph scheduler metadata is not alert attribution.

Built-in coverage and organization-owned rules

Microsoft’s GigaWiper article lists built-in Defender detections for GigaWiper, FlockWiper, possible ransomware activity, and ransomware behavior in the file system. Keep those protections enabled.

The safe filename emulator also triggered a separate Defender for Endpoint alert, System executable renamed and launched. This records an additional Microsoft-managed behavioral detection, but it is not labeled as a GigaWiper-family detection or as one of this pack’s custom alerts.

The custom pack adds transparency and local context:

Microsoft-managed protectionOrganization-owned detection
Vendor intelligence and malware-family knowledgeReviewable KQL and explicit assumptions
Signature and behavioral modelsEnvironment-specific allowlists and baselines
Automatically updated by MicrosoftChanged through the organization’s pull-request process
Broad customer protectionLocal response ownership and audit history
May identify the known family directlyCan identify similar pre-impact behavior without claiming family attribution

One does not replace the other.

Response priorities for suspected destructive activity

When several signals correlate on the same endpoint, prioritize preservation and containment.

  1. Rapidly verify whether the activity is authorized. When multiple high-confidence destructive indicators are present, or authorization cannot be confirmed immediately, isolate the endpoint through Defender under your incident-response authority.
  2. Preserve volatile evidence and capture the process tree, network connections, logged-on users, and nearby alerts.
  3. Investigate scheduled tasks, services, registry modifications, firewall changes, and newly written executables.
  4. Block confirmed malicious infrastructure and hashes while retaining behavior-based hunting.
  5. Review identity activity from the device and revoke affected sessions or credentials.
  6. Determine whether files were staged or transferred before destructive activity.
  7. Validate offline, immutable, and separately administered recovery paths.
  8. Rebuild rather than trust a device after confirmed boot, recovery, or raw-disk tampering.

Automated device isolation is deliberately not enabled by the Bicep templates. A filename such as mc.exe or an administrator clearing a custom log is not enough context for automatic containment in every environment.

What the validation established

The most reusable result is the delivery pattern around the five Bicep rules:

  • start with a disabled canary;
  • compile locally and in CI;
  • treat IDs as API contracts;
  • retain the native-provider result alongside successful stages;
  • keep the fallback manual, exact-ID, and separate from native synchronization;
  • use least privilege: Graph-only OIDC and no Azure RBAC for the fallback;
  • separate high-confidence alerts from hunts;
  • test high-risk logic with synthetic fixtures;
  • label the .candy rule as an impact-stage signal without treating a rename as evidence of encryption;
  • keep response automation opt-in;
  • maintain an evidence ledger;
  • clean up only exact lab artifacts.

The enduring result is the governed path from threat intelligence to a verifiable custom-rule deployment. Three separately scoped portal-native rules provide recorded evidence of scheduled and NRT evaluation, alert creation, entity mapping, incident correlation, and zero response actions. Native Repository synchronization remains recorded as an observed non-completion and is kept separate from that alert evidence. NLS-GW-005 remains query-validated only; no portal rule or alert is claimed.

The retained Graph objects still contain the validation revisions while the repository carries later hardening for NLS-GW-001 and NLS-GW-005. That documented drift is a lifecycle lesson, not alert evidence: detection as code is not complete until one authorized owner path deliberately reconciles desired and deployed state, revalidates the result, and records new evidence. I did not redeploy those rules merely to make the publication look cleaner.

Cleanup

After validating ownership of every existing lab artifact before the first deletion, the safe telemetry script removes only:

  • the exact OneDrive Update lab task;
  • the exact NLSLabMarker value at the selected lab registry path, while preserving the parent key;
  • the exact custom lab event log and source;
  • the NLS-GigaWiper-Lab working directory and decoys.

The Azure endpoint lives in a dedicated resource group with the platform’s default inbound deny, no custom inbound NSG rules, and an expiration tag. Delete that disposable group after evidence capture.

Custom-detection cleanup is separate from endpoint cleanup:

  • Remove the Sentinel Repository connection, then verify that its connection-created managed identity and Microsoft Sentinel Contributor, Logic App Contributor, CustomDetection.ReadWrite.All, and branch-scoped GitHub OIDC grants are retired. Deselecting Custom Detection Rules only stops that content type and is not identity cleanup.
  • Delete the six exact Graph-fallback IDs—nls-gw-000-canary through nls-gw-005-candy-rename-burst—through Defender XDR or an appropriately authorized exact-ID Microsoft Graph workflow.
  • Separately delete the three portal-native rules: NLS-GW-LIVE-001, NLS-GW-LIVE-003, and NLS-GW-LIVE-004.
  • After rule cleanup or ownership transfer, remove the dedicated fallback app registration and its GitHub environment variables.
  • Remove the credential-less residual nls-gigawiper-validation-20260711 diagnostic app registration and its tenant-wide Graph grants.

The checked-in fallback intentionally has no delete or prune mode. Do not use a complete-mode resource-group deployment as a shortcut.

Sources

How is your team bringing code review and evidence tracking into the Defender detection lifecycle? Find me on LinkedIn or through the other links below.

Jerrad Dahlager

Jerrad Dahlager, CISSP, CCSP

Cloud Security Architect · Adjunct Instructor

Marine Corps veteran and firm believer that the best security survives contact with reality.

Have thoughts on this post? I'd love to hear from you.