Links

Rules and Scheduled Rules

Rules and scheduled rules detect suspicious activity in logs, then generate alerts

Overview

Rules and scheduled rules are segments of logic through which log data is run to detect suspicious activity and generate alerts. Rules analyze real-time events, while scheduled rules analyze events queried from your data lake. These detection types differ from policies, which apply to cloud resource configurations.
Rules can be created in the Console using the Simple Detection builder or by writing Python; in the CLI workflow, rules can be written in Python or YAML. Scheduled rules can be written in Python (in the Console or CLI workflow). Panther provides a number of Panther-managed rules and scheduled rules in Python, which are already written and continuously updated.
Common examples of rules include analyzing logs for:
  • Authentication from unknown or unexpected locations
  • Sensitive API calls, such as administrative changes to SaaS services
  • Network traffic access to sensitive data sources, such as databases or virtual machines
  • New, suspicious entries added into a system's scheduled tasks, like cron
  • Alerts generated from NIDS, HIDS, or other security systems

Rules vs. scheduled rules

Both rules and scheduled rules define logic through which log events are run—but rules analyze real-time events, while scheduled rules analyze events queried from your data lake.
  • Rules
    • Rules, sometimes referred to as real-time rules, are the default mechanism of analyzing data sent to Panther. Rules work by accepting a defined set of log types such as one or more of the Supported Logs sources, or your own custom data. Rules have the benefit of low-latency detection and alerting.
    • Use cases: High-signal logs that do not require joins with other data.
  • Scheduled rules
    • Scheduled rules work by accepting individual rows output from an associated scheduled query.
    • Use cases: Querying windows of time further in the past, running statistical analysis over data, or joining separate data streams.

Using Python vs. YAML

If you are writing rules locally, in the CLI workflow, you can use either Python or YAML. (Scheduled rules can only be written in Python.) There are advantages to using both languages, outlined below.
  • Write rules in Python when:
    • The complexity of the logic is very high, and cannot be represented in YAML.
    • The detection requires any of the features currently listed as limitations of YAML.
  • Write rules in YAML when:
    • You'd like to promote collaboration between team members with differing levels of technical skill. When YAML detections are uploaded to Panther, they're represented in the Console in the Simple Detection builder. You can then edit (or create new) detections in the Console using the Simple Detection builder.
For examples of the same detection logic written in both Python and YAML, see Rule examples, below.

How rules and scheduled rules work

Rules and scheduled rules each analyze one event at a time. They use event thresholds and de-duplication to create event grouping within windows of time.
At a minimum, each rule and scheduled rule must define rule logic. For Python detections, this means they each must contain a rule() function; for YAML detections, each must contain a Detection key with at least one match expression.
return True triggers an alert, while return False does not trigger an alert.
Python rules can also define dynamic alert functions, and YAML rules can use dynamic alert keys. Both can also utilize Inline Filters that run before detection logic.

Title of associated alerts

The title of an alert from a certain detection is determined by that detection's configuration. When a separate deduplication string is not explicitly set, the alert title is also used to deduplicate alerts.

How the alert title is set

The order of precedence for setting the alert title is as follows:
Python
YAML

Alert title precedence in Python:

  1. 1.
    The output of the dynamic title() function is used.
  2. 2.
    If title() is not defined, the value of the detection's display name is used. This is defined:
    • In the Console: in the Name field
    • In the CLI workflow: in the DisplayName field in the YAML file
  3. 3.
    If there is no display name defined, the detection's ID is used. This is defined:
    • In the Console: in the ID field
    • In the CLI workflow: in theRuleID or PolicyID field in the YAML file

Alert title precedence in YAML:

  1. 1.
    The dynamic alert title is used. This is defined:
    • In the Console: in the Optional Fields > Default title is > Change to field
    • In the developer workflow: in the AlertTitle field
  2. 2.
    If a dynamic alert title is not defined, the value of the detection's display name is used. This is defined:
    • In the Console: in the Name field
    • In the developer workflow: in the DisplayName field
  3. 3.
    If there is no display name defined, the detection's ID is used. This is defined:
    • In the Console: in the ID field
    • In the developer workflow: in theRuleID or PolicyID field

Deduplication of alerts

Events triggering the same detection within its deduplication period that also share a deduplication string will be grouped together in a single alert.
Each rule and scheduled rule has a default event threshold of 1 and deduplication period of 1h. This means all events returning True from the rule function (with the same deduplication string) will be grouped into a single alert within the hour after first being generated.
A rule or scheduled rule with an event threshold of 5 and deduplication period of 15m would not trigger an alert until five or more events (with the same deduplication string) passed into the rule function returned True within a 15-minute time period.

Deduplication period

The detection editor in the Panther Console supports a maximum deduplication period of 24 hours. If you upload your detections via the bulk uploader or the Panther Analysis Tool (PAT), there is no limit on the value of DedupPeriodMinutes.
The deduplication period is not affected by changing the status of an alert. This means, for example, events will continue to be grouped into the same alert for the length of the deduplication period even if an alert's status is changed to Resolved.

How the deduplication string is set

The order of precedence for setting the deduplication string is as follows:
Python
YAML

Deduplication string precedence in Python:

  1. 1.
    The output of the dynamic dedup() function is used.
  2. 2.
    Ifdedup() is not defined, the alert title is used. The alert title is defined by the order of precedence defined here.

Deduplication string precedence in YAML:

  1. 1.
    The value of the GroupBy key is used.
  2. 2.
    If GroupBy is not present, the alert title is used. The alert title is defined by the order of precedence defined here.
Which method you use to set the deduplication string depends on how granularly you want to group alerts:
  • If you only want alerts generated by a certain detection to be grouped separately from alerts from other detections, using the detection's display name (given that the display name is unique) or ID as the deduplication string will suffice.
  • If you want alerts generated by a certain detection to be grouped separately not only from alerts generated by other detections, but also from alerts triggered by the same detection where one or more event fields have different values, you can use title() or AlertTitle (for Python and YAML detections, respectively) to dynamically set the alert title and therefore, the deduplication string.
  • If you want to group alerts generated by a certain detection distinctly from alerts generated by the same detection where one or more event field values differ and you want to group the alerts based on one or more event fields that weren't used in title() or AlertTitle (or if you didn't set title() or AlertTitle at all), you can use dedup() or GroupBy (for Python and YAML detections, respectively) to set the deduplication string.

How to write rules and scheduled rules

You can write rules in the Panther Console (using the Simple Detection builder or Python) or locally (in YAML or Python); scheduled rules can be written in Python (in the Panther Console or locally).
Before you start writing a new rule, remember to check to see if there's an existing Panther-managed rule that meets your needs.
Writing detections locally means creating Python and/or YAML files that define a Panther detection on your own machine. After writing detections locally, you upload the files to your Panther instance, typically via PAT.
Note: Anything printed to stdout or stderr by your Python code will end up in CloudWatch. For SaaS/CPaaS customers, Panther engineers can see these CloudWatch logs during routine application monitoring.

How to write rules

These instructions outline how to set up real-time rules. To configure a scheduled rule, see How to write scheduled rules.
Follow the below instructions to learn how to write rules:

How to write scheduled rules

Scheduled rules are associated with one or more scheduled queries. If you have not yet created a scheduled query, follow the How to create a Saved and Scheduled Query instructions first, then return to these instructions to create the scheduled rule.
If the scheduled query returns multiple rows, each row is processed by the rule logic as a separate event. The number of alerts triggered depends on the deduplication settings you've configured on the scheduled rule.
We recommend doing as much data processing as is possible in SQL (i.e., in the scheduled query) in order to take advantage of database optimizations and improve rule performance.
Follow the below instructions to learn how to write scheduled rules:

Rule errors and scheduled rule errors

Rule errors and scheduled rule errors are types of detection errors generated when a detection's Python code raises an exception.
If there is no specific routing configured for rule errors, the alert for a rule error will route to the same destination used by the alert. See Routing order precedence on Alert Destinations for more information.
In the event of a query timeout, the Python code for Destinations will not run.

Rule examples

See templates for rules and scheduled rules in the panther-analysis GitHub repository.
For in-depth information on how to write detections, see Writing Python Detections and Writing YAML Detections.

Auth0 multi-factor authentication policy disabled

See how one detection is represented in both Python and YAML:
Python
YAML

Auth0 multi-factor authentication policy disabled detection in Python

from global_filter_auth0 import filter_include_event
from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event
from panther_base_helpers import deep_get
def rule(event):
if not filter_include_event(event):
return False
data_description = deep_get(event, "data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
request_path = deep_get(
event, "data", "details", "request", "path", default="<NO_REQUEST_PATH_FOUND>"
)
request_body = deep_get(event, "data", "details", "request", "body", default=[-1])
return all(
[
data_description == "Set the Multi-factor Authentication policies",
request_path == "/api/v2/guardian/policies",
request_body == [],
is_auth0_config_event(event),
]
)

Auth0 multi-factor authentication policy disabled detection in YAML

Detection:
- DeepKey:
- data
- description
Condition: Equals
Value: Set the Multi-factor Authentication policies
- DeepKey:
- data
- details
- request
- path
Condition: Equals
Value: /api/v2/guardian/policies
- DeepKey:
- data
- details
- request
- body
Condition: IsNullOrEmpty
- DeepKey:
- data
- details
- request
- channel
Condition: Equals
Value: 'https://manage.auth0.com/'

Detect and alert when an admin panel is accessed on a web server

As an example, let's write a rule to send an alert when an admin panel is accessed on a web server.
Take the following NGINX log:
{
"httpReferer": "https://domain1.com/?p=1",
"httpUserAgent": "Chrome/80.0.3987.132 Safari/537.36",
"remoteAddr": "180.76.15.143",
"request": "GET /admin-panel/ HTTP/1.1",
"status": 200,
"time": "2019-02-06 00:00:38 +0000 UTC"
}
We want to create a detection that:
  • Looks for 200 (OK) web requests to any URL containing "admin-panel"
  • Generates an an alert title that says there has been successful admin panel logins from a specific IP address
  • Deduplicates events based on IP address
Python
YAML
def rule(event):
return event.get('status') == 200 and 'admin-panel' in event.get('request')
def title(event):
return f"Successful admin panel login detected from {event.get('remoteAddr')}"
def dedup(event):
return event.get('remoteAddr')
Detection:
- KeyPath: status
Condition: Equals
Value: 200
- KeyPath: request
Condition: Contains
Value: 'admin-panel'
AlertTitle: "Successful admin panel login detected from {remoteAddr}"
GroupBy:
- KeyPath: remoteAddr
Then, the following would occur:
  1. 1.
    An alert would be generated and sent to the set of associated destinations, which by default are based on the rule severity.
  2. 2.
    The alert's title would say, "Successful admin panel login detected from 180.76.15.143".
  3. 3.
    Similar events with the same deduplication string of 180.76.15.143 would be appended to the same alert.
    • A unique alert will be generated for each unique deduplication string, which in this case, is the IP of the requestor.
  4. 4.
    The recipient of the alert could then log into Panther to view all alert metadata and a summary of the events, as well as execute searches across all events to perform additional analysis.

Reference

Alert severity

We recommend following these guidelines to define alert severity levels:
Severity
Exploitability
Description
Examples
Info
None
No risk, simply informational
Gaining operational awareness.
Low
Difficult
Little to no risk if exploited
Non-sensitive information leaking such as system time and OS versions.
Medium
Difficult
Moderate risk if exploited
Expired credentials, missing protection against accidental data loss, encryption settings, best practice settings for audit tools.
High
Moderate
Very damaging if exploited
Large gaps in visibility, directly vulnerable infrastructure, misconfigurations directly related to data exposure.
Critical
Easy
Causes extreme damage if exploited
Public data/systems available, leaked access keys.