Back
Id0adab960-5565-4978-ba6d-044553e4acc4
RulenameAWSCloudTrail - Successful API executed from a Tor exit node
DescriptionIdentifies successful AWS CloudTrail API activity originating from an IP address identified as a TOR exit node in

the external TOR list hosted at https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip. The rule alerts

only when CloudTrail indicates the request completed successfully with no ErrorCode and no ErrorMessage, and the source

IP is present in the TOR exit node list.
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%20Web%20Services/Analytic%20Rules/AWS_APIfromTor.yaml
Version1.0.2
Arm template0adab960-5565-4978-ba6d-044553e4acc4.json
Deploy To Azure
let TorNodes = (
externaldata (TorIP:string)
[h@'https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip']
with (ignoreFirstRecord=true));
AWSCloudTrail
| where SourceIpAddress in (TorNodes) and isempty(ErrorCode) and isempty(ErrorMessage)
| 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]), "")
| project TimeGenerated, SourceIpAddress, AccountName, AccountUPNSuffix, UserIdentityArn, UserIdentityUserName, UserIdentityPrincipalid, EventName, EventSource, AWSRegion, RecipientAccountId
triggerOperator: gt
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon%20Web%20Services/Analytic%20Rules/AWS_APIfromTor.yaml
query: |
  let TorNodes = (
  externaldata (TorIP:string)
  [h@'https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip']
  with (ignoreFirstRecord=true));
  AWSCloudTrail
  | where SourceIpAddress in (TorNodes) and isempty(ErrorCode) and isempty(ErrorMessage)
  | 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]), "")
  | project TimeGenerated, SourceIpAddress, AccountName, AccountUPNSuffix, UserIdentityArn, UserIdentityUserName, UserIdentityPrincipalid, EventName, EventSource, AWSRegion, RecipientAccountId
requiredDataConnectors:
- dataTypes:
  - AWSCloudTrail
  connectorId: AWS
triggerThreshold: 0
severity: High
status: Available
alertDetailsOverride:
  alertDescriptionFormat: A successful AWS API call was observed from TOR exit node IP {{SourceIpAddress}} for account {{AccountName}}.
  alertDisplayNameFormat: 'Successful AWS API call from TOR exit node: {{AccountName}} from {{SourceIpAddress}}'
id: 0adab960-5565-4978-ba6d-044553e4acc4
relevantTechniques:
- T1204
queryFrequency: 1d
customDetails:
  AWSRegion: AWSRegion
  UserIdentityArn: UserIdentityArn
  EventName: EventName
  EventSource: EventSource
name: AWSCloudTrail - Successful API executed from a Tor exit node
kind: Scheduled
queryPeriod: 1d
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
description: |
  Identifies successful AWS CloudTrail API activity originating from an IP address identified as a TOR exit node in
  the external TOR list hosted at https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip. The rule alerts
  only when CloudTrail indicates the request completed successfully with no ErrorCode and no ErrorMessage, and the source
  IP is present in the TOR exit node list.
version: 1.0.2
{
  "$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/0adab960-5565-4978-ba6d-044553e4acc4')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/0adab960-5565-4978-ba6d-044553e4acc4')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "A successful AWS API call was observed from TOR exit node IP {{SourceIpAddress}} for account {{AccountName}}.",
          "alertDisplayNameFormat": "Successful AWS API call from TOR exit node: {{AccountName}} from {{SourceIpAddress}}"
        },
        "alertRuleTemplateName": "0adab960-5565-4978-ba6d-044553e4acc4",
        "customDetails": {
          "AWSRegion": "AWSRegion",
          "EventName": "EventName",
          "EventSource": "EventSource",
          "UserIdentityArn": "UserIdentityArn"
        },
        "description": "Identifies successful AWS CloudTrail API activity originating from an IP address identified as a TOR exit node in\nthe external TOR list hosted at https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip. The rule alerts\nonly when CloudTrail indicates the request completed successfully with no ErrorCode and no ErrorMessage, and the source\nIP is present in the TOR exit node list.\n",
        "displayName": "AWSCloudTrail - Successful API executed from a Tor exit node",
        "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%20Web%20Services/Analytic%20Rules/AWS_APIfromTor.yaml",
        "query": "let TorNodes = (\nexternaldata (TorIP:string)\n[h@'https://firewalliplists.gypthecat.com/lists/kusto/kusto-tor-exit.csv.zip']\nwith (ignoreFirstRecord=true));\nAWSCloudTrail\n| where SourceIpAddress in (TorNodes) and isempty(ErrorCode) and isempty(ErrorMessage)\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| project TimeGenerated, SourceIpAddress, AccountName, AccountUPNSuffix, UserIdentityArn, UserIdentityUserName, UserIdentityPrincipalid, EventName, EventSource, AWSRegion, RecipientAccountId\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "severity": "High",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Execution"
        ],
        "techniques": [
          "T1204"
        ],
        "templateVersion": "1.0.2",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}