{
  "technique_id": "T1651",
  "name": "Cloud Administration Command",
  "priority": "high",
  "status": "draft",
  "version": "0.1.0",
  "last_reviewed": "2026-07-23",
  "generated_by": "SOC Response Atlas by Basyrix",
  "tactics": [
    "Execution"
  ],
  "platforms": [
    "IaaS"
  ],
  "summary": "Adversaries may abuse cloud management services to execute commands within virtual machines. Resources such as AWS Systems Manager, Azure RunCommand, and Runbooks allow users to remotely run scripts in virtual machines by leveraging installed virtual machine agents. If an adversary gains administrative access to a cloud environment, they may be able to abuse cloud management services to execute commands in the environment’s virtual machines...",
  "soc_recommendation": "Investigate Cloud Administration Command activity in the context of Execution: confirm scope, affected host/identity, and whether it matches expected administrative behaviour before deciding this is benign.",
  "d3fend_mappings": [
    {
      "id": "D3-NTA",
      "name": "Network Traffic Analysis",
      "relationship": "detect",
      "practical_action": "Monitor for Network Traffic Analysis indicators relevant to this technique.",
      "tooling": [
        "Sentinel",
        "Defender for Endpoint"
      ]
    }
  ],
  "investigation_steps": {
    "microsoft": [
      "Review Defender for Endpoint / Defender XDR alerts and timeline for the affected host or identity.",
      "Check Sentinel analytics rules and incidents correlated with this technique.",
      "Review Entra ID sign-in and audit logs if the technique involves an identity or cloud resource."
    ],
    "generic": [
      "Confirm whether the observed cloud administration command activity matches expected administrative or application behaviour.",
      "Identify the host, account, or resource where the activity occurred and its business criticality.",
      "Check for related alerts before and after this activity to reconstruct the broader intrusion timeline.",
      "Real detection reference: \"AWSCloudTrail - Suspicious command sent to EC2\" -- An attacker with the necessary AWS permissions could be executing code remotely on an EC2 instance via SSM and saving the output to their own S3 bucket. Verify this action with the user identity and confirm it was authorized."
    ]
  },
  "evidence_to_collect": [
    "Host or resource affected",
    "Account or identity involved",
    "Timestamp of the activity",
    "Related process, file, or network artifact",
    "Any preceding or follow-on alerts"
  ],
  "response_actions": [
    {
      "name": "Contain the affected host or account",
      "category": "Containment",
      "risk": "Medium",
      "automation_safe": false,
      "approval_required": true,
      "tool": "Defender for Endpoint / Entra ID",
      "notes": "Requires approval -- confirm malicious intent before isolating a host or disabling an account."
    },
    {
      "name": "Collect and preserve evidence",
      "category": "Investigation",
      "risk": "Low",
      "automation_safe": true,
      "approval_required": false,
      "tool": "Defender for Endpoint",
      "notes": "Safe -- read-only evidence collection."
    }
  ],
  "queries": {
    "kql": [
      {
        "name": "21702832-aff3-4bd6-a8e1-663b6818503d — AWSCloudTrail - Suspicious command sent to EC2",
        "description": "An attacker with the necessary AWS permissions could be executing code remotely on an EC2 instance via SSM and saving the output to their own S3 bucket. Verify this action with the user identity and confirm it was authorized. (Source: Microsoft's official Azure-Sentinel Detections (MIT licensed).)",
        "query": "let command_executed = AWSCloudTrail\n| where EventName in (\"SendCommand\",\"CreateAssociation\") and isempty(ErrorCode) and isempty(ErrorMessage)\n| extend params = tostring(parse_json(RequestParameters).parameters)\n| extend s3bucketCommand = tostring(parse_json(RequestParameters).outputS3BucketName)\n| extend s3bucketAssociation = tostring(parse_json(RequestParameters).outputLocation.s3Location.outputS3BucketName)\n| where isnotempty(params)\n| extend commandId = tostring(parse_json(ResponseElements).command.commandId)\n| extend associationId = tostring(parse_json(ResponseElements).associationDescription.associationId)\n| extend executionId = iff(isnotempty(commandId), commandId, associationId)\n| extend s3bucket = iff(isnotempty(s3bucketCommand), s3bucketCommand, s3bucketAssociation)\n| extend UserIdentityUserName = iff(isnotempty(UserIdentityUserName), UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1]));\nAWSCloudTrail\n| where EventName == \"PutObject\" and isempty(ErrorCode) and isempty(ErrorMessage)\n| extend s3bucket = tostring(parse_json(RequestParameters).bucketName)\n| mv-expand todynamic(Resources)\n| extend accountId=tostring(todynamic(Resources.['accountId']))\n| where Resources contains \"accountId\" and accountId <> RecipientAccountId\n| join command_executed on s3bucket\n| extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)\n| extend UserName = tostring(split(UserIdentityArn, '/')[-1])\n| extend AccountName = case( UserIdentityPrincipalid == \"Anonymous\", \"Anonymous\", isempty(UserIdentityUserName), UserName, UserIdentityUserName)\n| extend AccountName = iif(AccountName contains \"@\", tostring(split(AccountName, '@', 0)[0]), AccountName),\n  AccountUPNSuffix = iif(AccountName contains \"@\", tostring(split(AccountName, '@', 1)[0]), \"\")"
      }
    ],
    "spl": [],
    "esql": [
      {
        "name": "a8b3e2f0-8c7d-11ef-b4c6-f661ea17fbcd — AWS EC2 LOLBin Execution via SSM SendCommand",
        "description": "(ESQL) Identifies the execution of Living Off the Land Binaries (LOLBins) or GTFOBins on EC2 instances via AWS Systems Manager (SSM) `SendCommand` API. This detection correlates AWS CloudTrail `SendCommand` events with endpoint process execution by matching SSM command IDs... (Source: Elastic's official detection-rules repository (Elastic License v2).)",
        "query": "FROM logs-aws.cloudtrail*, logs-endpoint.events.process-* METADATA _id, _version, _index\n| WHERE\n  // CloudTrail SSM SendCommand with AWS-RunShellScript\n  (\n    data_stream.dataset == \"aws.cloudtrail\"\n    AND event.action == \"SendCommand\"\n    AND aws.cloudtrail.request_parameters LIKE \"*documentName=AWS-RunShellScript*\"\n  )\n  // Linux endpoint process events, prefiltered to SSM shell runner OR LOLBins/GTFOBins\n  OR\n  (\n    data_stream.dataset == \"endpoint.events.process\"\n    AND host.os.type == \"linux\"\n    AND (\n      // SSM shell (_script.sh) runner\n      process.command_line LIKE \"%/document/orchestration/%/awsrunShellScript/%/_script.sh\"\n      // LOLBins / GTFOBins\n      OR process.name IN (\n        \"base64\",\n        \"curl\",\n        \"wget\",\n        \"openssl\",\n        \"nc\", \"ncat\", \"netcat\",\n        \"socat\",\n        \"python\", \"python3\",\n        \"perl\",\n        \"php\",\n        \"ruby\",\n        \"ssh\",\n        \"scp\",\n        \"sftp\",\n        \"rsync\"\n      )\n    )\n  )\n\n// Endpoint leg: extract SSM command ID from parent command line\n| DISSECT process.parent.command_line\n    \"%{}/document/orchestration/%{Esql.process_parent_command_line_ssm_command_id}/%{}\"\n\n// CloudTrail leg: extract SSM command ID from response_elements\n| DISSECT aws.cloudtrail.response_elements\n    \"%{}commandId=%{Esql.aws_cloudtrail_response_elements_ssm_command_id},%{}\"\n\n// Coalesce SSM command ID from both data sources\n| EVAL Esql.aws_ssm_command_id = COALESCE(\n    Esql.aws_cloudtrail_response_elements_ssm_command_id,\n    Esql.process_parent_command_line_ssm_command_id\n)\n| WHERE Esql.aws_ssm_command_id IS NOT NULL\n\n// Role flags\n| EVAL Esql.is_cloud_event    = data_stream.dataset == \"aws.cloudtrail\"\n| EVAL Esql.is_endpoint_event = data_stream.dataset == \"endpoint.events.process\"\n\n// Identify the SSM shell processes (the _script.sh runners)\n| EVAL Esql.is_ssm_shell_process =\n    Esql.is_endpoint_event\n    AND process.command_line LIKE \"%/document/orchestration/%/awsrunShellScript/%/_script.sh\"\n\n// LOLBins / GTFOBins on Linux\n| EVAL Esql.is_lolbin_process =\n    Esql.is_endpoint_event AND NOT Esql.is_ssm_shell_process\n\n// Aggregate per SSM command ID\n| STATS\n    // Core correlation counts & timing\n    Esql.aws_cloudtrail_event_count                 = SUM(CASE(Esql.is_cloud_event, 1, 0)),\n    Esql.endpoint_events_process_lolbin_count       = SUM(CASE(Esql.is_lolbin_process, 1, 0)),\n    Esql.endpoint_events_process_ssm_shell_count    = SUM(CASE(Esql.is_ssm_shell_process, 1, 0)),\n    Esql.aws_cloudtrail_first_event_ts              = MIN(CASE(Esql.is_cloud_event, @timestamp, null)),\n    Esql.endpoint_events_process_first_lolbin_ts    = MIN(CASE(Esql.is_lolbin_process, @timestamp, null)),\n\n    // AWS / CloudTrail identity & request context\n    Esql_priv.aws_cloudtrail_user_identity_arn_values          =\n      VALUES(CASE(Esql.is_cloud_event, aws.cloudtrail.user_identity.arn, null)),\n    Esql_priv.aws_cloudtrail_user_identity_access_key_id_values =\n      VALUES(CASE(Esql.is_cloud_event, aws.cloudtrail.user_identity.access_key_id, null)),\n    Esql_priv.user_name_values                                 =\n      VALUES(CASE(Esql.is_cloud_event, user.name, null)),\n\n    // AWS environment / request metadata\n    Esql.cloud_region_values     = VALUES(CASE(Esql.is_cloud_event, cloud.region, null)),\n    Esql.source_ip_values        = VALUES(CASE(Esql.is_cloud_event, source.ip, null)),\n    Esql.user_agent_original_values =\n      VALUES(CASE(Esql.is_cloud_event, user_agent.original, null)),\n\n    // Endpoint host & user context\n    Esql.host_name_values        = VALUES(CASE(Esql.is_endpoint_event, host.name, null)),\n    Esql_priv.endpoint_user_name_values =\n      VALUES(CASE(Esql.is_endpoint_event, user.name, null)),\n\n    // SSM shell processes on endpoint\n    Esql.process_command_line_ssm_shell_values =\n      VALUES(CASE(Esql.is_ssm_shell_process, process.command_line, null)),\n    Esql.process_pid_ssm_shell_values =\n      VALUES(CASE(Esql.is_ssm_shell_process, process.pid, null)),\n\n    // LOLBin processes on endpoint\n    Esql.process_name_lolbin_values =\n      VALUES(CASE(Esql.is_lolbin_process, process.name, null)),\n    Esql.process_executable_lolbin_values =\n      VALUES(CASE(Esql.is_lolbin_process, process.executable, null)),\n    Esql.process_command_line_lolbin_values =\n      VALUES(CASE(Esql.is_lolbin_process, process.command_line, null)),\n    Esql.process_pid_lolbin_values =\n      VALUES(CASE(Esql.is_lolbin_process, process.pid, null)),\n    Esql.process_parent_command_line_lolbin_values =\n      VALUES(CASE(Esql.is_lolbin_process, process.parent.command_line, null)),\n\n    Esql.data_stream_namespace_values = VALUES(data_stream.namespace)\n  BY Esql.aws_ssm_command_id\n\n// Detection condition: SSM SendCommand + AWS-RunShellScript + LOLBin on endpoint\n| WHERE Esql.aws_cloudtrail_event_count > 0\n  AND Esql.endpoint_events_process_lolbin_count > 0\n  AND DATE_DIFF(\n        \"minutes\",\n        Esql.endpoint_events_process_first_lolbin_ts,\n        Esql.aws_cloudtrail_first_event_ts\n      ) <= 5\n| SORT Esql.aws_cloudtrail_first_event_ts ASC\n| KEEP Esql.*, Esql_priv.*"
      },
      {
        "name": "ebbc1959-3309-4abf-b6cb-2bee3dbc9a7b — Azure Run Command Correlated with Process Execution",
        "description": "(ESQL) Correlates successful Azure Virtual Machine Run Command operations with endpoint process execution on the same host within minutes. Adversaries abuse Run Command to run scripts remotely as SYSTEM or root while activity logs only record the control-plane action; Elastic Defend process telemetry reveals the on-guest payload. (Source: Elastic's official detection-rules repository (Elastic License v2).)",
        "query": "FROM logs-azure.activitylogs-*, logs-endpoint.events.process-* METADATA _id, _version, _index\n| WHERE \n  (\n    event.category == \"process\" AND KQL(\"event.action:start\")\n    AND process.parent.name == \"powershell.exe\"\n    AND process.parent.command_line LIKE \"powershell  -ExecutionPolicy Unrestricted -File script?.ps1\"\n    AND process.name != \"conhost.exe\"\n  ) OR\n  (\n    KQL(\"event.category:process and event.action:exec and process.parent.name:(dash or bash or sh) and process.parent.args:/var/lib/waagent/run-command/download/*/script.sh\")\n   ) OR \n  (\n    event.module == \"azure\"\n    AND event.action == \"MICROSOFT.COMPUTE/VIRTUALMACHINES/RUNCOMMAND/ACTION\"\n    AND NOT KQL(\"event.outcome:failure\")\n   )\n\n// Azure hostname comes as upper-case while Endpoint event comes as lowercase\n| EVAL Esql.host_name = COALESCE(\n    TO_LOWER(host.name),\n    TO_LOWER(azure.resource.name)\n  )\n| EVAL ts_runcommand = CASE(event.module == \"azure\", @timestamp, null)\n| EVAL ts_endpoint = CASE(event.category == \"process\", @timestamp, null)\n| EVAL is_runcommand = CASE(event.module == \"azure\", 1, null)\n| EVAL is_endpoint = CASE(event.category == \"process\", 1, null)\n| EVAL Esql.time_bucket = DATE_TRUNC(2 minutes, @timestamp)\n| STATS\n    runcommand_count = COUNT(is_runcommand),\n    endpoint_count = COUNT(is_endpoint),\n    user.email = VALUES(user.email),\n    azure.activitylogs.identity.authorization.evidence.principal_id = VALUES(azure.activitylogs.identity.authorization.evidence.principal_id),\n    azure.activitylogs.tenant_id = VALUES(azure.activitylogs.tenant_id),\n    azure.subscription_id = VALUES(azure.subscription_id),\n    source.ip = VALUES(source.ip),\n    source.geo.country_name = VALUES(source.geo.country_name),\n    source.as.number = VALUES(source.as.number),\n    Esql.process_command_line_values = VALUES(process.command_line),\n    first_runcommand = MIN(ts_runcommand),\n    first_ps_exec = MIN(ts_endpoint),\n    outcome = VALUES(event.outcome)\n  BY Esql.host_name, Esql.time_bucket\n| WHERE runcommand_count >= 1 AND endpoint_count >= 1\n| EVAL delta_ms = TO_LONG(first_ps_exec) - TO_LONG(first_runcommand)\n| EVAL delta_sec = delta_ms / 1000\n| WHERE delta_sec >= 0 AND delta_sec <= 120\n| KEEP\n    user.email,\n    azure.activitylogs.identity.authorization.evidence.principal_id,\n    source.ip,\n    source.as.number,\n    source.geo.country_name,\n    azure.activitylogs.tenant_id,\n    azure.subscription_id,\n    Esql.*"
      }
    ]
  },
  "automation": {
    "safe": [
      "Add recommendation as Sentinel incident comment.",
      "Run enrichment queries.",
      "Create ServiceNow SecOps task."
    ],
    "approval_required": [
      "Contain or disable the affected host/account.",
      "Any change to production configuration."
    ]
  },
  "escalation_criteria": [
    "Cloud Administration Command activity observed on a privileged account or critical system.",
    "Activity follows or precedes other suspicious behaviour in the same investigation.",
    "Automated triage cannot confidently rule out malicious intent."
  ],
  "false_positive_considerations": [
    "Legitimate administrative or maintenance activity matching this pattern.",
    "Approved security testing or red team exercise.",
    "Known benign software producing similar telemetry."
  ],
  "confluence": {
    "title": "T1651 - Cloud Administration Command Response Guidance",
    "labels": [
      "mitre",
      "attack",
      "d3fend",
      "secops",
      "basyrix"
    ],
    "sections": [
      "summary",
      "d3fend_mappings",
      "investigation_steps",
      "response_actions",
      "queries",
      "automation",
      "escalation_criteria",
      "false_positive_considerations"
    ]
  }
}