Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Suspicious command sent to EC2

Back
Id21702832-aff3-4bd6-a8e1-663b6818503d
RulenameSuspicious command sent to EC2
DescriptionAn attacker with the necessary permissions could be executing code remotely on a machine and saving the output to his own S3 bucket. Verify this action with the user identity.
SeverityHigh
TacticsExecution
TechniquesT1204
Required data connectorsAWS
KindScheduled
Query frequency1d
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_SuspiciousCommandEC2.yaml
Version1.0.1
Arm template21702832-aff3-4bd6-a8e1-663b6818503d.json
Deploy To Azure
let command_executed = AWSCloudTrail
| where EventName in ("SendCommand","CreateAssociation") and isempty(ErrorCode) and isempty(ErrorMessage)
| extend params = tostring(parse_json(RequestParameters).parameters)
| extend s3bucketCommand = tostring(parse_json(RequestParameters).outputS3BucketName)
| extend s3bucketAssociation = tostring(parse_json(RequestParameters).outputLocation.s3Location.outputS3BucketName)
| where isnotempty(params)
| extend commandId = tostring(parse_json(ResponseElements).command.commandId)
| extend associationId = tostring(parse_json(ResponseElements).associationDescription.associationId)
| extend executionId = iff(isnotempty(commandId), commandId, associationId)
| extend s3bucket = iff(isnotempty(s3bucketCommand), s3bucketCommand, s3bucketAssociation)
| extend UserIdentityUserName = iff(isnotempty(UserIdentityUserName), UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1]))
| extend timestamp = TimeGenerated;
AWSCloudTrail
| where EventName == "PutObject" and isempty(ErrorCode) and isempty(ErrorMessage)
| extend s3bucket = tostring(parse_json(RequestParameters).bucketName)
| mv-expand todynamic(Resources)
| extend accountId=tostring(todynamic(Resources.['accountId']))
| where Resources contains "accountId" and accountId <> RecipientAccountId
| join command_executed on s3bucket
| 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]), "")
status: Available
id: 21702832-aff3-4bd6-a8e1-663b6818503d
name: Suspicious command sent to EC2
requiredDataConnectors:
- connectorId: AWS
  dataTypes:
  - AWSCloudTrail
severity: High
triggerThreshold: 0
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_SuspiciousCommandEC2.yaml
kind: Scheduled
description: |
    'An attacker with the necessary permissions could be executing code remotely on a machine and saving the output to his own S3 bucket. Verify this action with the user identity.'
relevantTechniques:
- T1204
queryPeriod: 1d
triggerOperator: gt
queryFrequency: 1d
query: |
  let command_executed = AWSCloudTrail
  | where EventName in ("SendCommand","CreateAssociation") and isempty(ErrorCode) and isempty(ErrorMessage)
  | extend params = tostring(parse_json(RequestParameters).parameters)
  | extend s3bucketCommand = tostring(parse_json(RequestParameters).outputS3BucketName)
  | extend s3bucketAssociation = tostring(parse_json(RequestParameters).outputLocation.s3Location.outputS3BucketName)
  | where isnotempty(params)
  | extend commandId = tostring(parse_json(ResponseElements).command.commandId)
  | extend associationId = tostring(parse_json(ResponseElements).associationDescription.associationId)
  | extend executionId = iff(isnotempty(commandId), commandId, associationId)
  | extend s3bucket = iff(isnotempty(s3bucketCommand), s3bucketCommand, s3bucketAssociation)
  | extend UserIdentityUserName = iff(isnotempty(UserIdentityUserName), UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1]))
  | extend timestamp = TimeGenerated;
  AWSCloudTrail
  | where EventName == "PutObject" and isempty(ErrorCode) and isempty(ErrorMessage)
  | extend s3bucket = tostring(parse_json(RequestParameters).bucketName)
  | mv-expand todynamic(Resources)
  | extend accountId=tostring(todynamic(Resources.['accountId']))
  | where Resources contains "accountId" and accountId <> RecipientAccountId
  | join command_executed on s3bucket
  | 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]), "")  
version: 1.0.1
tactics:
- Execution
entityMappings:
- fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: AccountUPNSuffix
  - identifier: CloudAppAccountId
    columnName: RecipientAccountId
  entityType: Account
- fieldMappings:
  - identifier: Address
    columnName: SourceIpAddress
  entityType: IP
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2023-02-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/21702832-aff3-4bd6-a8e1-663b6818503d')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/21702832-aff3-4bd6-a8e1-663b6818503d')]",
      "properties": {
        "alertRuleTemplateName": "21702832-aff3-4bd6-a8e1-663b6818503d",
        "customDetails": null,
        "description": "'An attacker with the necessary permissions could be executing code remotely on a machine and saving the output to his own S3 bucket. Verify this action with the user identity.'\n",
        "displayName": "Suspicious command sent to EC2",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "AccountUPNSuffix",
                "identifier": "UPNSuffix"
              },
              {
                "columnName": "RecipientAccountId",
                "identifier": "CloudAppAccountId"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "SourceIpAddress",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_SuspiciousCommandEC2.yaml",
        "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]))\n| extend timestamp = TimeGenerated;\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]), \"\")\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "severity": "High",
        "status": "Available",
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Execution"
        ],
        "techniques": [
          "T1204"
        ],
        "templateVersion": "1.0.1",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}