Detection rules › Panther

Panther rules: new

New AWS Account Created

#
Severity
informational
Entities
aws_account_ids
Log types
AWS.CloudTrail
Tags
DataModel, Indicator Collection, Persistence:Create Account
Reference
docs.aws.amazon.com
Source
github.com/panther-labs/panther-analysis

A new AWS account was created

MITRE ATT&CK coverage

TacticTechniques
Persistence

Detection logic

import json
from datetime import timedelta

import panther_event_type_helpers as event_type
from panther_base_helpers import resolve_timestamp_string
from panther_detection_helpers.caching import put_string_set

# Days an account is considered new
TTL = timedelta(days=3)


def parse_new_account_id(event):
    if event.get("serviceEventDetails"):
        try:
            details = json.loads(event.get("serviceEventDetails"))
            return str(
                details.get("createAccountStatus", {}).get("accountId", "<UNKNOWN_ACCOUNT_ID>")
            )
        except (TypeError, ValueError):
            return "<UNABLE TO PARSE ACCOUNT ID>"
    return "<UNKNOWN ACCOUNT ID>"


def rule(event):
    if event.udm("event_type") != event_type.ACCOUNT_CREATED:
        return False
    account_id = parse_new_account_id(event)
    event_time = resolve_timestamp_string(event.get("p_event_time"))
    expiry_time = event_time + TTL
    account_event_id = f"new_aws_account_{event.get('p_row_id')}"

    if account_id:
        put_string_set(
            "new_account - " + account_id, [account_event_id], expiry_time.strftime("%s")
        )

    return True


def title(event):
    return f"A new AWS account has been created. Account ID - [{parse_new_account_id(event)}]"

Rule specification

AnalysisType: rule
Filename: new_aws_account_logging.py
RuleID: "Standard.NewAWSAccountCreated"
DisplayName: "New AWS Account Created"
Enabled: true
LogTypes:
  - AWS.CloudTrail
Tags:
  - DataModel
  - Indicator Collection
  - Persistence:Create Account
Severity: Info
Reports:
  MITRE ATT&CK:
    - TA0003:T1136
Description: A new AWS account was created
Runbook: A new AWS account was created, ensure it was created through standard practice and is for a valid purpose.
Reference: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_security_incident-response.html#:~:text=AWS%20Organizations%20information%20in%20CloudTrail
SummaryAttributes:
  - p_any_aws_account_ids

Stages and Predicates

Fires on AWS.CloudTrail events when the condition below holds.

Condition

  • event_type is account_created

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Indicators

These rows show field, operator, and value matches.

Response runbook

A new AWS account was created, ensure it was created through standard practice and is for a valid purpose.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "awsRegion": "us-east-1",
  "eventID": "axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "eventName": "CreateAccountResult",
  "eventSource": "organizations.amazonaws.com",
  "eventTime": "2021-05-20 15:53:47Z",
  "eventType": "AwsServiceEvent",
  "eventVersion": "1.08",
  "managementEvent": true,
  "p_any_aws_account_ids": [
    "111111111111",
    "222222222222"
  ],
  "p_event_time": "2021-05-20 15:53:47Z",
  "p_log_type": "AWS.CloudTrail",
  "readOnly": false,
  "recipientAccountId": "292442345278",
  "serviceEventDetails": "{\n  \"createAccountStatus\": {\n    \"accountId\": \"1111111111111111\",\n    \"accountName\": \"****\",\n    \"completedTimestamp\": \"May 20, 2021 3:53:47 PM\",\n    \"id\": \"car-aaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n    \"requestedTimestamp\": \"May 20, 2021 3:53:44 PM\",\n    \"state\": \"SUCCEEDED\"\n  }\n}"
}

New Unique Values - Panther Audit Login from New IP

#
Tags
Anomaly Detection, Example, New Unique Values
Source
github.com/panther-labs/panther-analysis

Find instances of users signing in to Panther from an IP they previously haven't used.

Rule specification

AnalysisType: saved_query
QueryName: "New Unique Values - Panther Audit Login from New IP"
Description: Find instances of users signing in to Panther from an IP they previously haven't used.
Tags:
  - Anomaly Detection
  - Example
  - New Unique Values
Query: |-
    -- pragma: template

    {% import 'anomalies' new_unique_values %}

    with subquery as (
        SELECT
            *,
            actor:attributes.email as actoremail
        FROM panther_logs.public.panther_audit
        WHERE p_occurs_since('60 day')
    ),
    {{ new_unique_values('subquery', 'actoremail', 'sourceIP', '1day') }}

New User Account Created

#
Severity
informational
Compliance
Stratus Red Team aws.persistence.iam-create-admin-user
Log types
OneLogin.Events, AWS.CloudTrail, Zoom.Operation
Tags
DataModel, Indicator Collection, OneLogin, Persistence:Create Account
Reference
attack.mitre.org
Source
github.com/panther-labs/panther-analysis

A new account was created

MITRE ATT&CK coverage

TacticTechniques
Persistence

Detection logic

from datetime import timedelta

import panther_event_type_helpers as event_type
from panther_base_helpers import resolve_timestamp_string
from panther_detection_helpers.caching import put_string_set

# Days an account is considered new
TTL = timedelta(days=3)


def rule(event):
    if event.udm("event_type") != event_type.USER_ACCOUNT_CREATED:
        return False

    user_event_id = f"new_user_{event.get('p_row_id')}"
    new_user = event.udm("user") or "<UNKNOWN_USER>"
    new_account = event.udm("user_account_id") or "<UNKNOWN_ACCOUNT>"
    event_time = resolve_timestamp_string(event.get("p_event_time"))
    expiry_time = event_time + TTL

    if new_user:
        put_string_set(
            new_user + "-" + str(new_account), [user_event_id], expiry_time.strftime("%s")
        )
    return True


def title(event):
    return f"A new user account was created - [{event.udm('user') or '<UNKNOWN_USER>'}]"

Rule specification

# Monitors for useraccount creation and adds an entry to the KVStore for the user. This depends on the
# event_type of USER_ACCOUNT_CREATED to be in the data model for the log source and will work in tandem
# with a helper function that checks for the userid in the KV store.
# This is rule is explicitly looking for accounts associated with a userid, not automation accounts that
# May have no user associated

AnalysisType: rule
Filename: new_user_account_logging.py
RuleID: "Standard.NewUserAccountCreated"
DisplayName: "New User Account Created"
Enabled: true
LogTypes:
  - OneLogin.Events
  - AWS.CloudTrail
  - Zoom.Operation
Tags:
  - DataModel
  - Indicator Collection
  - OneLogin
  - Persistence:Create Account
Severity: Info
Reports:
  MITRE ATT&CK:
    - TA0003:T1136

  Stratus Red Team:
    - aws.persistence.iam-create-admin-user
Description: A new account was created
Runbook: A new user account was created, ensure it was created through standard practice and is for a valid purpose.
Reference: https://attack.mitre.org/techniques/T1136/001/
SummaryAttributes:
  - p_any_usernames

Stages and Predicates

Fires on OneLogin.Events, AWS.CloudTrail, Zoom.Operation events when the condition below holds.

Condition

  • event_type is user_account_created

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
user

Response runbook

A new user account was created, ensure it was created through standard practice and is for a valid purpose.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "actor_user_id": 123456,
  "actor_user_name": "Bob Cat",
  "event_type_id": 13,
  "p_event_time": "2021-06-27 00:08:28.792Z",
  "p_log_type": "OneLogin.Events",
  "p_row_id": "aaaaaaaabbbbbbbbbbbbccccccccc",
  "user_id": 12345,
  "user_name": "Bob Cat"
}