Skip to content

Automated Remediation

Automated Remediation Patterns

Automated remediation with AWS Lambda enables rapid response to security threats by leveraging event-driven workflows. Lambda functions can isolate compromised resources, rotate credentials, or enforce network restrictions in real time, reducing manual intervention and minimizing attack surface. These patterns integrate with AWS Security Hub, CloudWatch, and other services to create a cohesive security posture.


## Isolating Compromised EC2 Instances

Pattern: Use Lambda to automatically stop or terminate EC2 instances flagged by Security Hub.

Workflow:
1. Security Hub detects a compromised instance (e.g., via findings from GuardDuty or Inspector).
2. A CloudWatch Events rule triggers a Lambda function with the instance ID.
3. Lambda uses the EC2 API to stop or terminate the instance.

Example Code:

import boto3
import json

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    instance_id = event['detail']['instance-id']

    try:
        ec2.stop_instances(InstanceIds=[instance_id])
        return {
            'statusCode': 200,
            'body': json.dumps(f'Instance {instance_id} isolated.')
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': json.dumps(f'Error isolating instance: {str(e)}')
        }

Diagram:

[Security Hub Finding] --> [CloudWatch Events] --> [Lambda Function] --> [EC2 API]

Considerations:
- Use IAM roles to grant Lambda access to EC2 and Security Hub.
- Add logging to track isolation actions.


## Rotating Credentials via AWS Secrets Manager

Pattern: Automate credential rotation for databases or applications using Secrets Manager.

Workflow:
1. A Security Hub finding indicates a compromised credential.
2. Lambda retrieves the secret from Secrets Manager, generates a new one, and updates the target service.

Example Code:

import boto3
import os

def lambda_handler(event, context):
    secrets_client = boto3.client('secretsmanager')
    secret_name = os.environ['SECRET_NAME']

    try:
        response = secrets_client.get_secret_value(SecretId=secret_name)
        new_secret = generate_new_secret()  # Custom logic for credential generation
        secrets_client.put_secret_value(SecretId=secret_name, SecretString=new_secret)
        return {
            'statusCode': 200,
            'body': 'Credentials rotated successfully.'
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': f'Error rotating credentials: {str(e)}'
        }

Diagram:

[Security Hub Finding] --> [CloudWatch Events] --> [Lambda Function] --> [Secrets Manager]

Considerations:
- Ensure Lambda has permissions to access Secrets Manager.
- Use IAM roles to restrict secret access.


## Blocking IPs in Security Groups

Pattern: Dynamically block malicious IPs by updating security group rules.

Workflow:
1. A finding identifies a malicious IP address.
2. Lambda adds a deny rule to the security group associated with the target resource.

Example Code:

import boto3

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    security_group_id = event['detail']['security_group_id']  # Extracted from event
    ip_address = event['detail']['ip-source']

    try:
        # Check for existing rules to avoid duplicates
        response = ec2.describe_security_groups(GroupIds=[security_group_id])
        existing_rules = response['SecurityGroups'][0]['IpPermissions']

        # Check if the IP rule already exists
        rule_exists = any(
            any(
                rule['IpRanges'][0]['CidrIp'] == f"{ip_address}/32"
                for rule in group['IpPermissions']
            )
            for group in response['SecurityGroups']
        )

        if not rule_exists:
            ec2.revoke_security_group_ingress(
                GroupId=security_group_id,
                IpPermissions=[
                    {
                        'IpProtocol': 'tcp',
                        'FromPort': 22,
                        'ToPort': 22,
                        'IpRanges': [{'CidrIp': f"{ip_address}/32"}]
                    }
                ]
            )
            return {
                'statusCode': 200,
                'body': f'IP {ip_address} blocked in security group {security_group_id}.'
            }
        else:
            return {
                'statusCode': 400,
                'body': f'IP {ip_address} already exists in security group {security_group_id}.'
            }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': f'Error blocking IP: {str(e)}'
        }

Diagram:

[Security Hub Finding] --> [CloudWatch Events] --> [Lambda Function] --> [EC2 Security Group]

Considerations:
- Use temporary security groups for high-traffic scenarios.
- Monitor for rule conflicts or duplicates.


Key takeaways

  • Automation reduces response time: Lambda enables real-time remediation without manual intervention.
  • Integrate with security services: Use Security Hub findings to trigger Lambda workflows.
  • Prioritize IAM and error handling: Ensure strict permissions and robust logging for secure operations.
  • Scalability: Design workflows to handle large-scale incidents without overwhelming infrastructure.