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

AWSCloudTrail - Successful API executed from a Tor exit node

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 Web Services/Analytic Rules/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
version: 1.0.2
id: 0adab960-5565-4978-ba6d-044553e4acc4
relevantTechniques:
- T1204
requiredDataConnectors:
- connectorId: AWS
  dataTypes:
  - AWSCloudTrail
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}}'
triggerOperator: gt
entityMappings:
- fieldMappings:
  - columnName: AccountName
    identifier: Name
  - columnName: AccountUPNSuffix
    identifier: UPNSuffix
  - columnName: RecipientAccountId
    identifier: CloudAppAccountId
  entityType: Account
- fieldMappings:
  - columnName: SourceIpAddress
    identifier: Address
  entityType: IP
name: AWSCloudTrail - Successful API executed from a Tor exit node
queryFrequency: 1d
triggerThreshold: 0
customDetails:
  UserIdentityArn: UserIdentityArn
  AWSRegion: AWSRegion
  EventSource: EventSource
  EventName: EventName
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.  
status: Available
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_APIfromTor.yaml
queryPeriod: 1d
severity: High
kind: Scheduled
tactics:
- Execution
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