Cloud Threat Hunting - Persistence

--- ## Cloud Threat Hunting - Persistence Playbook The playbook is responsible for hunting persistence activity in the cloud. It supports AWS, GCP, and Azure - one at a time. ### Hunting Queries The playbook executes hunting queries for each provider related to each of the following: 1. IAM 2. Compute Resources 3. Compute Functions ### Indicator Extraction If relevant events are found during the search, indicators will be extracted using the `ExtractIndicators-CloudLogging` script. ---

Cloud Incident Response · 23 tasks · 8 inputs · 7 outputs

Details

IDCloud Threat Hunting - Persistence
From Version6.8.0
Tasks23

README

Cloud Threat Hunting - Persistence Playbook

The playbook is responsible for hunting persistence activity in the cloud. It supports AWS, GCP, and Azure - one at a time.

Hunting Queries

The playbook executes hunting queries for each provider related to each of the following:

  1. IAM
  2. Compute Resources
  3. Compute Functions

Indicator Extraction

If relevant events are found during the search, indicators will be extracted using the ExtractIndicators-CloudLogging script.

Dependencies

This playbook uses the following sub-playbooks, integrations, and scripts.

Sub-playbooks

This playbook does not use any sub-playbooks.

Integrations

This playbook does not use any integrations.

Scripts

  • IsIntegrationAvailable
  • Set
  • ExtractIndicators-CloudLogging

Commands

  • gcp-logging-log-entries-list
  • aws-cloudtrail-lookup-events
  • azure-log-analytics-execute-query

Playbook Inputs


Name Description Default Value Required
cloudProvider The cloud service provider involved.
The supported CSPs are AWS, Azure and GCP.
  Optional
AWSAccessKeyID The AWS access key ID.   Optional
username The username that initiated the API call.   Optional
region The region to search for events in.
e.g. us-east-1, us-west-2, etc.
  Optional
AzureTimespan The timespan to limit by the hunting query.
e.g.,
Use 2d for timespan of 2 days
Use 1.5h for timespan of 1.5 hour
Use 30m for timespan of 30 minutes
  Optional
AWSTimespan Date and time in the following format - yyyy-mm-ddThh:mm:ss
e.g.,
2022-05-29T12:00:00
2021-01-01T12:00:00
  Optional
GCPTimespan Date in ISO.
e.g.
2022-05-29T12:00:00.123Z
2021-01-01T12:00:00.234Z
  Optional
GCPProjectName The GCP project name.   Optional

Playbook Outputs


Path Description Type
CloudIndicators.arn The ARN. unknown
CloudIndicators.access_key_id The AWS access key ID. unknown
CloudIndicators.resource_name The resource name. unknown
CloudIndicators.source_ip The source IP. unknown
CloudIndicators.username The username used by the attacker. unknown
CloudIndicators.event_name The name of the event. unknown
CloudIndicators.user_agent The user agent used by the attacker. unknown

Playbook Image


Cloud Threat Hunting - Persistence

Inputs

  • cloudProvider — The cloud service provider involved. The supported CSPs are AWS, Azure and GCP.
  • AWSAccessKeyID — The AWS access key ID.
  • username — The username that initiated the API call.
  • region — The region to search for events in. e.g. us-east-1, us-west-2, etc.
  • AzureTimespan — The timespan to limit by the hunting query. e.g., Use 2d for timespan of 2 days Use 1.5h for timespan of 1.5 hour Use 30m for timespan of 30 minutes
  • AWSTimespan — Date and time in the following format - yyyy-mm-ddThh:mm:ss e.g., 2022-05-29T12:00:00 2021-01-01T12:00:00
  • GCPTimespan — Date in ISO. e.g. 2022-05-29T12:00:00.123Z 2021-01-01T12:00:00.234Z
  • GCPProjectName — The GCP project name.

Outputs

  • CloudIndicators.arn — The ARN.
  • CloudIndicators.access_key_id — The AWS access key ID.
  • CloudIndicators.resource_name — The resource name.
  • CloudIndicators.source_ip — The source IP.
  • CloudIndicators.username — The username used by the attacker.
  • CloudIndicators.event_name — The name of the event.
  • CloudIndicators.user_agent — The user agent used by the attacker.

Commands used

aws-cloudtrail-lookup-events azure-log-analytics-execute-query gcp-logging-log-entries-list

Flowchart

AWS Azure GCP no yes no yes no yes yes Start Start Select cloud provider Select cloud provider AWS AWS Azure Azure GCP GCP Hunt for Compute Instance persistence activity - azure-log-analytics-execute-query Hunt for Compute Instance... azure-log-analytics-execute-q... Hunt for Compute Function persistence activity - azure-log-analytics-execute-query Hunt for Compute Function... azure-log-analytics-execute-q... Hunt for IAM persistence activity - azure-log-analytics-execute-query Hunt for IAM persistence ... azure-log-analytics-execute-q... Fetch events for specified Access Key ID - aws-cloudtrail-lookup-events Fetch events for specifie... aws-cloudtrail-lookup-events Filter Events Filter Events Hunt for Compute Instance persistence activity - Set Hunt for Compute Instance... Set Hunt for Compute Function persistence activity - Set Hunt for Compute Function... Set Hunt for IAM persistence activity - gcp-logging-log-entries-list Hunt for IAM persistence ... gcp-logging-log-entries-list Hunt for Compute Instance persistence activity - gcp-logging-log-entries-list Hunt for Compute Instance... gcp-logging-log-entries-list Hunt for Compute Function persistence activity - gcp-logging-log-entries-list Hunt for Compute Function... gcp-logging-log-entries-list Extract Indicators Extract Indicators Hunt for IAM persistence activity - Set Hunt for IAM persistence ... Set Is Azure Log Analytics enabled? - IsIntegrationAvailable Is Azure Log Analytics en... IsIntegrationAvailable Is AWS - CloudTrail enabled? - IsIntegrationAvailable Is AWS - CloudTrail enabled? IsIntegrationAvailable Is Google Cloud Logging enabled? - IsIntegrationAvailable Is Google Cloud Logging e... IsIntegrationAvailable Extract indicators - ExtractIndicators-CloudLogging Extract indicators ExtractIndicators-CloudLogging Found results? Found results? Done Done
id: Cloud Threat Hunting - Persistence
version: -1
name: Cloud Threat Hunting - Persistence
description: |-
  ---

  ## Cloud Threat Hunting - Persistence Playbook

  The playbook is responsible for hunting persistence activity in the cloud. It supports AWS, GCP, and Azure - one at a time.

  ### Hunting Queries

  The playbook executes hunting queries for each provider related to each of the following:

  1. IAM
  2. Compute Resources
  3. Compute Functions

  ### Indicator Extraction

  If relevant events are found during the search, indicators will be extracted using the `ExtractIndicators-CloudLogging` script.

  ---
starttaskid: "0"
tasks:
  "0":
    id: "0"
    taskid: d03533f4-d52f-47d8-8c85-1a69c1eef655
    type: start
    task:
      id: d03533f4-d52f-47d8-8c85-1a69c1eef655
      version: -1
      name: ""
      iscommand: false
      brand: ""
      description: ''
    nexttasks:
      '#none#':
      - "1"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": -150
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "1":
    id: "1"
    taskid: a808eff0-094b-4973-8a91-4026a4c2504a
    type: condition
    task:
      id: a808eff0-094b-4973-8a91-4026a4c2504a
      version: -1
      name: Select cloud provider
      description: Checks the cloud provider.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      AWS:
      - "2"
      Azure:
      - "3"
      GCP:
      - "4"
    separatecontext: false
    conditions:
    - label: AWS
      condition:
      - - operator: isEqualString
          left:
            value:
              complex:
                root: inputs.cloudProvider
            iscontext: true
          right:
            value:
              simple: AWS
          ignorecase: true
    - label: Azure
      condition:
      - - operator: isEqualString
          left:
            value:
              complex:
                root: inputs.cloudProvider
            iscontext: true
          right:
            value:
              simple: Azure
          ignorecase: true
    - label: GCP
      condition:
      - - operator: isEqualString
          left:
            value:
              complex:
                root: inputs.cloudProvider
            iscontext: true
          right:
            value:
              simple: GCP
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": -20
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "2":
    id: "2"
    taskid: 2ddf36db-6ccd-4781-8a99-86b69773d5b6
    type: title
    task:
      id: 2ddf36db-6ccd-4781-8a99-86b69773d5b6
      version: -1
      name: AWS
      type: title
      iscommand: false
      brand: ""
      description: ''
    nexttasks:
      '#none#':
      - "19"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": 200
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "3":
    id: "3"
    taskid: a86c9c09-f132-4bcc-80f4-c8acdf62004d
    type: title
    task:
      id: a86c9c09-f132-4bcc-80f4-c8acdf62004d
      version: -1
      name: Azure
      type: title
      iscommand: false
      brand: ""
      description: ''
    nexttasks:
      '#none#':
      - "18"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 910,
          "y": 200
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "4":
    id: "4"
    taskid: 4cfe1349-6619-4d8f-886e-44368d5a1965
    type: title
    task:
      id: 4cfe1349-6619-4d8f-886e-44368d5a1965
      version: -1
      name: GCP
      type: title
      iscommand: false
      brand: ""
      description: ''
    nexttasks:
      '#none#':
      - "20"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": -10,
          "y": 200
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "5":
    id: "5"
    taskid: 75e423b7-0a3b-4857-8546-dfdd66e7ea3d
    type: regular
    task:
      id: 75e423b7-0a3b-4857-8546-dfdd66e7ea3d
      version: -1
      name: Hunt for Compute Instance persistence activity
      description: Executes an analytics query for data.
      tags:
      - PersistenceHunting
      script: '|||azure-log-analytics-execute-query'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "6"
    scriptarguments:
      extend-context:
        simple: CloudPersistence.ComputeInstances=
      ignore-outputs:
        simple: "false"
      query:
        simple: |-
          AzureActivity
          | where OperationNameValue in~ ("microsoft.compute/virtualMachines/write", "microsoft.compute/virtualMachines/extensions/write", "Microsoft.Network/networkSecurityGroups/securityRules/write", "Microsoft.Compute/virtualMachines/runCommand/action") and Caller contains "${inputs.username}"
      timespan:
        complex:
          root: inputs.AzureTimespan
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 910,
          "y": 690
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: true
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "6":
    id: "6"
    taskid: 63c03081-5c05-4ad9-87b8-62265e5f9fbc
    type: regular
    task:
      id: 63c03081-5c05-4ad9-87b8-62265e5f9fbc
      version: -1
      name: Hunt for Compute Function persistence activity
      description: Executes an analytics query for data.
      tags:
      - PersistenceHunting
      script: '|||azure-log-analytics-execute-query'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "16"
    scriptarguments:
      extend-context:
        simple: CloudPersistence.ComputeFunctions=
      ignore-outputs:
        simple: "false"
      query:
        simple: |-
          AzureActivity
          | where OperationNameValue in~ ("Microsoft.Logic/workflows/write", "Microsoft.Logic/workflows/run/action", "Microsoft.Web/sites/Write", "microsoft.web/sites/functions/write", "Microsoft.Automation/automationAccounts/runbooks", "Microsoft.Automation/automationAccounts/jobs/write", "Microsoft.Automation/automationAccounts/runbooks/publish/action", "Microsoft.Automation/automationAccounts/runbooks/draft/write", "Microsoft.Automation/automationAccounts/runbooks/write", "Microsoft.Automation/automationAccounts/Schedules/write") and Caller contains "${inputs.username}"
      timespan:
        complex:
          root: inputs.AzureTimespan
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 910,
          "y": 850
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: true
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "7":
    id: "7"
    taskid: 69fca908-df76-4c2e-8b27-bf2b5f023472
    type: regular
    task:
      id: 69fca908-df76-4c2e-8b27-bf2b5f023472
      version: -1
      name: Hunt for IAM persistence activity
      description: Executes an analytics query for data.
      tags:
      - PersistenceHunting
      script: '|||azure-log-analytics-execute-query'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "5"
    scriptarguments:
      extend-context:
        simple: CloudPersistence.IAM=
      ignore-outputs:
        simple: "false"
      query:
        simple: |-
          AzureActivity
          | where OperationNameValue in~ ("microsoft.directory/users/create", "microsoft.directory/users/enable", "microsoft.directory/users/restore", "microsoft.directory/servicePrincipals/owners/update", "microsoft.directory/servicePrincipals/credentials/update", "microsoft.directory/servicePrincipals/enable", "microsoft.directory/users/password/update", "microsoft.directory/servicePrincipals/create", "microsoft.directory/applications/create", "microsoft.directory/servicePrincipals/create") and Caller contains "${inputs.username}"
      timespan:
        complex:
          root: inputs.AzureTimespan
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 910,
          "y": 530
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: true
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "8":
    id: "8"
    taskid: 2f66656d-24b3-4e62-8ec8-550327cd39d7
    type: regular
    task:
      id: 2f66656d-24b3-4e62-8ec8-550327cd39d7
      version: -1
      name: Fetch events for specified Access Key ID
      description: Looks up API activity events captured by CloudTrail that create, update, or delete resources in your account. Events for a region can be looked up for the times in which you had CloudTrail turned on in that region during the last seven days.
      script: '|||aws-cloudtrail-lookup-events'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "10"
    scriptarguments:
      attributeKey:
        simple: AccessKeyId
      attributeValue:
        complex:
          root: inputs.AWSAccessKeyID
      region:
        complex:
          root: inputs.region
      startTime:
        complex:
          root: inputs.AWSTimespan
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": 530
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "10":
    id: "10"
    taskid: c853705f-8944-4808-8b76-3dac7b1ed7cb
    type: title
    task:
      id: c853705f-8944-4808-8b76-3dac7b1ed7cb
      version: -1
      name: Filter Events
      type: title
      iscommand: false
      brand: ""
      description: ''
    nexttasks:
      '#none#':
      - "17"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": 705
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "11":
    id: "11"
    taskid: 9c0e98a2-33dd-428f-8d30-f73bccd6faa6
    type: regular
    task:
      id: 9c0e98a2-33dd-428f-8d30-f73bccd6faa6
      version: -1
      name: Hunt for Compute Instance persistence activity
      description: Set a value in context under the key you entered.
      tags:
      - PersistenceHunting
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "12"
    scriptarguments:
      key:
        simple: CloudPersistence.ComputeInstances
      value:
        complex:
          root: AWS.CloudTrail.Events
          filters:
          - - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: CreateKeyPair
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: ImportKeyPair
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: RunInstances
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: ModifyInstanceAttributes
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: CreateLaunchTemplate
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: CreateLaunchTemplateVersion
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: CreateSecurityGroup
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: ModifySecurityGroupRules
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: AuthorizeSecurityGroupIngress
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: AuthorizeSecurityGroupEgress
          accessor: CloudTrailEvent
    separatecontext: false
    continueonerror: true
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": 1010
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "12":
    id: "12"
    taskid: ab3c96ec-7c74-4a22-8bc5-06bf2289e9d2
    type: regular
    task:
      id: ab3c96ec-7c74-4a22-8bc5-06bf2289e9d2
      version: -1
      name: Hunt for Compute Function persistence activity
      description: Set a value in context under the key you entered.
      tags:
      - PersistenceHunting
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "16"
    scriptarguments:
      key:
        simple: CloudPersistence.ComputeFunctions
      value:
        complex:
          root: AWS.CloudTrail.Events
          filters:
          - - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: CreateFunction
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: UpdateFunctionCode
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: UpdateFunctionConfiguration
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: InvokeFunction
          accessor: CloudTrailEvent
    separatecontext: false
    continueonerror: true
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": 1170
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "13":
    id: "13"
    taskid: 5fd9b3f4-8d03-498b-85eb-dd47e30a5b2a
    type: regular
    task:
      id: 5fd9b3f4-8d03-498b-85eb-dd47e30a5b2a
      version: -1
      name: Hunt for IAM persistence activity
      description: Lists log entries. Use this method to retrieve log entries that originated from a project/folder/organization/billing account.
      tags:
      - PersistenceHunting
      script: '|||gcp-logging-log-entries-list'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "14"
    scriptarguments:
      extend-context:
        simple: CloudPersistence.IAM=
      filter:
        simple: |-
          log_id("cloudaudit.googleapis.com/activity") AND timestamp>="${inputs.GCPTimespan}" AND
          protoPayload.methodName =("google.iam.admin.v1.EnableServiceAccount" OR "google.iam.admin.v1.CreateServiceAccountKey" OR "google.iam.admin.v1.CreateServiceAccount" OR "google.iam.admin.v1.CreateRole" OR "google.iam.admin.v1.UpdateRole" OR "google.iam.admin.v1.generateAccessToken" OR "google.iam.serviceAccount.setIamPolicy")
      ignore-outputs:
        simple: "false"
      project_name:
        complex:
          root: inputs.GCPProjectName
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": -10,
          "y": 530
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: true
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "14":
    id: "14"
    taskid: 41f44847-b7a4-4361-8354-543d811e607d
    type: regular
    task:
      id: 41f44847-b7a4-4361-8354-543d811e607d
      version: -1
      name: Hunt for Compute Instance persistence activity
      description: Lists log entries. Use this method to retrieve log entries that originated from a project/folder/organization/billing account.
      tags:
      - PersistenceHunting
      script: '|||gcp-logging-log-entries-list'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "15"
    scriptarguments:
      extend-context:
        simple: CloudPersistence.ComputeInstances=
      filter:
        simple: |-
          log_id("cloudaudit.googleapis.com/activity") AND timestamp>="${inputs.GCPTimespan}" AND
          protoPayload.methodName =("compute.v1.instances.insert" OR "compute.v1.instances.setMetadata" OR "compute.v1.disks.insert" OR "compute.v1.instanceTemplates.insert" OR "compute.v1.instanceGroups.insert" OR "compute.v1.firewalls.insert" OR "compute.v1.firewalls.update" OR "compute.v1.firewalls.patch")
      ignore-outputs:
        simple: "false"
      project_name:
        complex:
          root: inputs.GCPProjectName
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": -10,
          "y": 690
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: true
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "15":
    id: "15"
    taskid: 68dade83-92ae-410f-81c5-5e8bcde3a326
    type: regular
    task:
      id: 68dade83-92ae-410f-81c5-5e8bcde3a326
      version: -1
      name: Hunt for Compute Function persistence activity
      description: Lists log entries. Use this method to retrieve log entries that originated from a project/folder/organization/billing account.
      tags:
      - PersistenceHunting
      script: '|||gcp-logging-log-entries-list'
      type: regular
      iscommand: true
      brand: ""
    nexttasks:
      '#none#':
      - "16"
    scriptarguments:
      extend-context:
        simple: CloudPersistence.ComputeFunctions=
      filter:
        simple: |-
          log_id("cloudaudit.googleapis.com/activity") AND timestamp>="${inputs.GCPTimespan}" AND
          protoPayload.methodName =("google.cloud.functions.v1.CloudFunctionsService.CreateFunction" OR "google.cloud.functions.v1.CloudFunctionsService.UpdateFunction")
      ignore-outputs:
        simple: "false"
      project_name:
        complex:
          root: inputs.GCPProjectName
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": -10,
          "y": 850
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: true
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "16":
    id: "16"
    taskid: 6bc4fc6a-b397-46f0-806d-23adb6501bf2
    type: title
    task:
      id: 6bc4fc6a-b397-46f0-806d-23adb6501bf2
      version: -1
      name: Extract Indicators
      type: title
      iscommand: false
      brand: ""
      description: ''
    nexttasks:
      '#none#':
      - "22"
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": 1340
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "17":
    id: "17"
    taskid: d21eb234-f1d8-4195-8a16-08df581b07fb
    type: regular
    task:
      id: d21eb234-f1d8-4195-8a16-08df581b07fb
      version: -1
      name: Hunt for IAM persistence activity
      description: Set a value in context under the key you entered.
      tags:
      - PersistenceHunting
      scriptName: Set
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "11"
    scriptarguments:
      key:
        simple: CloudPersistence.IAM
      value:
        complex:
          root: AWS.CloudTrail.Events
          filters:
          - - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: CreateUser
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: CreateGroup
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: CreatePolicy
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: CreateRole
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: CreateAccessKey
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: UpdateAccessKey
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events
                iscontext: true
              right:
                value:
                  simple: CreateLoginProfile
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events
                iscontext: true
              right:
                value:
                  simple: UpdateLoginProfile
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: AddUserToGroup
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: AttachUserPolicy
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: PutRolePolicy
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: PutUserPolicy
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: PutGroupPolicy
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: UploadSSHPublicKey
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: UpdateAssumeRolePolicy
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: CreateSAMLProvider
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: UpdateSAMLProvider
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: AssumeRole
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: GetSessionToken
              ignorecase: true
            - operator: isEqualString
              left:
                value:
                  simple: AWS.CloudTrail.Events.EventName
                iscontext: true
              right:
                value:
                  simple: GetFederationToken
          accessor: CloudTrailEvent
    separatecontext: false
    continueonerror: true
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": 850
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "18":
    id: "18"
    taskid: 3ad0bbae-58ac-4126-8549-81fe98dda66b
    type: condition
    task:
      id: 3ad0bbae-58ac-4126-8549-81fe98dda66b
      version: -1
      name: Is Azure Log Analytics enabled?
      description: Returns 'yes' if integration brand is available. Otherwise returns 'no'
      scriptName: IsIntegrationAvailable
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      "no":
      - "16"
      "yes":
      - "7"
    scriptarguments:
      brandname:
        simple: Azure Log Analytics
    results:
    - brandInstances
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 910,
          "y": 330
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "19":
    id: "19"
    taskid: e125c6ce-476a-4843-8bf3-30fd60392af6
    type: condition
    task:
      id: e125c6ce-476a-4843-8bf3-30fd60392af6
      version: -1
      name: Is AWS - CloudTrail enabled?
      description: Returns 'yes' if integration brand is available. Otherwise returns 'no'
      scriptName: IsIntegrationAvailable
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      "no":
      - "16"
      "yes":
      - "8"
    scriptarguments:
      brandname:
        simple: AWS - CloudTrail
    results:
    - brandInstances
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": 330
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "20":
    id: "20"
    taskid: dacd33d5-2f56-4237-8dca-8ce5ef5deb0c
    type: condition
    task:
      id: dacd33d5-2f56-4237-8dca-8ce5ef5deb0c
      version: -1
      name: Is Google Cloud Logging enabled?
      description: Returns 'yes' if integration brand is available. Otherwise returns 'no'
      scriptName: IsIntegrationAvailable
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      "no":
      - "16"
      "yes":
      - "13"
    scriptarguments:
      brandname:
        simple: GoogleCloudLogging
    results:
    - brandInstances
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": -10,
          "y": 330
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "21":
    id: "21"
    taskid: 3ba9c741-d7a7-4de6-86ca-159f1b1228af
    type: regular
    task:
      id: 3ba9c741-d7a7-4de6-86ca-159f1b1228af
      version: -1
      name: Extract indicators
      description: This script will extract indicators from a given AWS CloudTrail or GCP Logging event.
      scriptName: ExtractIndicators-CloudLogging
      type: regular
      iscommand: false
      brand: ""
    nexttasks:
      '#none#':
      - "23"
    scriptarguments:
      json_data:
        complex:
          root: CloudPersistence
          accessor: IAM
          transformers:
          - operator: append
            args:
              item:
                value:
                  simple: CloudPersistence.ComputeInstances
                iscontext: true
          - operator: append
            args:
              item:
                value:
                  simple: CloudPersistence.ComputeFunctions
                iscontext: true
    separatecontext: false
    continueonerror: true
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": 1650
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "22":
    id: "22"
    taskid: 015006b4-cdec-4f28-8e37-ab6aebb51851
    type: condition
    task:
      id: 015006b4-cdec-4f28-8e37-ab6aebb51851
      version: -1
      name: Found results?
      description: Checks if any results were received by the threat hunting queries.
      type: condition
      iscommand: false
      brand: ""
    nexttasks:
      '#default#':
      - "23"
      "yes":
      - "21"
    separatecontext: false
    conditions:
    - label: "yes"
      condition:
      - - operator: isNotEmpty
          left:
            value:
              complex:
                root: CloudPersistence
                accessor: IAM
                transformers:
                - operator: append
                  args:
                    item:
                      value:
                        simple: CloudPersistence.ComputeInstances
                      iscontext: true
                - operator: append
                  args:
                    item:
                      value:
                        simple: CloudPersistence.ComputeFunctions
                      iscontext: true
            iscontext: true
          right:
            value: {}
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": 1470
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
  "23":
    id: "23"
    taskid: f4bc71ad-e7ea-4891-8c92-9a2a24ce1525
    type: title
    task:
      id: f4bc71ad-e7ea-4891-8c92-9a2a24ce1525
      version: -1
      name: Done
      type: title
      iscommand: false
      brand: ""
      description: ''
    separatecontext: false
    continueonerrortype: ""
    view: |-
      {
        "position": {
          "x": 450,
          "y": 1810
        }
      }
    note: false
    timertriggers: []
    ignoreworker: false
    skipunavailable: false
    quietmode: 0
    isoversize: false
    isautoswitchedtoquietmode: false
view: |-
  {
    "linkLabelsPosition": {
      "18_16_no": 0.2,
      "18_7_yes": 0.47,
      "19_16_no": 0.17,
      "19_8_yes": 0.44,
      "1_3_Azure": 0.66,
      "1_4_GCP": 0.64,
      "20_13_yes": 0.4,
      "20_16_no": 0.18,
      "22_21_yes": 0.39
    },
    "paper": {
      "dimensions": {
        "height": 2025,
        "width": 1300,
        "x": -10,
        "y": -150
      }
    }
  }
inputs:
- key: cloudProvider
  value: {}
  required: false
  description: |-
    The cloud service provider involved.
    The supported CSPs are AWS, Azure and GCP.
  playbookInputQuery:
- key: AWSAccessKeyID
  value: {}
  required: false
  description: The AWS access key ID.
  playbookInputQuery:
- key: username
  value: {}
  required: false
  description: The username that initiated the API call.
  playbookInputQuery:
- key: region
  value: {}
  required: false
  description: |-
    The region to search for events in.
    e.g. us-east-1, us-west-2, etc.
  playbookInputQuery:
- key: AzureTimespan
  value: {}
  required: false
  description: |-
    The timespan to limit by the hunting query.
    e.g.,
    Use 2d for timespan of 2 days
    Use 1.5h for timespan of 1.5 hour
    Use 30m for timespan of 30 minutes
  playbookInputQuery:
- key: AWSTimespan
  value: {}
  required: false
  description: |-
    Date and time in the following format - yyyy-mm-ddThh:mm:ss
    e.g.,
    2022-05-29T12:00:00
    2021-01-01T12:00:00
  playbookInputQuery:
- key: GCPTimespan
  value: {}
  required: false
  description: |-
    Date in ISO.
    e.g.
    2022-05-29T12:00:00.123Z
    2021-01-01T12:00:00.234Z
  playbookInputQuery:
- key: GCPProjectName
  value: {}
  required: false
  description: The GCP project name.
  playbookInputQuery:
outputs:
- contextPath: CloudIndicators.arn
  description: The ARN.
- contextPath: CloudIndicators.access_key_id
  description: The AWS access key ID.
- contextPath: CloudIndicators.resource_name
  description: The resource name.
- contextPath: CloudIndicators.source_ip
  description: The source IP.
- contextPath: CloudIndicators.username
  description: The username used by the attacker.
- contextPath: CloudIndicators.event_name
  description: The name of the event.
- contextPath: CloudIndicators.user_agent
  description: The user agent used by the attacker.
tests:
- No tests (auto formatted)
fromversion: 6.8.0