T1485.001 Microsoft Sentinel · KQL

Detect Lifecycle-Triggered Deletion in Microsoft Sentinel

Adversaries may modify the lifecycle policies of a cloud storage bucket to destroy all objects stored within. Cloud storage buckets allow users to set lifecycle policies to automate migration, archival, or deletion of objects after a set period of time. If a threat actor has sufficient permissions to modify these policies, they can apply a rule that expires all objects within one day, achieving large-scale data destruction without issuing explicit delete commands. In AWS environments, an adversary with the s3:PutLifecycleConfiguration permission may invoke the PutBucketLifecycle API call to set a short-expiry deletion rule across an entire bucket. Adversaries have also exploited this mechanism against CloudTrail log storage buckets to destroy audit evidence alongside operational data, combining data destruction with indicator removal. Similar capabilities exist in Azure Blob Storage lifecycle management policies and GCP Storage object lifecycle management.

MITRE ATT&CK

Tactic
Impact
Technique
T1485 Data Destruction
Sub-technique
T1485.001 Lifecycle-Triggered Deletion
Canonical reference
https://attack.mitre.org/techniques/T1485/001/

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
let ShortExpiryThresholdDays = 7;
let SuspiciousLifecycleOperations = dynamic(["PutBucketLifecycle", "PutBucketLifecycleConfiguration"]);
// AWS S3 lifecycle policy abuse via AWSCloudTrail
let AWSLifecycleChanges = AWSCloudTrail
| where TimeGenerated > ago(24h)
| where EventSource == "s3.amazonaws.com"
| where EventName in (SuspiciousLifecycleOperations)
| extend RawParams = tostring(RequestParameters)
| extend BucketName = tostring(parse_json(RequestParameters)["bucketName"])
| extend ExpirationDaysStr = extract(@'"Days"\s*:\s*(\d+)', 1, RawParams)
| extend ExpirationDays = toint(ExpirationDaysStr)
| extend HasDateExpiration = RawParams contains "\"Date\""
| extend FilterPrefix = extract(@'"Prefix"\s*:\s*"([^"]*)"', 1, RawParams)
| extend RuleStatus = extract(@'"Status"\s*:\s*"([^"]*)"', 1, RawParams)
| extend IsEnabled = isempty(RuleStatus) or RuleStatus =~ "Enabled"
| extend IsShortExpiry = IsEnabled and (ExpirationDays > 0 and ExpirationDays <= ShortExpiryThresholdDays)
| extend IsWildcardPrefix = isempty(FilterPrefix)
| extend CloudProvider = "AWS"
| extend Actor = UserIdentityArn
| extend SourceIP = SourceIpAddress
| extend ResourceName = BucketName
| extend RiskScore = case(
    IsShortExpiry and IsWildcardPrefix, 4,
    IsShortExpiry, 3,
    IsWildcardPrefix and IsEnabled, 2,
    1)
| where IsEnabled
| project TimeGenerated, CloudProvider, Actor, ResourceName, ExpirationDays,
          HasDateExpiration, FilterPrefix, RuleStatus, IsShortExpiry, IsWildcardPrefix,
          RiskScore, SourceIP, UserAgent, AWSRegion, EventName, ErrorCode, ErrorMessage;
// Azure Blob Storage lifecycle policy changes via AzureActivity
let AzureLifecycleChanges = AzureActivity
| where TimeGenerated > ago(24h)
| where OperationNameValue =~ "microsoft.storage/storageaccounts/managementpolicies/write"
| where ActivityStatusValue =~ "Success"
| extend RawProps = tostring(Properties)
| extend ExpirationDaysStr = extract(@'"daysAfterModificationGreaterThan"\s*:\s*(\d+)', 1, RawProps)
| extend ExpirationDays = toint(ExpirationDaysStr)
| extend IsShortExpiry = ExpirationDays > 0 and ExpirationDays <= ShortExpiryThresholdDays
| extend CloudProvider = "Azure"
| extend Actor = Caller
| extend SourceIP = CallerIpAddress
| extend ResourceName = tostring(split(ResourceId, "/")[8])
| extend IsWildcardPrefix = true
| extend RiskScore = iff(IsShortExpiry, 3, 1)
| extend AWSRegion = ""
| extend EventName = OperationNameValue
| extend ErrorCode = ""
| extend ErrorMessage = ""
| extend RuleStatus = "Enabled"
| extend FilterPrefix = ""
| extend HasDateExpiration = false
| project TimeGenerated, CloudProvider, Actor, ResourceName, ExpirationDays,
          HasDateExpiration, FilterPrefix, RuleStatus, IsShortExpiry, IsWildcardPrefix,
          RiskScore, SourceIP, UserAgent, AWSRegion, EventName, ErrorCode, ErrorMessage;
union AWSLifecycleChanges, AzureLifecycleChanges
| sort by RiskScore desc, TimeGenerated desc
critical severity high confidence

Detects cloud storage lifecycle policy modifications that could enable bulk data destruction via automated expiration rules. Monitors AWS CloudTrail for PutBucketLifecycle and PutBucketLifecycleConfiguration API calls, and Azure Activity Log for managementpolicies/write operations on storage accounts. Assigns a risk score based on expiration window length (≤7 days = high risk) and whether the rule applies to the entire bucket (wildcard prefix = higher risk). Critical score (4) assigned to short-expiry rules with no prefix filter, indicating all objects in the bucket will be destroyed.

Data Sources

Cloud Storage: Cloud Storage ModificationAWS CloudTrail: S3 API CallsAzure Activity Log: Storage Account Operations

Required Tables

AWSCloudTrailAzureActivity

False Positives & Tuning

  • Legitimate data lifecycle management policies for cost optimization — organizations regularly configure long-expiry lifecycle rules to tier old objects to cheaper storage classes or delete them after compliance retention periods
  • Developer or DevOps engineers testing lifecycle configurations in non-production accounts or sandbox S3 buckets
  • Compliance-driven data destruction policies that legitimately set short retention windows for sensitive PII or regulated data to meet legal deletion requirements
  • Data pipeline cleanup rules that intentionally expire temporary processing artifacts or staging data after a short window
  • Terraform, CDK, or CloudFormation infrastructure-as-code deployments that apply lifecycle policies as part of automated stack provisioning or updates
Download portable Sigma rule (.yml)

Other platforms for T1485.001


Testing Methodology

Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Apply 1-Day Deletion Lifecycle to S3 Bucket

    Expected signal: AWS CloudTrail management event: EventName=PutBucketLifecycleConfiguration, EventSource=s3.amazonaws.com, requestParameters.bucketName=<BUCKET_NAME>. The requestParameters will contain the lifecycle JSON with Days=1 and empty Prefix. Sentinel AWSCloudTrail table: TimeGenerated, UserIdentityArn, EventName=PutBucketLifecycleConfiguration, SourceIpAddress, UserAgent=aws-cli.

  2. Test 2Apply Lifecycle Deletion to CloudTrail Log Delivery Bucket

    Expected signal: Two CloudTrail events: (1) DescribeTrails (readonly) showing reconnaissance step, (2) PutBucketLifecycleConfiguration against the CloudTrail log bucket. The combination of DescribeTrails immediately followed by PutBucketLifecycleConfiguration on the trail's S3 bucket is a high-fidelity indicator in the Sentinel hunting query 2.

  3. Test 3Azure Blob Storage Lifecycle Management Policy — Short Expiry

    Expected signal: Azure Activity Log event: OperationName=microsoft.storage/storageaccounts/managementpolicies/write, ActivityStatus=Succeeded, Caller=<UPN or service principal>, CallerIpAddress=<source IP>, ResourceId includes the storage account name. Event appears in Sentinel AzureActivity table within 5-15 minutes of execution.

  4. Test 4Enumerate S3 Buckets and Apply Bulk Lifecycle Deletion (Multi-Bucket Ransomware Simulation)

    Expected signal: Multiple PutBucketLifecycleConfiguration CloudTrail events in rapid succession, all with the same UserIdentityArn and SourceIpAddress, targeting different S3 buckets. Also generates a ListBuckets event immediately prior. This burst pattern (N lifecycle events in <5 minutes from single actor) is highly anomalous and directly triggers hunting query 1.

Unlock Pro Content

Get the full detection package for T1485.001 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections