gbernat / resilient_fn_AWS

IBM Resilient integration with AWS. Ability to orchestrate with AWS in information gathering activities such as getting data from EC2 Instances or Security Groups, as well as performing actions like stopping/terminating EC2 Instances, creating snapshots, assigning security groups, tagging objects, deleting key pairs and execution of Lambda functions. The use of specific credentials (access keys) in each action is allowed if required.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

fn_aws Functions for IBM Resilient SOAR

Table of Contents


Release Notes

Version Date Notes
1.0.0 02/2021 Initial Release

Overview

Resilient Circuits Components for 'fn_aws'

IBM Resilient integration with AWS. Ability to orchestrate with AWS in information gathering activities such as getting data from EC2 Instances or Security Groups, as well as performing actions like stopping/terminating EC2 Instances, creating snapshots, assigning security groups, tagging objects, deleting key pairs and execution of Lambda functions. The use of specific credentials (access keys) in each action is allowed if required.

Key Features

  • Retrieve comprehensive information about AWS EC2 instances and security groups affected by a security incident.
  • Multiple search criteria, and many objects can be queried at once.
  • Create tags for AWS resources.
  • Ability to create AMI copies of an Instance, and Volume snapshots.
  • Replace the assigned security groups of an instance.
  • Start, Stop, Hibernate o Terminate one or more instances.
  • Delete compromised key pairs.
  • Execute Lambda functions synchronously, whether with input event or not.

Requirements

This app supports the IBM Resilient SOAR Platform and the IBM Cloud Pak for Security.

Resilient platform

The Resilient platform supports two app deployment mechanisms, App Host and integration server.

If deploying to a Resilient platform with an App Host, the requirements are:

  • Resilient platform >= 39.0.6328.
  • The app is in a container-based format (available from the AppExchange as a zip file).

If deploying to a Resilient platform with an integration server, the requirements are:

  • Resilient platform >= 39.0.6328.
  • The app is in the older integration format (available from the AppExchange as a zip file which contains a tar.gz file).
  • Integration server is running resilient_circuits>=30.0.0.
  • If using an API key account, make sure the account provides the following minimum permissions:
    Name Permissions
    Org Data Read
    Function Read

The following Resilient platform guides provide additional information:

  • App Host Deployment Guide: provides installation, configuration, and troubleshooting information, including proxy server settings.
  • Integration Server Guide: provides installation, configuration, and troubleshooting information, including proxy server settings.
  • System Administrator Guide: provides the procedure to install, configure and deploy apps.

The above guides are available on the IBM Knowledge Center at ibm.biz/resilient-docs. On this web page, select your Resilient platform version. On the follow-on page, you can find the App Host Deployment Guide or Integration Server Guide by expanding Resilient Apps in the Table of Contents pane. The System Administrator Guide is available by expanding System Administrator.

Cloud Pak for Security

If you are deploying to IBM Cloud Pak for Security, the requirements are:

  • IBM Cloud Pak for Security >= 1.4.
  • Cloud Pak is configured with an App Host.
  • The app is in a container-based format (available from the AppExchange as a zip file).

The following Cloud Pak guides provide additional information:

  • App Host Deployment Guide: provides installation, configuration, and troubleshooting information, including proxy server settings. From the Table of Contents, select Case Management and Orchestration & Automation > Orchestration and Automation Apps.
  • System Administrator Guide: provides information to install, configure, and deploy apps. From the IBM Cloud Pak for Security Knowledge Center table of contents, select Case Management and Orchestration & Automation > System administrator.

These guides are available on the IBM Knowledge Center at ibm.biz/cp4s-docs. From this web page, select your IBM Cloud Pak for Security version. From the version-specific Knowledge Center page, select Case Management and Orchestration & Automation.

Proxy Server

The app does support a proxy server.


Installation

Install

  • To install or uninstall an App or Integration on the Resilient platform, see the documentation at ibm.biz/resilient-docs.
  • To install or uninstall an App on IBM Cloud Pak for Security, see the documentation at ibm.biz/cp4s-docs and follow the instructions above to navigate to Orchestration and Automation.

App Configuration

The following table provides the settings you need to configure the app. These settings are made in the app.config file. See the documentation discussed in the Requirements section for the procedure.

Config Required Example Description
aws_access_key_id Yes AWS_ACCESS_KEY_ID Default AWS credentials to be used
aws_secret_access_key Yes AWS_SECRET_ACCESS_KEY
[another]_aws_access_key_id No AWS_ACCESS_KEY_ID You can use additional access_key/secret_access_key pairs. Prepend '[another-name]_' to 'aws_access_key_id' and 'aws_secret_access_key' in app.config, and then use '[another-name]' in funtion's field 'aws_access_key_name'
[another]_aws_secret_access_key No AWS_SECRET_ACCESS_KEY
default_region Yes sa-east-1 Default region name to be used when not other explicitly indicated in functions
http_proxy No http://proxy:80 Indicate proxy if necessary
https_proxy No http://proxy:80

Custom Layouts

  • Import the Data Tables and Custom Fields like the screenshot below:


Function - AWS: create tags

Assign Tags to resources. Multiple Tags and resources are allowed. Input multiple resources as: ami-xxx...xxx,i-xxx...xxx. If a tag key already exists, the value is overwritten with the new value.

IAM permissions required:

  • ec2:CreateTags
Inputs:

Name Type Required Example Tooltip
aws_access_key_name text No - OPTIONAL to use different access key than default's. If not present, "aws_access_key_id" and "aws_secret_access_key" pair from app.config are used.
aws_region text No - If not present, "default_region" region from app.config is used
aws_resource_id text Yes - Where multiple values are allowed, enter them separated by commas
aws_tag_names text Yes "[{'Key': 'First_Tag', 'Value': 'First Value'}, {'Key': 'Second_Tag', 'Value': 'Second Value'}]" -

Outputs:

results = {'success': True} 

Example Pre-Process Script:

inputs.aws_resource_id = artifact.value
inputs.aws_region = 'sa-east-1'

inputs.aws_tag_names = "[{ 'Key': 'source', 'Value': 'Resilient' }, { 'Key': 'security_posture', 'Value': 'quarantine' }]"

Example Post-Process Script:

incident.addNote('Tags created')


Function - AWS: Lambda invoke function

Invokes synchronously a Lambda function.
If the function expects an input event, enter it as json in 'aws_lamdba_payload' input field.
If your Lambda function has logs output, the content of 'LogResult' of the lambda API invoke is return in results, otherwise it is return the entire response of the API for you to decide wich information is relevant (see API documentation: invoke)

IAM permissions required:

  • lambda:InvokeFunction
Inputs:

Name Type Required Example Tooltip
aws_access_key_name text No - OPTIONAL to use different access key than default's. If not present, "aws_access_key_id" and "aws_secret_access_key" pair from app.config are used.
aws_lambda_function_name text Yes - The lambda function name to invoke
aws_lambda_payload text No - The JSON that you want to provide to your Lambda function as input
aws_region text No - If not present, "default_region" region from app.config is used

Outputs:

results = {
    "success": True,
    "lambdaResult": "START RequestId: xx..xx Version: $LATEST\n
    Received event: {}\n
    ...
    lambda funcion output
    ...
    END RequestId: xx..xx\n
    REPORT RequestId: xx..xx\tDuration: 3051.58 ms\tBilled Duration: 3052 ms\t
    Memory Size: 1024 MB\tMax Memory Used: 100 MB\tInit Duration: 585.11 ms\t\n"
}

Example Pre-Process Script:

inputs.aws_lambda_function_name = 'my-lambda-function'
inputs.aws_lambda_payload = '{"key1":"value1","key2":"value2"}'

Example Post-Process Script:

incident.addNote(str(results.lambdaResult))


Function - AWS: EC2 change instance status

A function to change the state of one or more instances. If hibernate is selected but the instances cannot hibernate successfully, a normal shutdown occurs. Terminate instances is also allowed (use with extremely careful).

IAM permissions required:

  • ec2:StopInstances
  • ec2:TerminateInstances
  • ec2:StartInstances
Inputs:

Name Type Required Example Tooltip
aws_access_key_name text No - OPTIONAL to use different access key than default's. If not present, "aws_access_key_id" and "aws_secret_access_key" pair from app.config are used.
aws_instance_status select Yes hibernate / stop / start / terminate -
aws_region text No - If not present, "default_region" region from app.config is used
aws_resource_id text Yes - Where multiple values are allowed, enter them separated by commas

Outputs:

results = {
    "success": True,
    "statusInstances": {
        "StoppingInstances": [
            {
                "CurrentState": {
                    "Code": 64,
                    "Name": "stopping"
                },
                "InstanceId": "",
                "PreviousState": {
                    "Code": 16,
                    "Name": "running"
                }
            }
        ],
        "ResponseMetadata": {
            "RequestId": "",
            "HTTPStatusCode": 200,
            "HTTPHeaders": {
                "x-amzn-requestid": "",
                "cache-control": "",
                "strict-transport-security": "",
                "content-type": "",
                "content-length": "",
                "date": "",
                "server": ""
            },
            "RetryAttempts": 0
        }
    }
}

Example Pre-Process Script:

inputs.aws_resource_id = artifact.value
inputs.aws_instance_status = 'stop'

Example Post-Process Script:

if results.success:
  incident.addNote('Status change results: {}'.format(str(results.statusInstances)))
  


Function - AWS: EC2 describe Security Group

Gets the information of one o more Security Group listed in aws_resource_id. Searching by Security Group Id is default. Other options are available by changing aws_security_group_filter_name.

IAM permissions required:

  • ec2:DescribeSecurityGroups
Inputs:

Name Type Required Example Tooltip
aws_access_key_name text No - OPTIONAL to use different access key than default's. If not present, "aws_access_key_id" and "aws_secret_access_key" pair from app.config are used.
aws_region text No - If not present, "default_region" region from app.config is used
aws_resource_id text Yes - Where multiple values are allowed, enter them separated by commas
aws_security_group_filter_name select No vpc-id / group-id / group-name Criteria for searching security groups

Outputs:

results = {
    "success": True,
    "securityGroups": [
        {
            "Description": "",
            "GroupName": "",
            "IpPermissions": [
                {
                    "FromPort": ,
                    "IpProtocol": "",
                    "IpRanges": [
                        {
                            "CidrIp": ""
                        }
                    ],
                    "Ipv6Ranges": [],
                    "PrefixListIds": [],
                    "ToPort": ,
                    "UserIdGroupPairs": []
                }
            ],
            "OwnerId": "",
            "GroupId": "",
            "IpPermissionsEgress": [
                {
                    "IpProtocol": "",
                    "IpRanges": [
                        {
                            "CidrIp": ""
                        }
                    ],
                    "Ipv6Ranges": [],
                    "PrefixListIds": [],
                    "UserIdGroupPairs": []
                }
            ],
            "VpcId": ""
        }
    ]
}

Example Pre-Process Script:

vpc = workflow.properties.instance_data.reservations[0]['Instances'][0]['VpcId']


inputs.aws_security_group_filter_name = 'vpc-id'
inputs.aws_resource_id = vpc

Example Post-Process Script:

# Processing if the function is a success
if(results.success):
  sgs = results['securityGroups']
  
  for inst in sgs:
    # Add Row
    row = incident.addRow("aws_security_groups")
    
    row["groupname"] = inst["GroupName"]
    row["sgdescription"] = inst["Description"]
    row["sgownerid"] = inst["OwnerId"]
    row["sggroupid"] = inst["GroupId"]
    row["vpcid"] = inst["VpcId"]


Function - AWS: EC2 modify security groups

Replaces the Security Groups assigned to the Instance for those described in aws_security_groups (can be a list of security group Ids separated by comma)

IAM permissions required:

  • ec2:ModifyInstanceAttribute
Inputs:

Name Type Required Example Tooltip
aws_access_key_name text No - OPTIONAL to use different access key than default's. If not present, "aws_access_key_id" and "aws_secret_access_key" pair from app.config are used.
aws_region text No - If not present, "default_region" region from app.config is used
aws_resource_id text Yes - Where multiple values are allowed, enter them separated by commas
aws_security_groups text Yes sg-03..bc,sg-01..bb List of security groups Ids separated by comma to set in the Instance

Outputs:

results = {
    "success": True
}

Example Pre-Process Script:

inputs.aws_resource_id = artifact.value
inputs.aws_security_groups = 'sg-032bea0e7926abfbc,sg-01e6a74a8527336bb'

Example Post-Process Script:

if results.success:
  incident.addNote('Security Groups for Instance: {} were successfully changed.'.format(artifact.value))


Function - AWS: EC2 create snapshot

Creates a volume snapshot if aws_resource_id is a Volume (vol-xxx..xxx), or creates a complete image if it is an Instance Id (i-xxx...xxx)

IAM permissions required:

  • ec2:CreateSnapshot
  • ec2:CreateImage
Inputs:

Name Type Required Example Tooltip
aws_access_key_name text No - OPTIONAL to use different access key than default's. If not present, "aws_access_key_id" and "aws_secret_access_key" pair from app.config are used.
aws_region text No - If not present, "default_region" region from app.config is used
aws_resource_id text Yes For Volume snapshot enter: vol-xx..xx. To create AMI from Instance enter: i-xx..xx Where multiple values are allowed, enter them separated by commas

Outputs:

results = {'success': True, 'snapshotId': 'ami-xx..xx'}

Example Pre-Process Script:

inputs.aws_resource_id = artifact.value

Example Post-Process Script:

if results.success:
  incident.addNote('AMI from {} successfully created: {}'.format(artifact.value, results.snapshotId))


Function - AWS: EC2 describe Instance

Gets the information of one o more Instance listed in aws_resource_id. Searching by Instance Id is default. If 'image-id' is selected in aws_instances_filter_name, and one or more AMI id is entered, the output includes Instance information related to that AMI Id.

IAM permissions required:

  • ec2:DescribeInstances
Inputs:

Name Type Required Example Tooltip
aws_access_key_name text No - OPTIONAL to use different access key than default's. If not present, "aws_access_key_id" and "aws_secret_access_key" pair from app.config are used.
aws_instances_filter_name select No - Criteria for searching instances
aws_region text No - If not present, "default_region" region from app.config is used
aws_resource_id text Yes - Where multiple values are allowed, enter them separated by commas

Outputs:

results = {
    "success": True,
    "reservations": [
        {
            "Groups": [],
            "Instances": [
                {
                    "AmiLaunchIndex": 0,
                    "ImageId": "",
                    "InstanceId": "",
                    "InstanceType": "",
                    "KeyName": "",
                    "LaunchTime": "",
                    "Monitoring": {
                        "State": ""
                    },
                    "Placement": {
                        "AvailabilityZone": "",
                        "GroupName": "",
                        "Tenancy": ""
                    },
                    "PrivateDnsName": "",
                    "PrivateIpAddress": "",
                    "ProductCodes": [],
                    "PublicDnsName": "",
                    "State": {
                        "Code": 80,
                        "Name": ""
                    },
                    "StateTransitionReason": "",
                    "SubnetId": "",
                    "VpcId": "",
                    "Architecture": "",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "",
                            "Ebs": {
                                "AttachTime": "",
                                "DeleteOnTermination": ,
                                "Status": "",
                                "VolumeId": ""
                            }
                        }
                    ],
                    "ClientToken": "",
                    "EbsOptimized": ,
                    "EnaSupport": ,
                    "Hypervisor": "",
                    "NetworkInterfaces": [
                        {
                            "Attachment": {
                                "AttachTime": "",
                                "AttachmentId": "",
                                "DeleteOnTermination": ,
                                "DeviceIndex": 0,
                                "Status": ""
                            },
                            "Description": "",
                            "Groups": [
                                {
                                    "GroupName": "",
                                    "GroupId": ""
                                }
                            ],
                            "Ipv6Addresses": [],
                            "MacAddress": "",
                            "NetworkInterfaceId": "",
                            "OwnerId": "",
                            "PrivateDnsName": "",
                            "PrivateIpAddress": "",
                            "PrivateIpAddresses": [
                                {
                                    "Primary": ,
                                    "PrivateDnsName": "",
                                    "PrivateIpAddress": ""
                                }
                            ],
                            "SourceDestCheck": ,
                            "Status": "",
                            "SubnetId": "",
                            "VpcId": "",
                            "InterfaceType": ""
                        }
                    ],
                    "RootDeviceName": "",
                    "RootDeviceType": "",
                    "SecurityGroups": [
                        {
                            "GroupName": "",
                            "GroupId": ""
                        }
                    ],
                    "SourceDestCheck": ,
                    "StateReason": {
                        "Code": "",
                        "Message": ""
                    },
                    "Tags": [
                        {
                            "Key": "",
                            "Value": ""
                        }
                    ],
                    "VirtualizationType": "",
                    "CpuOptions": {
                        "CoreCount": 1,
                        "ThreadsPerCore": 1
                    },
                    "CapacityReservationSpecification": {
                        "CapacityReservationPreference": ""
                    },
                    "HibernationOptions": {
                        "Configured": 
                    },
                    "MetadataOptions": {
                        "State": "",
                        "HttpTokens": "",
                        "HttpPutResponseHopLimit": 1,
                        "HttpEndpoint": ""
                    },
                    "EnclaveOptions": {
                        "Enabled": 
                    }
                }
            ],
            "OwnerId": "",
            "ReservationId": ""
        }
    ]
}

Example Pre-Process Script:

inputs.aws_resource_id = artifact.value
inputs.aws_region = 'sa-east-1'

Example Post-Process Script:

# Processing if the function is a success
if(results.success):
  reservations = results.reservations
  
  for rsv in reservations:
    instances = rsv['Instances']
  
    for inst in instances:
      # Add Row
      row = incident.addRow("aws_instances")
      row["instanceid"] = inst["InstanceId"]
      row["imageid"] = inst["ImageId"]
      row["instancetype"] = inst["InstanceType"]
      row["keyname"] = inst["KeyName"]
      row["launchtime"] = inst["LaunchTime"]
      row["availabilityzone"] = inst["Placement"]["AvailabilityZone"]
      row["privatednsname"] = inst["PrivateDnsName"]
      row["publicdnsname"] = inst["PublicDnsName"]
      row["instance_state"] = inst["State"]["Name"]
      row["vpcid"] = inst["VpcId"]
      row["securitygroups"] = ('\n'.join(list(map(lambda x : x['GroupName']+' ('+x['GroupId']+')', inst["SecurityGroups"]))) if "SecurityGroups" in inst.keys() else '')
      row["instance_tags"] = ('\n'.join(list(map(lambda x : x['Key']+': '+x['Value'], inst["Tags"]))) if "Tags" in inst.keys() else '')


Function - AWS: delete key pair

Deletes the specified key pair, by removing the public key from Amazon EC2. Use with extremely careful.
The output shows the status prior to deletion.

IAM permissions required:

  • ec2:DeleteKeyPair
  • ec2:DescribeKeyPairs
Inputs:

Name Type Required Example Tooltip
aws_access_key_name text No - OPTIONAL to use different access key than default's. If not present, "aws_access_key_id" and "aws_secret_access_key" pair from app.config are used.
aws_key_name text Yes frontend_dev key name
aws_region text No - If not present, "default_region" region from app.config is used

Outputs:

results = {
    "success": True,
    "deletedKeyPair": {
        "KeyPairId": "key-xx..xx",
        "KeyFingerprint": "57:::::::::::::::::::52",
        "KeyName": "frontend_dev",
        "Tags": [
            {
                "Key": "origin",
                "Value": "resilient"
            }
        ]
    }
}


Data Table - AWS Instances

API Name:

aws_instances

Columns:

Column Name API Access Name Type
AvailabilityZone availabilityzone text
ImageId imageid text
State instance_state text
InstanceId instanceid text
InstanceType instancetype text
KeyName keyname text
LaunchTime launchtime text
PrivateDnsName privatednsname text
PublicDnsName publicdnsname text
SecurityGroups securitygroups textarea
Tags instance_tags textarea
VpcId vpcid text

Data Table - AWS Security Groups

API Name:

aws_security_groups

Columns:

Column Name API Access Name Type
GroupName groupname text
Description sgdescription text
GroupId sggroupid text
OwnerID sgownerid text
VpcId vpcid text

Custom Artifact Types

Display Name API Access Name
AWS Instance ID aws_instance_id

Rules

Rule Name Object Workflow Triggered
Example: AWS Describe instance artifact example_aws_describe_instance
Example: AWS Describe Security Groups artifact example_aws_describe_security_groups
Example: AWS Take an AMI snapshot and Terminate artifact example_aws_take_an_ami_snapshot_and_terminate
Example: AWS Invoke lambda function incident example_aws_invoke_lamba_function
Example: AWS Change Security Groups artifact example_aws_change_security_groups
Example: AWS Tag instance artifact example_aws_tag_instance_as_quarantined

Troubleshooting & Support

Refer to the documentation listed in the Requirements section for troubleshooting information.

For Support

This is a IBM Community provided App. Please search the Community https://ibm.biz/resilientcommunity for assistance.

About

IBM Resilient integration with AWS. Ability to orchestrate with AWS in information gathering activities such as getting data from EC2 Instances or Security Groups, as well as performing actions like stopping/terminating EC2 Instances, creating snapshots, assigning security groups, tagging objects, deleting key pairs and execution of Lambda functions. The use of specific credentials (access keys) in each action is allowed if required.

License:MIT License


Languages

Language:Python 98.1%Language:Dockerfile 1.5%Language:Shell 0.4%