SIEM Integration Overview: Panther

🚧

Panther Sunsetting Built in Lookup Tables

Panther is sunsetting the GreyNoise Enrichment Provider on June 17, 2024. Starting that date, GreyNoise intelligence data will no longer be natively available in Panther. Please reach out to your Support team with any questions or concerns.

Panther Documentation

The Panther documentation for this feature can be found at: https://docs.panther.com/enrichment/greynoise

GreyNoise Integration for Panther

As of the 1.32 release of the Panther platform, GreyNoise NOISE and RIOT dataset are available natively within the Panther platform. These built-in data sources can be used to enrich IP addresses in all the default log types that ship with Panther. The ability to enrich custom log types will be included in a future release.

Basic vs. Advanced Enrichment sources

Panther includes two packages of GreyNoise enrichment sources: Basic and Advanced

Basic

The Basic enrichment sources (greynoise_noise_basic and greynoise_riot_basic) are included at no additional charge for all Panther customers. These enrichment sources provide basic level access to the GreyNoise enrichment data, including the following fields returned for each enriched IP within the data sets

The fields for Noise Basic include:
IP
NOISE/SEEN
CLASSIFICATION
ACTOR

The fields for RIOT Basic include:
IP
RIOT
NAME

Enabling

The Basic enrichment sources can be enabled by toggling the Enabled button on the GreyNoise Basic Pack. For detailed instructions, please see: https://docs.panther.com/enrichment/greynoise/how-to-use-greynoise-to-enhance-detections

🚧

Viewing GreyNoise Data in Data Explorer

Currently, you are not able to browse the GreyNoise data via the Panther Data Explorer

Advanced

The Advanced enrichment sources (greynoise_noise_advanced and greynoise_riot_advanced) are available to customers with a current GreyNoise Automate or Search Level 6+ subscription. These enrichment sources provide basic level access to the GreyNoise enrichment data, including the following fields returned for each enriched IP within the data sets

The fields for Noise Advanced include:
IP
NOISE/SEEN
CLASSIFICATION
ACTOR
BOT
CVE
FIRST_SEEN
LAST_SEEN
METADATA
RAW_DATA
SPOOFABLE
TAGS
VPN
VPN_SERVICE

The fields for RIOT Advanced include:
IP
RIOT
NAME
TRUST_LEVEL
CATEGORY
DESCRIPTION
EXPLANATION
REFERENCE
LAST_UPDATED

Enabling

The Advanced enrichment sources must be enabled by Panther so that appropriate subscription or trial levels can be validated. Please reach out to your Panther CSM for assistance.

Detection Samples

In additional to the enrichment sources, an additional python library as been created to help build detections based on GreyNoise enrichment data. Additional information on the Python Library can be found at

The following is a set of samples showing some of the basic detection modifications that can be made:

The starting point for adding the GreyNoise enrichment is to import the python helper library and enrich the event in the following fashion

from panther_greynoise_helpers import GetGreyNoiseObject, GetGreyNoiseRiotObject

def rule(event):
    global noise
    global riot
    noise = GetGreyNoiseObject(event)
    riot = GetGreyNoiseRiotObject(event)

Base Alert Sample

from panther_base_helpers import deep_get

def rule(event):
    if (event.get("eventType") == "user.session.start" 
    and deep_get(event, "outcome", "result") == "FAILURE"):
        return True
    return False

def title(event):
    return f"A Possible Brute Force Attack on Okta Detected from IP {deep_get(event, 'client', 'ipAddress')}"

def severity(event):
    return "MEDIUM"

Base Alert Sample Update with Dynamic Severity Based on GreyNoise Enrichment

from panther_base_helpers import deep_get
from panther_greynoise_helpers import GetGreyNoiseObject

def rule(event):
    global noise
    noise = GetGreyNoiseObject(event)
    if (event.get("eventType") == "user.session.start" and deep_get(event, "outcome", "result") == "FAILURE"):
        return True
    return False

def title(event):
    return f"A Possible Brute Force Attack on Okta Detected from IP {deep_get(event, 'client', 'ipAddress')}"

def severity(event):
    if noise.classification("client.ipAddress") == "malicious":
        return "CRITICAL"
    if noise.classification("client.ipAddress") == "benign":
        return "LOW"
    return "MEDIUM"

Base Alert Sample Update with Dynamic Severity Based on GreyNoise Enrichment and Additional Alert Context

from panther_base_helpers import deep_get
from panther_greynoise_helpers import GetGreyNoiseObject

def rule(event):
    global noise
    noise = GetGreyNoiseObject(event)
    if (event.get("eventType") == "user.session.start" and deep_get(event, "outcome", "result") == "FAILURE"):
        return True
    return False

def title(event):
    return f"A Possible Brute Force Attack on Okta Detected from IP {deep_get(event, 'client', 'ipAddress')}"

def severity(event):
    if noise.classification("client.ipAddress") == "malicious":
        return "CRITICAL"
    if noise.classification("client.ipAddress") == "benign":
        return "LOW"
    return "MEDIUM"

def alert_context(event):
    context ={"message": "No GreyNoise Data Available"}
    if noise.classification:
        context = {
            "actor": noise.actor("client.ipAddress"),
            "classification": noise.classification("client.ipAddress"),
            "ip": noise.ip_address("client.ipAddress"),
        }
    return context

Base Alert Sample Update including RIOT dataset enrichment.

from panther_base_helpers import deep_get
from panther_greynoise_helpers import GetGreyNoiseObject, GetGreyNoiseRiotObject

def rule(event):
    global noise
    noise = GetGreyNoiseObject(event)
    riot = GetGreyNoiseRiotObject(event)

    if riot.is_riot:
        return False
    if (event.get("eventType") == "user.session.start" 
    and deep_get(event, "outcome", "result") == "FAILURE"):
        return True
    return False

def title(event):
    return f"A Possible Brute Force Attack on Okta Detected from IP {deep_get(event, 'client', 'ipAddress')}"

def severity(event):
    if noise.classification("client.ipAddress") == "malicious":
        return "CRITICAL"
    return "MEDIUM"

def alert_context(event):
    context = {
        "actor": noise.actor("client.ipAddress"),
        "classification": noise.classification("client.ipAddress"),
        "ip": noise.ip_address("client.ipAddress"),
    }
    return context

Additional Assistance

For additional assistance with the Panther GreyNoise integration, please reach out to your Panther or GreyNoise CSM.