Back
Id8c2dc344-9352-4ca1-8863-b1b7a5e09e59
RulenameAWSCloudTrail - Suspicious AWS CLI Command Execution
DescriptionThis detection focuses on identifying potentially suspicious activities involving the execution of AWS Command Line Interface (CLI) commands, particularly focusing on reconnaissance operations.
SeverityMedium
TacticsReconnaissance
TechniquesT1595
T1592.004
T1589.002
T1589.003
T1590
T1591
T1596
Required data connectorsAWS
KindScheduled
Query frequency1d
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon%20Web%20Services/Analytic%20Rules/SuspiciousAWSCLICommandExecution.yaml
Version1.0.2
Arm template8c2dc344-9352-4ca1-8863-b1b7a5e09e59.json
Deploy To Azure
let SuspiciousCommands= pack_array('iam.list-users', 'iam.list-groups', 'ec2.describe-vpcs', 'ec2.describe-subnets', 'route53.list-hosted-zones', 'kms.list-keys', 'kms.list-aliases', 'ecs.list-clusters', 'ecs.list-services', 'iam.list-roles', 'iam.get-user''iam.list-access-keys', 'ec2.describe-security-groups', 'ec2.describe-network-acls', 'ec2.describe-network-interfaces', 'ec2.describe-route-tables', 'ec2.describe-internet-gateways', 'ec2.describe-vpc-peering-connections', 'ec2.describe-network-interfaces', 'ec2.describe-network-interfaces', 'ec2.describe-transit-gateway-vpc-attachment', 'ec2.describe-vpc');
// Retrieve AWS CloudTrail events
AWSCloudTrail 
// Filter events with UserAgent starting with "aws-cli"
| where UserAgent startswith "aws-cli" 
// Extract the command from the UserAgent using string splitting
| extend command = tostring(split(UserAgent, "off command/", 1)[0])  
// Filter events based on predefined suspicious command list
| where command has_any (SuspiciousCommands)  
| extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)
| extend UserName = tostring(split(UserIdentityArn, '/')[-1])
| extend AccountName = case( UserIdentityPrincipalid == "Anonymous", "Anonymous", isempty(UserIdentityUserName), UserName, UserIdentityUserName)
| extend AccountName = iif(AccountName contains "@", tostring(split(AccountName, '@', 0)[0]), AccountName),
  AccountUPNSuffix = iif(AccountName contains "@", tostring(split(AccountName, '@', 1)[0]), "")
// Summarize relevant information for further analysis
| summarize 
    CommadCount = dcount(command), 
    EventCount = dcount(EventName), 
    commands = make_list(command), 
    Events = make_list(EventName) 
    by 
    bin(TimeGenerated, 1min), 
    RecipientAccountId, AccountName, AccountUPNSuffix, 
    UserIdentityUserName, 
    SourceIpAddress, 
    SessionMfaAuthenticated 
// Filter out results with a sufficient count of unique suspicious commands in 1 min time window
| where CommadCount >= 8
name: AWSCloudTrail - Suspicious AWS CLI Command Execution
tactics:
- Reconnaissance
alertDetailsOverride:
  alertDisplayNameFormat: Suspicious AWS CLI reconnaissance by {{AccountName}} - {{CommadCount}} commands
  alertDescriptionFormat: User {{AccountName}} executed {{CommadCount}} suspicious AWS CLI reconnaissance commands from {{SourceIpAddress}} within 1 minute window.
queryFrequency: 1d
triggerThreshold: 0
customDetails:
  AWSUserIp: SourceIpAddress
  AWSUser: UserIdentityUserName
  SuspiciousCommand: commands
relevantTechniques:
- T1595
- T1592.004
- T1589.002
- T1589.003
- T1590
- T1591
- T1596
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon%20Web%20Services/Analytic%20Rules/SuspiciousAWSCLICommandExecution.yaml
kind: Scheduled
description: |
  'This detection focuses on identifying potentially suspicious activities involving the execution of AWS Command Line Interface (CLI) commands, particularly focusing on reconnaissance operations.'
requiredDataConnectors:
- connectorId: AWS
  dataTypes:
  - AWSCloudTrail
entityMappings:
- fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: AccountUPNSuffix
  - identifier: CloudAppAccountId
    columnName: RecipientAccountId
  entityType: Account
severity: Medium
queryPeriod: 1d
query: |
  let SuspiciousCommands= pack_array('iam.list-users', 'iam.list-groups', 'ec2.describe-vpcs', 'ec2.describe-subnets', 'route53.list-hosted-zones', 'kms.list-keys', 'kms.list-aliases', 'ecs.list-clusters', 'ecs.list-services', 'iam.list-roles', 'iam.get-user''iam.list-access-keys', 'ec2.describe-security-groups', 'ec2.describe-network-acls', 'ec2.describe-network-interfaces', 'ec2.describe-route-tables', 'ec2.describe-internet-gateways', 'ec2.describe-vpc-peering-connections', 'ec2.describe-network-interfaces', 'ec2.describe-network-interfaces', 'ec2.describe-transit-gateway-vpc-attachment', 'ec2.describe-vpc');
  // Retrieve AWS CloudTrail events
  AWSCloudTrail 
  // Filter events with UserAgent starting with "aws-cli"
  | where UserAgent startswith "aws-cli" 
  // Extract the command from the UserAgent using string splitting
  | extend command = tostring(split(UserAgent, "off command/", 1)[0])  
  // Filter events based on predefined suspicious command list
  | where command has_any (SuspiciousCommands)  
  | extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)
  | extend UserName = tostring(split(UserIdentityArn, '/')[-1])
  | extend AccountName = case( UserIdentityPrincipalid == "Anonymous", "Anonymous", isempty(UserIdentityUserName), UserName, UserIdentityUserName)
  | extend AccountName = iif(AccountName contains "@", tostring(split(AccountName, '@', 0)[0]), AccountName),
    AccountUPNSuffix = iif(AccountName contains "@", tostring(split(AccountName, '@', 1)[0]), "")
  // Summarize relevant information for further analysis
  | summarize 
      CommadCount = dcount(command), 
      EventCount = dcount(EventName), 
      commands = make_list(command), 
      Events = make_list(EventName) 
      by 
      bin(TimeGenerated, 1min), 
      RecipientAccountId, AccountName, AccountUPNSuffix, 
      UserIdentityUserName, 
      SourceIpAddress, 
      SessionMfaAuthenticated 
  // Filter out results with a sufficient count of unique suspicious commands in 1 min time window
  | where CommadCount >= 8
triggerOperator: gt
version: 1.0.2
id: 8c2dc344-9352-4ca1-8863-b1b7a5e09e59
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/8c2dc344-9352-4ca1-8863-b1b7a5e09e59')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/8c2dc344-9352-4ca1-8863-b1b7a5e09e59')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "User {{AccountName}} executed {{CommadCount}} suspicious AWS CLI reconnaissance commands from {{SourceIpAddress}} within 1 minute window.",
          "alertDisplayNameFormat": "Suspicious AWS CLI reconnaissance by {{AccountName}} - {{CommadCount}} commands"
        },
        "alertRuleTemplateName": "8c2dc344-9352-4ca1-8863-b1b7a5e09e59",
        "customDetails": {
          "AWSUser": "UserIdentityUserName",
          "AWSUserIp": "SourceIpAddress",
          "SuspiciousCommand": "commands"
        },
        "description": "'This detection focuses on identifying potentially suspicious activities involving the execution of AWS Command Line Interface (CLI) commands, particularly focusing on reconnaissance operations.'\n",
        "displayName": "AWSCloudTrail - Suspicious AWS CLI Command Execution",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "AccountUPNSuffix",
                "identifier": "UPNSuffix"
              },
              {
                "columnName": "RecipientAccountId",
                "identifier": "CloudAppAccountId"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon%20Web%20Services/Analytic%20Rules/SuspiciousAWSCLICommandExecution.yaml",
        "query": "let SuspiciousCommands= pack_array('iam.list-users', 'iam.list-groups', 'ec2.describe-vpcs', 'ec2.describe-subnets', 'route53.list-hosted-zones', 'kms.list-keys', 'kms.list-aliases', 'ecs.list-clusters', 'ecs.list-services', 'iam.list-roles', 'iam.get-user''iam.list-access-keys', 'ec2.describe-security-groups', 'ec2.describe-network-acls', 'ec2.describe-network-interfaces', 'ec2.describe-route-tables', 'ec2.describe-internet-gateways', 'ec2.describe-vpc-peering-connections', 'ec2.describe-network-interfaces', 'ec2.describe-network-interfaces', 'ec2.describe-transit-gateway-vpc-attachment', 'ec2.describe-vpc');\n// Retrieve AWS CloudTrail events\nAWSCloudTrail \n// Filter events with UserAgent starting with \"aws-cli\"\n| where UserAgent startswith \"aws-cli\" \n// Extract the command from the UserAgent using string splitting\n| extend command = tostring(split(UserAgent, \"off command/\", 1)[0])  \n// Filter events based on predefined suspicious command list\n| where command has_any (SuspiciousCommands)  \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]), \"\")\n// Summarize relevant information for further analysis\n| summarize \n    CommadCount = dcount(command), \n    EventCount = dcount(EventName), \n    commands = make_list(command), \n    Events = make_list(EventName) \n    by \n    bin(TimeGenerated, 1min), \n    RecipientAccountId, AccountName, AccountUPNSuffix, \n    UserIdentityUserName, \n    SourceIpAddress, \n    SessionMfaAuthenticated \n// Filter out results with a sufficient count of unique suspicious commands in 1 min time window\n| where CommadCount >= 8\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "severity": "Medium",
        "subTechniques": [
          "T1592.004",
          "T1589.002",
          "T1589.003"
        ],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Reconnaissance"
        ],
        "techniques": [
          "T1589",
          "T1590",
          "T1591",
          "T1592",
          "T1595",
          "T1596"
        ],
        "templateVersion": "1.0.2",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}