Detection rules › Kusto

Palo Alto - possible internal to external port scanning

Status
available
Severity
low
Time window
1h
Group by
ApplicationProtocol, DestinationIP, DestinationPort, DeviceAction, DeviceName, DeviceProduct, DeviceVendor, Protocol, Reason, SourceIP, SourceUserID
Source
github.com/Azure/Azure-Sentinel

'Identifies a list of internal Source IPs (10.x.x.x Hosts) that have triggered 10 or more non-graceful tcp server resets from one or more Destination IPs which results in an "ApplicationProtocol = incomplete" designation. The server resets coupled with an "Incomplete" ApplicationProtocol designation can be an indication of internal to external port scanning or probing attack. References: https://knowledgebase.paloaltonetworks.com/KCSArticleDetail?id=kA10g000000ClUvCAK and https://knowledgebase.paloaltonetworks.com/KCSArticleDetail?id=kA10g000000ClTaCAK'

MITRE ATT&CK coverage

TacticTechniques
Discovery

Rule body

id: 5b72f527-e3f6-4a00-9908-8e4fee14da9f
name: Palo Alto - possible internal to external port scanning
description: |
  'Identifies a list of internal Source IPs (10.x.x.x Hosts) that have triggered 10 or more non-graceful tcp server resets from one or more Destination IPs which results in an "ApplicationProtocol = incomplete" designation. The server resets coupled with an "Incomplete" ApplicationProtocol designation can be an indication of internal to external port scanning or probing attack.
  References: https://knowledgebase.paloaltonetworks.com/KCSArticleDetail?id=kA10g000000ClUvCAK and
  https://knowledgebase.paloaltonetworks.com/KCSArticleDetail?id=kA10g000000ClTaCAK'
severity: Low
status: Available
requiredDataConnectors:
  - connectorId: CefAma
    dataTypes:
      - CommonSecurityLog
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Discovery
relevantTechniques:
  - T1046
query: |
  CommonSecurityLog
  | where isnotempty(DestinationPort) and DeviceAction !in ("reset-both", "deny")
  // filter out common usage ports. Add ports that are legitimate for your environment
  | where DestinationPort !in ("443", "53", "389", "80", "0", "880", "8888", "8080")
  | where ApplicationProtocol == "incomplete"
  // filter out IANA ephemeral or negotiated ports as per https://en.wikipedia.org/wiki/Ephemeral_port
  | where DestinationPort !between (toint(49512) .. toint(65535))
  | where Computer != ""
  | where ipv4_is_private(DestinationIP) == false
  | extend Reason = coalesce(
                                column_ifexists("Reason", ""),
                                extract("reason=(.+?)(;|$)", 1, AdditionalExtensions),
                                ""
                            )
  // Filter out any graceful reset reasons of AGED OUT which occurs when a TCP session closes with a FIN due to aging out.
  | where Reason !has "aged-out"
  // Filter out any TCP FIN which occurs when a TCP FIN is used to gracefully close half or both sides of a connection.
  | where Reason !has "tcp-fin"
  // Uncomment one of the following where clauses to trigger on specific TCP reset reasons
  // See Palo Alto article for details - https://knowledgebase.paloaltonetworks.com/KCSArticleDetail?id=kA10g000000ClUvCAK
  // TCP RST-server - Occurs when the server sends a TCP reset to the client
  // | where AdditionalExtensions has "reason=tcp-rst-from-server"
  // TCP RST-client - Occurs when the client sends a TCP reset to the server
  // | where AdditionalExtensions has "reason=tcp-rst-from-client"
  // Already performed
  //| extend reason = tostring(split(AdditionalExtensions, ";")[3])
  | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), count() by DeviceName, SourceUserID, SourceIP, ApplicationProtocol, Reason, DestinationPort, Protocol, DeviceVendor, DeviceProduct, DeviceAction, DestinationIP
  | where count_ >= 10
  | summarize StartTimeUtc = min(StartTimeUtc), EndTimeUtc = max(EndTimeUtc), makeset(DestinationIP), totalcount = sum(count_) by DeviceName, SourceUserID, SourceIP, ApplicationProtocol, Reason, DestinationPort, Protocol, DeviceVendor, DeviceProduct, DeviceAction
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: SourceUserID
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: DeviceName
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: SourceIP
version: 1.0.8
kind: Scheduled

Stages and Predicates

Stage 1: source

CommonSecurityLog

Stage 2: where

| where isnotempty(DestinationPort) and DeviceAction !in ("reset-both", "deny")

Stage 3: where

| where DestinationPort !in ("443", "53", "389", "80", "0", "880", "8888", "8080")

Stage 4: where

| where ApplicationProtocol == "incomplete"

Stage 5: where

| where DestinationPort !between (toint(49512) .. toint(65535))

Stage 6: where

| where Computer != ""

Stage 7: where

| where ipv4_is_private(DestinationIP) == false

Stage 8: extend

| extend Reason = coalesce(
                              column_ifexists("Reason", ""),
                              extract("reason=(.+?)(;|$)", 1, AdditionalExtensions),
                              ""
                          )

Stage 9: where

| where Reason !has "aged-out"

Stage 10: where

| where Reason !has "tcp-fin"

Stage 11: summarize

| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), count() by DeviceName, SourceUserID, SourceIP, ApplicationProtocol, Reason, DestinationPort, Protocol, DeviceVendor, DeviceProduct, DeviceAction, DestinationIP

Stage 12: where

| where count_ >= 10

Stage 13: summarize

| summarize StartTimeUtc = min(StartTimeUtc), EndTimeUtc = max(EndTimeUtc), makeset(DestinationIP), totalcount = sum(count_) by DeviceName, SourceUserID, SourceIP, ApplicationProtocol, Reason, DestinationPort, Protocol, DeviceVendor, DeviceProduct, DeviceAction

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
DeviceActionindeny, reset-bothexcludes:DeviceAction field:"DeviceAction" value:"deny" field:"DeviceAction" value:"reset-both"
DestinationPortin0, 389, 443, 53, 80, 8080, 880, 8888excludes:DestinationPort
DestinationPortge49512excludes:DestinationPort field:"DestinationPort" value:"49512"
DestinationPortle65535excludes:DestinationPort field:"DestinationPort" value:"65535"
DestinationIPcidr_match10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, 127.0.0.0/8excludes:DestinationIP
Reasonmatchaged-outexcludes:Reason field:"Reason" value:"aged-out"
Reasonmatchtcp-finexcludes:Reason field:"Reason" value:"tcp-fin"

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
ApplicationProtocolsummarize
DestinationPortsummarize
DeviceActionsummarize
DeviceNamesummarize
DeviceProductsummarize
DeviceVendorsummarize
EndTimeUtcsummarize
Protocolsummarize
Reasonsummarize
SourceIPsummarize
SourceUserIDsummarize
StartTimeUtcsummarize
totalcountsummarize