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

Successful brute force attack on S3 Bucket.

Back
Id31b9e94b-0df6-4a3d-a297-3457b53c5d86
RulenameSuccessful brute force attack on S3 Bucket.
DescriptionA successful brute force attack on an S3 bucket was detected. Verify these actions, and if needed, remediate the compromise.
SeverityHigh
TacticsDefenseEvasion
TechniquesT1562
Required data connectorsAWS
KindScheduled
Query frequency1h
Query period1h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_S3BruteForce.yaml
Version1.0.0
Arm template31b9e94b-0df6-4a3d-a297-3457b53c5d86.json
Deploy To Azure
let timeframe = 1h;
let failed_attempts = AWSCloudTrail
| where TimeGenerated >= ago(timeframe)
| where EventName == "GetObject" and isnotempty(ErrorMessage) and isnotempty(ErrorCode)
| where UserIdentityAccountId == "ANONYMOUS_PRINCIPAL" or UserIdentityAccessKeyId <> RecipientAccountId
| extend bucketName = tostring(parse_json(RequestParameters).bucketName), keyName = tostring(parse_json(RequestParameters).key)
| summarize time_min_failed=arg_min(TimeGenerated, *), failed_keys = dcount(keyName) by UserIdentityAccountId, SourceIpAddress, bucketName
| where failed_keys > 20;
let success_attempts = AWSCloudTrail
| where TimeGenerated >= ago(timeframe)
| where EventName == "GetObject" and isempty(ErrorMessage) and isempty(ErrorCode)
| where UserIdentityAccountId == "ANONYMOUS_PRINCIPAL" or UserIdentityAccessKeyId <> RecipientAccountId
| extend bucketName = tostring(parse_json(RequestParameters).bucketName), keyName = tostring(parse_json(RequestParameters).key)
| summarize time_min_success=arg_min(TimeGenerated, *), success_keys = dcount(keyName) by UserIdentityAccountId, SourceIpAddress, bucketName
| where success_keys >= 1;
failed_attempts
| join kind=inner success_attempts on SourceIpAddress, UserIdentityAccountId, bucketName
| where time_min_success > time_min_failed
| project-away keyName
| extend UserIdentityUserName = iff(isnotempty(UserIdentityUserName), UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1]))
| extend timestamp = time_min_success, IPCustomEntity = SourceIpAddress, AccountCustomEntity = UserIdentityUserName, AssumedRoleArn = UserIdentityArn
severity: High
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_S3BruteForce.yaml
description: |
    'A successful brute force attack on an S3 bucket was detected. Verify these actions, and if needed, remediate the compromise.'
triggerOperator: gt
queryPeriod: 1h
requiredDataConnectors:
- dataTypes:
  - AWSCloudTrail
  connectorId: AWS
queryFrequency: 1h
triggerThreshold: 0
tactics:
- DefenseEvasion
query: |
  let timeframe = 1h;
  let failed_attempts = AWSCloudTrail
  | where TimeGenerated >= ago(timeframe)
  | where EventName == "GetObject" and isnotempty(ErrorMessage) and isnotempty(ErrorCode)
  | where UserIdentityAccountId == "ANONYMOUS_PRINCIPAL" or UserIdentityAccessKeyId <> RecipientAccountId
  | extend bucketName = tostring(parse_json(RequestParameters).bucketName), keyName = tostring(parse_json(RequestParameters).key)
  | summarize time_min_failed=arg_min(TimeGenerated, *), failed_keys = dcount(keyName) by UserIdentityAccountId, SourceIpAddress, bucketName
  | where failed_keys > 20;
  let success_attempts = AWSCloudTrail
  | where TimeGenerated >= ago(timeframe)
  | where EventName == "GetObject" and isempty(ErrorMessage) and isempty(ErrorCode)
  | where UserIdentityAccountId == "ANONYMOUS_PRINCIPAL" or UserIdentityAccessKeyId <> RecipientAccountId
  | extend bucketName = tostring(parse_json(RequestParameters).bucketName), keyName = tostring(parse_json(RequestParameters).key)
  | summarize time_min_success=arg_min(TimeGenerated, *), success_keys = dcount(keyName) by UserIdentityAccountId, SourceIpAddress, bucketName
  | where success_keys >= 1;
  failed_attempts
  | join kind=inner success_attempts on SourceIpAddress, UserIdentityAccountId, bucketName
  | where time_min_success > time_min_failed
  | project-away keyName
  | extend UserIdentityUserName = iff(isnotempty(UserIdentityUserName), UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1]))
  | extend timestamp = time_min_success, IPCustomEntity = SourceIpAddress, AccountCustomEntity = UserIdentityUserName, AssumedRoleArn = UserIdentityArn  
status: Available
kind: Scheduled
relevantTechniques:
- T1562
version: 1.0.0
id: 31b9e94b-0df6-4a3d-a297-3457b53c5d86
entityMappings:
- fieldMappings:
  - columnName: AccountCustomEntity
    identifier: FullName
  entityType: Account
- fieldMappings:
  - columnName: IPCustomEntity
    identifier: Address
  entityType: IP
name: Successful brute force attack on S3 Bucket.
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/31b9e94b-0df6-4a3d-a297-3457b53c5d86')]",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/31b9e94b-0df6-4a3d-a297-3457b53c5d86')]",
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules",
      "kind": "Scheduled",
      "apiVersion": "2022-11-01-preview",
      "properties": {
        "displayName": "Successful brute force attack on S3 Bucket.",
        "description": "'A successful brute force attack on an S3 bucket was detected. Verify these actions, and if needed, remediate the compromise.'\n",
        "severity": "High",
        "enabled": true,
        "query": "let timeframe = 1h;\nlet failed_attempts = AWSCloudTrail\n| where TimeGenerated >= ago(timeframe)\n| where EventName == \"GetObject\" and isnotempty(ErrorMessage) and isnotempty(ErrorCode)\n| where UserIdentityAccountId == \"ANONYMOUS_PRINCIPAL\" or UserIdentityAccessKeyId <> RecipientAccountId\n| extend bucketName = tostring(parse_json(RequestParameters).bucketName), keyName = tostring(parse_json(RequestParameters).key)\n| summarize time_min_failed=arg_min(TimeGenerated, *), failed_keys = dcount(keyName) by UserIdentityAccountId, SourceIpAddress, bucketName\n| where failed_keys > 20;\nlet success_attempts = AWSCloudTrail\n| where TimeGenerated >= ago(timeframe)\n| where EventName == \"GetObject\" and isempty(ErrorMessage) and isempty(ErrorCode)\n| where UserIdentityAccountId == \"ANONYMOUS_PRINCIPAL\" or UserIdentityAccessKeyId <> RecipientAccountId\n| extend bucketName = tostring(parse_json(RequestParameters).bucketName), keyName = tostring(parse_json(RequestParameters).key)\n| summarize time_min_success=arg_min(TimeGenerated, *), success_keys = dcount(keyName) by UserIdentityAccountId, SourceIpAddress, bucketName\n| where success_keys >= 1;\nfailed_attempts\n| join kind=inner success_attempts on SourceIpAddress, UserIdentityAccountId, bucketName\n| where time_min_success > time_min_failed\n| project-away keyName\n| extend UserIdentityUserName = iff(isnotempty(UserIdentityUserName), UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1]))\n| extend timestamp = time_min_success, IPCustomEntity = SourceIpAddress, AccountCustomEntity = UserIdentityUserName, AssumedRoleArn = UserIdentityArn\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "PT1H",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0,
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "DefenseEvasion"
        ],
        "techniques": [
          "T1562"
        ],
        "alertRuleTemplateName": "31b9e94b-0df6-4a3d-a297-3457b53c5d86",
        "customDetails": null,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "AccountCustomEntity",
                "identifier": "FullName"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "IPCustomEntity",
                "identifier": "Address"
              }
            ]
          }
        ],
        "status": "Available",
        "templateVersion": "1.0.0",
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_S3BruteForce.yaml"
      }
    }
  ]
}