Lambda CRUD Actions


Description

Unauthorized lambda Create, Read, Update, or Delete event occurred.

Query · python

from fnmatch import fnmatch

from panther_aws_helpers import aws_rule_context

LAMBDA_CRUD_EVENTS = {
    "AddPermission",
    "CreateAlias",
    "CreateEventSourceMapping",
    "CreateFunction",
    "DeleteAlias",
    "DeleteEventSourceMapping",
    "DeleteFunction",
    "PublishVersion",
    "RemovePermission",
    "UpdateAlias",
    "UpdateEventSourceMapping",
    "UpdateFunctionCode",
    "UpdateFunctionConfiguration",
}

ALLOWED_ROLES = [
    "*DeployRole",
]


def rule(event):
    if (
        event.get("eventSource") == "lambda.amazonaws.com"
        and event.get("eventName") in LAMBDA_CRUD_EVENTS
    ):
        for role in ALLOWED_ROLES:
            if fnmatch(event.deep_get("userIdentity", "arn", default="unknown-arn"), role):
                return False
        return True
    return False


def title(event):
    return (
        f"[{event.deep_get('userIdentity','arn', default = 'unknown-arn')}] "
        f"performed Lambda "
        f"[{event.get('eventName')}] in "
        f"[{event.get('recipientAccountId')} {event.get('awsRegion')}]."
    )


def dedup(event):
    return f"{event.deep_get('userIdentity','arn', default = 'unknown-arn')}"


def alert_context(event):
    return aws_rule_context(event)

Analyst notes

https://docs.aws.amazon.com/lambda/latest/dg/logging-using-cloudtrail.html

Raw source Lambda CRUD Actions · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
Filename: aws_lambda_crud.py
RuleID: "AWS.LAMBDA.CRUD"
DisplayName: "Lambda CRUD Actions"
Enabled: false
LogTypes:
  - AWS.CloudTrail
Tags:
  - AWS
  - Security Control
  - Configuration Required
Reports:
  CIS:
    - 3.12
  MITRE ATT&CK:
    - TA0005:T1525
Severity: High
Description: Unauthorized lambda Create, Read, Update, or Delete event occurred.
Runbook: https://docs.aws.amazon.com/lambda/latest/dg/logging-using-cloudtrail.html
Reference: https://docs.aws.amazon.com/lambda/latest/dg/logging-using-cloudtrail.html
SummaryAttributes:
  - eventSource
  - eventName
  - recipientAccountId
  - awsRegion
  - p_any_aws_arns
Tests:
  - Name: Lambda DeleteFunction Unauthorized Account
    ExpectedResult: true
    Log:
      {
        "eventVersion": "1.03",
        "userIdentity":
          {
            "type": "IAMUser",
            "principalId": "A1B2C3D4E5F6G7EXAMPLE",
            "arn": "arn:aws:iam::999999999999:user/myUserName",
            "accountId": "999999999999",
            "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
            "userName": "myUserName",
          },
        "eventTime": "2015-03-18T19:04:42Z",
        "eventSource": "lambda.amazonaws.com",
        "eventName": "DeleteFunction",
        "awsRegion": "us-east-1",
        "sourceIPAddress": "127.0.0.1",
        "userAgent": "Python-httplib2/0.8 (gzip)",
        "requestParameters": { "functionName": "basic-node-task" },
        "responseElements": null,
        "requestID": "a2198ecc-cda1-11e4-aaa2-e356da31e4ff",
        "eventID": "20b84ce5-730f-482e-b2b2-e8fcc87ceb22",
        "eventType": "AwsApiCall",
        "recipientAccountId": "999999999999",
      }
  - Name: Lambda DeleteFunction Unauthorized User
    ExpectedResult: true
    Log:
      {
        "eventVersion": "1.03",
        "userIdentity":
          {
            "type": "IAMUser",
            "principalId": "A1B2C3D4E5F6G7EXAMPLE",
            "arn": "arn:aws:iam::123456789012:user/myUserName",
            "accountId": "123456789012",
            "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
            "userName": "myUserName",
          },
        "eventTime": "2015-03-18T19:04:42Z",
        "eventSource": "lambda.amazonaws.com",
        "eventName": "DeleteFunction",
        "awsRegion": "us-east-1",
        "sourceIPAddress": "127.0.0.1",
        "userAgent": "Python-httplib2/0.8 (gzip)",
        "requestParameters": { "functionName": "basic-node-task" },
        "responseElements": null,
        "requestID": "a2198ecc-cda1-11e4-aaa2-e356da31e4ff",
        "eventID": "20b84ce5-730f-482e-b2b2-e8fcc87ceb22",
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
      }
  - Name: Lambda DeleteFunction Authorized Account
    ExpectedResult: false
    Log:
      {
        "eventVersion": "1.03",
        "userIdentity":
          {
            "type": "IAMUser",
            "principalId": "A1B2C3D4E5F6G7EXAMPLE",
            "arn": "arn:aws:iam::123456789012:user/DeployRole",
            "accountId": "123456789012",
            "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
            "userName": "myUserName",
          },
        "eventTime": "2015-03-18T19:04:42Z",
        "eventSource": "lambda.amazonaws.com",
        "eventName": "DeleteFunction",
        "awsRegion": "us-west-1",
        "sourceIPAddress": "127.0.0.1",
        "userAgent": "Python-httplib2/0.8 (gzip)",
        "requestParameters": { "functionName": "basic-node-task" },
        "responseElements": null,
        "requestID": "a2198ecc-cda1-11e4-aaa2-e356da31e4ff",
        "eventID": "20b84ce5-730f-482e-b2b2-e8fcc87ceb22",
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
      }


# ------ paired body: aws_lambda_crud.py ------

from fnmatch import fnmatch

from panther_aws_helpers import aws_rule_context

LAMBDA_CRUD_EVENTS = {
    "AddPermission",
    "CreateAlias",
    "CreateEventSourceMapping",
    "CreateFunction",
    "DeleteAlias",
    "DeleteEventSourceMapping",
    "DeleteFunction",
    "PublishVersion",
    "RemovePermission",
    "UpdateAlias",
    "UpdateEventSourceMapping",
    "UpdateFunctionCode",
    "UpdateFunctionConfiguration",
}

ALLOWED_ROLES = [
    "*DeployRole",
]


def rule(event):
    if (
        event.get("eventSource") == "lambda.amazonaws.com"
        and event.get("eventName") in LAMBDA_CRUD_EVENTS
    ):
        for role in ALLOWED_ROLES:
            if fnmatch(event.deep_get("userIdentity", "arn", default="unknown-arn"), role):
                return False
        return True
    return False


def title(event):
    return (
        f"[{event.deep_get('userIdentity','arn', default = 'unknown-arn')}] "
        f"performed Lambda "
        f"[{event.get('eventName')}] in "
        f"[{event.get('recipientAccountId')} {event.get('awsRegion')}]."
    )


def dedup(event):
    return f"{event.deep_get('userIdentity','arn', default = 'unknown-arn')}"


def alert_context(event):
    return aws_rule_context(event)

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.