Detection rules › Panther

AWS Potential Backdoor Lambda Function Through Resource-Based Policy

Status
Experimental
Severity
informational
Compliance
Stratus Red Team aws.persistence.lambda-backdoor-function
Log types
AWS.CloudTrail
Reference
https://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html
Source
github.com/panther-labs/panther-analysis

Identifies when a permission is added to a Lambda function, which could indicate a potential security risk.

MITRE ATT&CK coverage

TacticTechniques
Initial AccessT1078 Valid Accounts
PersistenceT1078 Valid Accounts
Privilege EscalationT1078 Valid Accounts
StealthT1078 Valid Accounts

Rule body yaml

AnalysisType: rule
Filename: aws_backdoor_lambda_function.py
RuleID: "AWS.Potential.Backdoor.Lambda"
DisplayName: "AWS Potential Backdoor Lambda Function Through Resource-Based Policy"
Enabled: true
LogTypes:
  - AWS.CloudTrail
Reports:
  MITRE ATT&CK:
    - TA0007:T1078

  Stratus Red Team:
    - aws.persistence.lambda-backdoor-function
Severity: Info
Status: Experimental
Description: >
  Identifies when a permission is added to a Lambda function, which could indicate a potential security risk.
Runbook: Make sure that the permission is legitimate and necessary. If not, remove the permission
Reference: https://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html
Tests:
  - Name: Lambda Add Permission Event
    ExpectedResult: true
    Log:
      {
        "eventVersion": "1.05",
        "userIdentity": {
          "type": "AssumedRole",
          "principalId": "tester",
          "arn": "arn:aws:sts::123456789012:assumed-role/tester",
          "accountId": "123456789012",
          "accessKeyId": "1",
          "sessionContext": {
            "sessionIssuer": {
              "type": "Role",
              "principalId": "1111",
              "arn": "arn:aws:iam::123456789012:role/tester",
              "accountId": "123456789012",
              "userName": "Tester"
            },
            "webIdFederationData": {},
            "attributes": {
              "mfaAuthenticated": "true",
              "creationDate": "2019-01-01T00:00:00Z"
            }
          }
        },
        "eventTime": "2019-01-01T00:00:00Z",
        "eventSource": "lambda.amazonaws.com",
        "eventName": "AddPermission20150331",
        "awsRegion": "us-west-2",
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "console.amazonaws.com",
        "requestParameters": {
          "functionName": "my-lambda-function"
        },
        "responseElements": null,
        "requestID": "1",
        "eventID": "1",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
        "p_log_type": "AWS.CloudTrail"
      }
  - Name: Lambda Add Permission Event v2
    ExpectedResult: true
    Log:
      {
        "eventVersion": "1.05",
        "userIdentity": {
          "type": "AssumedRole",
          "principalId": "tester",
          "arn": "arn:aws:sts::123456789012:assumed-role/tester",
          "accountId": "123456789012",
          "accessKeyId": "1",
          "sessionContext": {
            "sessionIssuer": {
              "type": "Role",
              "principalId": "1111",
              "arn": "arn:aws:iam::123456789012:role/tester",
              "accountId": "123456789012",
              "userName": "Tester"
            },
            "webIdFederationData": {},
            "attributes": {
              "mfaAuthenticated": "true",
              "creationDate": "2019-01-01T00:00:00Z"
            }
          }
        },
        "eventTime": "2019-01-01T00:00:00Z",
        "eventSource": "lambda.amazonaws.com",
        "eventName": "AddPermission20150331v2",
        "awsRegion": "us-west-2",
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "console.amazonaws.com",
        "requestParameters": {
          "functionName": "my-lambda-function"
        },
        "responseElements": null,
        "requestID": "1",
        "eventID": "1",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
        "p_log_type": "AWS.CloudTrail"
      }
  - Name: Lambda Remove Permission Event
    ExpectedResult: false
    Log:
      {
        "eventVersion": "1.05",
        "userIdentity": {
          "type": "AssumedRole",
          "principalId": "tester",
          "arn": "arn:aws:sts::123456789012:assumed-role/tester",
          "accountId": "123456789012",
          "accessKeyId": "1",
          "sessionContext": {
            "sessionIssuer": {
              "type": "Role",
              "principalId": "1111",
              "arn": "arn:aws:iam::123456789012:role/tester",
              "accountId": "123456789012",
              "userName": "Tester"
            },
            "webIdFederationData": {},
            "attributes": {
              "mfaAuthenticated": "true",
              "creationDate": "2019-01-01T00:00:00Z"
            }
          }
        },
        "eventTime": "2019-01-01T00:00:00Z",
        "eventSource": "lambda.amazonaws.com",
        "eventName": "RemovePermission",
        "awsRegion": "us-west-2",
        "sourceIPAddress": "111.111.111.111",
        "userAgent": "console.amazonaws.com",
        "requestParameters": {
          "functionName": "my-lambda-function"
        },
        "responseElements": null,
        "requestID": "1",
        "eventID": "1",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "recipientAccountId": "123456789012",
        "p_log_type": "AWS.CloudTrail"
      }

Detection logic

Condition

not (errorCode is_not_null or errorMessage is_not_null)
eventSource eq "lambda.amazonaws.com"
eventName in ["AddPermission20150331", "AddPermission20150331v2"]

Exclusions

Top-level NOT(...) conjuncts: predicates this rule actively suppresses.

FieldKindExcluded values
errorCodeis_not_null(no value, null check)
errorMessageis_not_null(no value, null check)

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
eventNamein
  • AddPermission20150331
  • AddPermission20150331v2
eventSourceeq
  • lambda.amazonaws.com

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
eventName
eventSource
awsRegion
recipientAccountId
sourceIPAddress
userAgent
userIdentity
actor_user
functionNamerequestParameters.functionName