T1535

Unused/Unsupported Cloud Regions

Defense Evasion Last updated:

Adversaries may create cloud instances in unused geographic service regions in order to evade detection. Access is usually obtained through compromising accounts used to manage cloud infrastructure. Cloud service providers provide infrastructure globally, but organizations typically monitor only a subset of available regions and may not have security tooling (GuardDuty, Security Hub, Defender for Cloud) enabled in every region. Resources created in unmonitored or lightly-monitored regions may go undetected, enabling adversaries to conduct cryptocurrency mining, command-and-control staging, data exfiltration, and lateral movement without triggering alerts configured for primary regions. A notable variation exploits regional gaps in security service coverage — certain AWS regions may lack GuardDuty enrollment, CloudTrail data events, or Security Hub aggregation by default.

What is T1535 Unused/Unsupported Cloud Regions?

Unused/Unsupported Cloud Regions (T1535) maps to the Defense Evasion tactic — the adversary is trying to avoid being detected in MITRE ATT&CK.

This page provides production-ready detection logic for Unused/Unsupported Cloud Regions, covering the data sources and telemetry it touches: Cloud: Cloud Infrastructure Modification, Cloud: Cloud Service, Azure Activity Logs, AWS CloudTrail. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.

MITRE ATT&CK

Tactic
Defense Evasion
Technique
T1535 Unused/Unsupported Cloud Regions
Canonical reference
https://attack.mitre.org/techniques/T1535/
Microsoft Sentinel / Defender
kusto
// CONFIGURE: Update these lists to match your organization's approved/actively monitored cloud regions
let ApprovedAzureRegions = dynamic(["eastus", "eastus2", "westus", "westus2", "westeurope", "northeurope", "uksouth", "ukwest"]);
let ApprovedAWSRegions = dynamic(["us-east-1", "us-west-2", "eu-west-1", "eu-central-1"]);
//
// Azure: Detect successful resource creation in unapproved regions
let AzureUnusualRegion =
AzureActivity
| where TimeGenerated > ago(24h)
| where ActivityStatusValue =~ "Succeeded"
| where OperationNameValue has_any (
    "Microsoft.Compute/virtualMachines/write",
    "Microsoft.Compute/virtualMachineScaleSets/write",
    "Microsoft.ContainerService/managedClusters/write",
    "Microsoft.Storage/storageAccounts/write",
    "Microsoft.Network/virtualNetworks/write",
    "Microsoft.Sql/servers/write",
    "Microsoft.Web/sites/write",
    "Microsoft.KeyVault/vaults/write",
    "Microsoft.Resources/resourceGroups/write"
  )
| extend ResourceLocation = tolower(extract('"location":"([^"]+)"', 1, tostring(Properties)))
| where isnotempty(ResourceLocation)
| where ResourceLocation !in (ApprovedAzureRegions)
| project
    TimeGenerated,
    Caller,
    CallerIpAddress,
    OperationNameValue,
    ResourceLocation,
    ResourceGroup,
    SubscriptionId,
    CorrelationId,
    CloudProvider = "Azure";
//
// AWS: Detect successful resource creation events in unapproved regions
let AWSUnusualRegion =
AWSCloudTrail
| where TimeGenerated > ago(24h)
| where isempty(ErrorCode)
| where EventName in~ (
    "RunInstances",
    "CreateBucket",
    "CreateCluster",
    "CreateFunction",
    "CreateDBInstance",
    "CreateDBCluster",
    "CreateVolume",
    "CreateVpc",
    "CreateUser",
    "CreateAccessKey",
    "CreateRole",
    "CreateStackInstances",
    "CreateSecret",
    "CreateKey"
  )
| where AWSRegion !in (ApprovedAWSRegions)
| project
    TimeGenerated,
    Caller = UserIdentityArn,
    CallerIpAddress = SourceIpAddress,
    OperationNameValue = EventName,
    ResourceLocation = AWSRegion,
    ResourceGroup = RecipientAccountId,
    SubscriptionId = RecipientAccountId,
    CorrelationId = EventTypeName,
    CloudProvider = "AWS";
//
union AzureUnusualRegion, AWSUnusualRegion
| extend RiskIndicators = pack_array(
    iff(CloudProvider == "AWS" and OperationNameValue in ("CreateUser", "CreateAccessKey", "CreateRole"), "IAM resource in unapproved region", ""),
    iff(OperationNameValue =~ "RunInstances" or OperationNameValue has "virtualMachines/write", "Compute instance in unapproved region", ""),
    iff(OperationNameValue =~ "CreateFunction", "Serverless function in unapproved region", "")
  )
| extend RiskIndicators = array_strcat(array_slice(RiskIndicators, 0, array_length(RiskIndicators)), ", ")
| sort by TimeGenerated desc

Detects successful cloud resource creation events in geographic regions not included in the organization's approved/monitored region list. Covers Azure (via AzureActivity) and AWS (via AWSCloudTrail) for compute, storage, networking, database, IAM, and serverless resource provisioning. The approved region dynamic lists MUST be customized to match your actual cloud footprint before deployment. Special attention is given to IAM and compute resources, which are most commonly abused for cryptomining and C2 staging in dormant regions.

high severity medium confidence

Data Sources

Cloud: Cloud Infrastructure Modification Cloud: Cloud Service Azure Activity Logs AWS CloudTrail

Required Tables

AzureActivity AWSCloudTrail

False Positives

  • Legitimate cloud expansion projects deploying to new regions for disaster recovery, latency optimization, or data residency compliance requirements where the approved region list has not been updated
  • Development and QA teams spinning up temporary infrastructure in non-production regions for performance benchmarking, compliance testing, or proof-of-concept work
  • Infrastructure-as-code automation pipelines (Terraform, CDK, ARM templates) deploying resources to new regions as part of an approved rollout where the change management process did not include updating detection allowlists
  • Third-party managed service providers, SaaS vendors, or cloud integrators creating resources on behalf of the organization in their operationally preferred regions
  • Disaster recovery failover events where standby infrastructure is legitimately activated in secondary regions

Sigma rule & cross-platform mapping

The detection logic for Unused/Unsupported Cloud Regions (T1535) above is provided in a vendor-neutral form so you can deploy it on any SIEM. The same logic is shipped here as native KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the following logsource:

logsource:
  product: azure

Browse the community-maintained Sigma rules for this technique:


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 1AWS EC2 Instance Launch in Unused Region

    Expected signal: AWS CloudTrail EventName=RunInstances in region ap-southeast-1. UserIdentityArn shows the calling principal. RequestParameters will include imageId, instanceType, and maxCount. This event appears in both regional CloudTrail (if enabled in ap-southeast-1) and the global management events endpoint in us-east-1.

  2. Test 2AWS S3 Bucket Creation in Unused Region

    Expected signal: AWS CloudTrail EventName=CreateBucket in region sa-east-1. The requestParameters field includes the bucket name and LocationConstraint. This event is captured in CloudTrail management events regardless of whether regional CloudTrail is enabled in sa-east-1.

  3. Test 3AWS IAM Access Key Creation via Unused Region API Endpoint

    Expected signal: AWS CloudTrail EventName=CreateUser and EventName=CreateAccessKey. UserIdentityArn shows the calling principal. Even though IAM is global, these events should be correlated with the unusual region activity detected in other tests — a pattern of unusual region compute creation followed by IAM key creation is a high-confidence compromise indicator.

  4. Test 4Azure Resource Group Creation in Unused Region

    Expected signal: Azure Activity Log OperationNameValue=Microsoft.Resources/resourceGroups/write with ActivityStatusValue=Succeeded. The Caller field shows the authenticated principal's UPN or service principal ID. CallerIpAddress records the source IP. Properties contains the location field 'japaneast' which the KQL extraction regex will parse.


Response Playbook

Triage

  1. Identify exactly what resource was created: note the resource type (EC2, S3, Lambda, IAM user/key), the specific unapproved region, and the timestamp. Check if the region has any existing organizational infrastructure using AWS Organizations SCPs or Azure Policy assignments.
  2. Determine the identity that made the API call: Is it a human IAM user, an assumed role, a service account, or a root account? Root account usage in any unusual region is critical priority.
  3. Assess whether the region has monitoring coverage: Check if AWS GuardDuty, CloudTrail, and Security Hub are enabled in the target region. In Azure, verify whether Defender for Cloud is enabled for that subscription in that region. Absence of monitoring tools in the region is a strong adversary indicator.
  4. Review the caller's recent activity: Pull CloudTrail or AzureActivity events for the same identity over the past 7 days. Look for other unusual regions, IAM changes (new keys, role modifications), data access patterns, or privilege escalation events in the 24 hours prior.
  5. Check the source IP address of the API call: Is it a known corporate IP, a cloud service endpoint, or an unexpected residential/VPN/TOR exit node? Threat intelligence enrichment on the source IP is high value here.
  6. Determine if this is a first-ever use of the region: Query CloudTrail for all historical activity in the target region from your account. Zero prior history combined with resource creation is a strong indicator of adversary activity.

Containment

  1. Immediately terminate or stop all resources created in the unapproved region: `aws ec2 terminate-instances --instance-ids <id> --region <region>` or equivalent. Do not delete until forensic snapshots are taken.
  2. If the calling identity is an IAM access key: deactivate it immediately via `aws iam update-access-key --access-key-id <id> --status Inactive --user-name <user>`. For Azure service principals, remove the credential from the app registration.
  3. If the calling identity is a human user account: force a password reset, revoke all active sessions (`aws iam delete-login-profile` + invalidate STS tokens), and require MFA re-enrollment.
  4. Enable GuardDuty, CloudTrail (with data events), and Security Hub in the affected region immediately if not already enabled — the adversary may have chosen it specifically for lack of monitoring coverage.
  5. Apply an SCP (AWS Organizations) or Azure Policy to deny resource creation in the unapproved region across all accounts while the incident is being investigated.
  6. Review and rotate any secrets or credentials that may have been exposed to the compromised identity or to resources created in the unapproved region.

Evidence Collection

  1. AWS CloudTrail: Pull all API events in the target region for the 24 hours before and after the detection: `aws cloudtrail lookup-events --region <region> --start-time <time> --end-time <time>`. If CloudTrail was not enabled in the region, check management events in us-east-1 (global services endpoint).
  2. CloudTrail Management Events: Even without regional CloudTrail, management-plane events (IAM, STS, Organizations) are logged to the global endpoint. Check for `AssumeRole` calls, `CreateAccessKey`, and `GetSessionToken` events preceding the unapproved region activity.
  3. VPC Flow Logs and Security Group Rules: If an EC2 instance was created, capture VPC flow logs before termination to identify C2 communication patterns, mining pool connections (port 3333, 4444, 5555, 14444), or data exfiltration destinations.
  4. EC2/Compute Metadata: Before terminating instances, capture AMI ID (is it a custom or public image?), IAM instance profile, user data script (often contains malicious payload), and running processes via AWS Systems Manager Session Manager if accessible.
  5. Billing and Cost Anomalies: Check AWS Cost Explorer or Azure Cost Management for unexpected charges in the target region. Cryptocurrency mining typically shows sustained high CPU utilization charges for compute instances.
  6. IAM Credential Report and Access Advisor: Run `aws iam generate-credential-report` to identify when the compromised credential was last used, from where, and for which services. `aws iam get-access-key-last-used` shows the last use timestamp and region.
  7. CloudWatch Metrics: Pull CPU, network I/O, and memory metrics for any running instances in the region before termination. Sustained high CPU (>80%) is characteristic of cryptomining workloads.

Escalation Criteria

  • ! Root account credentials used to create resources in the unapproved region — this indicates full account compromise and requires immediate escalation to cloud security leadership.
  • ! The target region has no monitoring tooling enabled (no GuardDuty, no CloudTrail data events) — the adversary likely chose this region deliberately to evade detection, indicating a sophisticated, targeted attack.
  • ! IAM users, access keys, or roles created in the unapproved region — persistence mechanisms have been established and the adversary may have multiple footholds even after the initial resource is terminated.
  • ! Evidence of cryptocurrency mining (pool connections to known mining pools, sustained high compute CPU utilization) — this indicates active resource abuse and ongoing financial impact.
  • ! The compromised identity belongs to a privileged account (cloud administrator, billing account, security auditor role) with broad organizational permissions.
  • ! Multiple accounts in the organization show activity in the same unapproved region within a short window — this suggests automated lateral movement across accounts using stolen credentials or cross-account role abuse.

Investigation Guide

Forensic Artifacts

  • > AWS CloudTrail Management Events: All CreateBucket, RunInstances, CreateFunction, CreateUser, CreateAccessKey calls regardless of regional CloudTrail status — management events are always logged to us-east-1 endpoint
  • > AWS Cost and Usage Reports: Unexpected line items in billing for regions outside normal footprint, especially EC2 compute charges indicating long-running instances
  • > VPC Flow Logs: Outbound connections from EC2 instances to known cryptocurrency mining pools (pool.minexmr.com, xmrpool.eu, c3pool.com) or command-and-control infrastructure
  • > EC2 User Data Scripts: Retrieved via `aws ec2 describe-instance-attribute --attribute userData --instance-id <id> --region <region>` — frequently contains malicious payload or miner configuration
  • > AWS Config: Resource configuration history in affected region, if Config was enabled. Shows what resources were created and their configurations even after termination
  • > IAM Access Advisor: `aws iam get-service-last-accessed-details` shows which services the compromised role accessed and in which regions, revealing full scope of activity
  • > Azure Activity Log: Resource provider operations in the unapproved region, retained for 90 days in the Azure portal and indefinitely if exported to Log Analytics
  • > Instance Profile and Role Assumption Chains: STS AssumeRole events in CloudTrail showing how the adversary escalated from initial access credentials to the role used for resource creation

Tuning Guidance

The primary tuning requirement for this detection is maintaining an accurate approved regions list. Review your organization's AWS Organizations SCPs (Service Control Policies) or Azure Policy assignments that restrict regions — these lists are the authoritative source for what regions should be allowed and monitored. Update the detection's region lists quarterly or whenever a cloud expansion project is approved. For AWS environments, consider using the AWS Config managed rule 'restricted-region-operations' as a complementary control and pulling its findings into the SIEM. To reduce noise from legitimate automation, build an allowlist of known service account ARNs or Azure service principal object IDs used by Infrastructure-as-Code tools (Terraform state backends, CDK deployment roles) and exclude them from the core alert while keeping them in the hunting queries. Consider creating a separate, lower-severity alert tier for storage-only resources (S3 buckets, Azure Blob storage) versus compute instances and IAM resources, which should always be high severity regardless of region context. Organizations using AWS Control Tower can query the Account Factory audit trail for approved region enrollment, providing a dynamic source of truth that avoids manual list maintenance.


Hunting Queries

Hunt for identities that have recently started using cloud regions they have never used in the prior 90-day baseline period. A previously dormant identity suddenly accessing a new region, especially with resource creation events, is a strong indicator of credential theft and adversary use of less-monitored infrastructure.

Hunting — KQL
kql
// Hunt: Accounts that have never previously used a region now showing activity
let LookbackWindow = 90d;
let RecentWindow = 7d;
let HistoricalRegions =
AWSCloudTrail
| where TimeGenerated between (ago(LookbackWindow) .. ago(RecentWindow))
| summarize HistoricalRegions = make_set(AWSRegion) by UserIdentityArn;
let RecentActivity =
AWSCloudTrail
| where TimeGenerated > ago(RecentWindow)
| where isempty(ErrorCode)
| summarize RecentRegions = make_set(AWSRegion), EventCount = count() by UserIdentityArn;
RecentActivity
| join kind=leftouter HistoricalRegions on UserIdentityArn
| extend NewRegions = set_difference(RecentRegions, coalesce(HistoricalRegions, dynamic([])))
| where array_length(NewRegions) > 0
| project UserIdentityArn, NewRegions, RecentRegions, HistoricalRegions, EventCount
| sort by array_length(NewRegions) desc
Hunting — SPL
spl
index=* (sourcetype="aws:cloudtrail" OR sourcetype="amazon:cloudtrail")
  NOT errorCode=*
| eval Actor=coalesce('userIdentity.arn', 'userIdentity.userName')
| eval WeeksAgo=round((now() - _time) / 604800, 0)
| eval IsRecent=if(WeeksAgo <= 1, 1, 0)
| stats values(awsRegion) as AllRegions, values(eval(if(IsRecent=1, awsRegion, null()))) as RecentRegions, values(eval(if(IsRecent=0, awsRegion, null()))) as HistoricalRegions by Actor
| eval NewRegions=mvfilter(NOT match(RecentRegions, mvjoin(HistoricalRegions, "|")))
| where mvcount(NewRegions) > 0
| table Actor, NewRegions, RecentRegions, HistoricalRegions
| sort - mvcount(NewRegions)

Hunt for AWS regions where resource creation is occurring but no security tooling (GuardDuty, Security Hub, Config) has logged any activity. This identifies regions that adversaries may have specifically chosen for their lack of monitoring coverage, a key indicator distinguishing opportunistic cryptomining from targeted evasion.

Hunting — KQL
kql
// Hunt: Regions with resource creation but NO security tooling activity (GuardDuty, Security Hub, CloudTrail)
AWSCloudTrail
| where TimeGenerated > ago(30d)
| where isempty(ErrorCode)
| where EventName in~ ("RunInstances", "CreateBucket", "CreateFunction", "CreateDBInstance", "CreateVolume")
| summarize ResourceCreationCount = count(), Actors = make_set(UserIdentityArn), Events = make_set(EventName) by AWSRegion
| join kind=leftanti (
    AWSCloudTrail
    | where TimeGenerated > ago(30d)
    | where EventSource in ("guardduty.amazonaws.com", "securityhub.amazonaws.com", "config.amazonaws.com")
    | summarize by AWSRegion
  ) on AWSRegion
| extend DetectionCoverage = "NONE — no GuardDuty, Security Hub, or Config activity in region"
| sort by ResourceCreationCount desc
Hunting — SPL
spl
index=* (sourcetype="aws:cloudtrail" OR sourcetype="amazon:cloudtrail")
  NOT errorCode=*
| eval ResourceCreation=if(eventName IN ("RunInstances","CreateBucket","CreateFunction","CreateDBInstance","CreateVolume"), 1, 0)
| eval SecurityService=if(match(eventSource, "(guardduty|securityhub|config)\.amazonaws\.com"), 1, 0)
| stats sum(ResourceCreation) as ResourceCreations, sum(SecurityService) as SecurityServiceActivity by awsRegion
| where ResourceCreations > 0 AND SecurityServiceActivity=0
| eval CoverageGap="No GuardDuty, Security Hub, or Config events in this region"
| table awsRegion, ResourceCreations, SecurityServiceActivity, CoverageGap
| sort - ResourceCreations

Hunt for high-volume EC2 instance creation bursts spanning multiple regions in a short time window. Cryptomining adversaries often attempt to maximize compute capacity by launching many instances across multiple undermonitored regions simultaneously. More than 5 instances or activity in 2+ regions within an hour from the same identity warrants investigation.

Hunting — KQL
kql
// Hunt: Unusual compute creation bursts in non-standard regions suggesting cryptomining scale-up
AWSCloudTrail
| where TimeGenerated > ago(7d)
| where EventName =~ "RunInstances"
| where isempty(ErrorCode)
| extend InstanceCount = toint(tostring(parse_json(RequestParameters).maxCount))
| summarize
    TotalInstances = sum(InstanceCount),
    Regions = make_set(AWSRegion),
    TimeRange = strcat(format_datetime(min(TimeGenerated), 'yyyy-MM-dd HH:mm'), " to ", format_datetime(max(TimeGenerated), 'yyyy-MM-dd HH:mm')),
    UniqueRegions = dcount(AWSRegion)
  by UserIdentityArn, bin(TimeGenerated, 1h)
| where TotalInstances > 5 or UniqueRegions > 2
| sort by TotalInstances desc
Hunting — SPL
spl
index=* (sourcetype="aws:cloudtrail" OR sourcetype="amazon:cloudtrail")
  eventName="RunInstances" NOT errorCode=*
| eval Actor=coalesce('userIdentity.arn', 'userIdentity.userName')
| eval InstanceCount=coalesce('requestParameters.maxCount', 1)
| bin _time span=1h
| stats sum(InstanceCount) as TotalInstances, dc(awsRegion) as UniqueRegions, values(awsRegion) as Regions by _time, Actor
| where TotalInstances > 5 OR UniqueRegions > 2
| sort - TotalInstances

Atomic Red Team Tests

Test 1 AWS EC2 Instance Launch in Unused Region
linux

Launches a minimal EC2 t3.micro instance in the ap-southeast-1 (Singapore) region, simulating an adversary spinning up cryptomining compute in an unmonitored region. Uses the Amazon Linux 2 AMI. Requires AWS CLI with credentials that have ec2:RunInstances permission. Replace the AMI ID with a current ap-southeast-1 Amazon Linux 2 AMI before running.

Command

bash
aws ec2 run-instances --region ap-southeast-1 --image-id ami-0df7a207adb9748c7 --instance-type t3.micro --count 1 --no-associate-public-ip-address --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=df00tech-test}]' --query 'Instances[0].InstanceId' --output text

Cleanup

bash
INSTANCE_ID=$(aws ec2 describe-instances --region ap-southeast-1 --filters 'Name=tag:Name,Values=df00tech-test' --query 'Reservations[0].Instances[0].InstanceId' --output text) && aws ec2 terminate-instances --region ap-southeast-1 --instance-ids $INSTANCE_ID

Expected Telemetry

AWS CloudTrail EventName=RunInstances in region ap-southeast-1. UserIdentityArn shows the calling principal. RequestParameters will include imageId, instanceType, and maxCount. This event appears in both regional CloudTrail (if enabled in ap-southeast-1) and the global management events endpoint in us-east-1.

Expected Detection

KQL: AWSCloudTrail where EventName == 'RunInstances' and AWSRegion not in ApprovedRegions fires and joins into the union output. SPL: EventName=RunInstances, awsRegion=ap-southeast-1 matches where isApprovedRegion=0, RiskScore includes +2 for compute creation.

Test 2 AWS S3 Bucket Creation in Unused Region
linux

Creates an S3 bucket in the sa-east-1 (São Paulo) region, simulating adversary staging of an exfiltration destination or C2 payload hosting bucket in an unmonitored region. Bucket names must be globally unique — the command appends a timestamp to ensure uniqueness.

Command

bash
BUCKET_NAME="df00tech-test-$(date +%s)" && aws s3api create-bucket --bucket $BUCKET_NAME --region sa-east-1 --create-bucket-configuration LocationConstraint=sa-east-1 && echo "Created bucket: $BUCKET_NAME"

Cleanup

bash
BUCKET_NAME=$(aws s3api list-buckets --query 'Buckets[?starts_with(Name, `df00tech-test-`)].Name' --output text) && aws s3api delete-bucket --bucket $BUCKET_NAME --region sa-east-1

Expected Telemetry

AWS CloudTrail EventName=CreateBucket in region sa-east-1. The requestParameters field includes the bucket name and LocationConstraint. This event is captured in CloudTrail management events regardless of whether regional CloudTrail is enabled in sa-east-1.

Expected Detection

KQL: AWSCloudTrail where EventName == 'CreateBucket' and AWSRegion not in ApprovedRegions. SPL: eventName=CreateBucket, awsRegion=sa-east-1, isApprovedRegion=0. Lower RiskScore than IAM or compute but still triggers the detection.

Test 3 AWS IAM Access Key Creation via Unused Region API Endpoint
linux

Creates a new IAM access key for the current user by making the API call through the global IAM endpoint. Simulates an adversary who has compromised credentials and creates new access keys to establish persistence — a common step after initial access via unused region activity. IAM is a global service so the region is always us-east-1, but this test validates detection of IAM manipulation by a potentially compromised identity.

Command

bash
TEST_USER="df00tech-test-user-$(date +%s)" && aws iam create-user --user-name $TEST_USER && aws iam create-access-key --user-name $TEST_USER --query 'AccessKey.AccessKeyId' --output text && echo "Test user and access key created: $TEST_USER"

Cleanup

bash
TEST_USER=$(aws iam list-users --query 'Users[?starts_with(UserName, `df00tech-test-user-`)].UserName' --output text) && ACCESS_KEY=$(aws iam list-access-keys --user-name $TEST_USER --query 'AccessKeyMetadata[0].AccessKeyId' --output text) && aws iam delete-access-key --user-name $TEST_USER --access-key-id $ACCESS_KEY && aws iam delete-user --user-name $TEST_USER

Expected Telemetry

AWS CloudTrail EventName=CreateUser and EventName=CreateAccessKey. UserIdentityArn shows the calling principal. Even though IAM is global, these events should be correlated with the unusual region activity detected in other tests — a pattern of unusual region compute creation followed by IAM key creation is a high-confidence compromise indicator.

Expected Detection

KQL: AWSCloudTrail where EventName in ('CreateUser', 'CreateAccessKey'). In the detection context, these IAM events correlated with preceding unusual-region compute events elevate the overall incident severity. SPL: RiskScore += 3 for IAM resource creation events.

Test 4 Azure Resource Group Creation in Unused Region
linux

Creates an Azure Resource Group in the japaneast region, simulating an adversary establishing a container for subsequent resource deployment in an unmonitored Azure region. Requires Azure CLI authenticated with credentials having Contributor or Owner role at the subscription level.

Command

bash
az group create --name df00tech-test-rg --location japaneast --tags purpose=security-test created-by=df00tech

Cleanup

bash
az group delete --name df00tech-test-rg --yes --no-wait

Expected Telemetry

Azure Activity Log OperationNameValue=Microsoft.Resources/resourceGroups/write with ActivityStatusValue=Succeeded. The Caller field shows the authenticated principal's UPN or service principal ID. CallerIpAddress records the source IP. Properties contains the location field 'japaneast' which the KQL extraction regex will parse.

Expected Detection

KQL: AzureActivity where OperationNameValue has 'resourceGroups/write' and ResourceLocation (extracted from Properties) not in ApprovedAzureRegions. The japaneast location is parsed from the Properties JSON and compared against the approved list, triggering the AzureUnusualRegion branch of the union query.

Related Detections