ayberk.ninja ayberk.ninja

Managing Security Alarms with Automation in AWS

10 minutes to read

Managing Security Alarms with Automation in AWS

TLDR;

Automated detection of security threats and taking necessary actions are among the most important aspects. As the attack surface expands daily, the number of topics requiring regular monitoring also increases. At this point, it is critical to build, design, and maintain automated systems as well as manual controls and human power. AWS has various security services that allow us to perform some security checks on a regular basis. Using these services more efficiently depends on the architecture we will design depending on the structure of our organization. In this blog post, I will take some security alarms that we think may be harmful in AWS by using AWS’s security services and take automatic actions thanks to Lambda.

What Will We Automate?

What Else Can You Automate?

Detecting and Automating Responses to AWS CloudTrail Deactivation

When attackers gain unauthorized access through the interface or CLI, there are some steps they will take. One of them will be to erase the traces they have left behind. The first method they will try for this will be to deactivate CloudTrail if it is active. In this example, we will check whether CloudTrail is active or not in an automated way and reactivate it if it is deactivated. Of course, the task of activating CloudTrail also falls to our automation.

My goal here is to give you an overview of how you can build mini security automations in AWS, rather than having you do these examples in person.

At the end of the day, our architecture will look like this: AWS CloudTrail Deactivation Automation Architecture

Enable cloudtrail-enabled Rule in AWS Config

First of all, we need to activate the AWS Config service. I skip the part on how to activate AWS Config and continue my article in the scenario where it is already active. We need to check whether CloudTrail is active on AWS Config. For that from the left menu we have to go to Rules and Add Rule. By selecting AWS Managed Rule, we select cloudtrail-enabled or multi-region-cloudtrail-enabled and create our rule.

We could have created the automation for this scenario by listening to CloudTrail calls directly on EventBridge without using AWS Config. I added this step so that you can see different scenarios.

AWS Config cloudtrail-enabled Rule

Automatic Response with Lambda Function

We need the Lambda function to take the automatic action if CloudTrail is deactivated. The code we will write here will be quite simple. Of course, you may need to improve your code depending on the needs of the organization. For this, we will of course create an IAM role, create our Lambda function, and add the IAM code to this Lambda function. (Spoiler: Yes! We will then use EventBridge to trigger the Lambda function).

Before we start creating the Lambda function, we will need to create an IAM role to give the Lambda function the authorizations it needs to make the necessary changes to CloudTrail. You can also use AWS’s IAM Role Generator to create an IAM role.

For this, you must follow these steps on the IAM screen:

Make sure to comply with the least privilege policy when creating a new IAM role. This could prevent further security problems. Here, we will create our authorization instead of authorizing our role such as AdministratorAccess.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudtrail:UpdateTrail",
                "cloudtrail:StartLogging",
                "cloudtrail:DescribeTrails",
                "lambda:InvokeFunction",
                "cloudtrail:GetTrailStatus"
            ],
            "Resource": "*"
        }
    ]
}

You can customize the Policy according to your needs.

Finally we can create our Lambda function. I will create the Lambda function in Python 3.x. You can of course use any other programming language that suits you or that you are comfortable with. Anyway, it is up to you to improve and extend the code here according to your needs. Here is my PoC code:

# Import the required libs
import json
import boto3
import logging
from botocore.exceptions import ClientError

# Making logging settings
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    # Create a client to access the AWS CloudTrail service
    cloudtrail = boto3.client('cloudtrail')
    
    try:
        # Log the incoming event
        logger.info(f"Received event: {json.dumps(event)}")
        # List all CloudTrails in the account
        response = cloudtrail.describe_trails()
        
        # If there is no trail, return an error
        if not response['trailList']:
            logger.warning("No CloudTrail trails found in the account")
            return {
                'statusCode': 404,
                'body': 'No CloudTrail trails found'
            }
        
        # Perform operations for each trail
        for trail in response['trailList']:
            trail_name = trail['Name']
            
            try:
                # Checking the current status of the trail
                status = cloudtrail.get_trail_status(Name=trail_name)
                
                # If logging is closed then do them
                if not status['IsLogging']:
                    logger.info(f"Trail {trail_name} is disabled. Enabling it...")
                    
                    # Activate the Trail
                    cloudtrail.start_logging(Name=trail_name)
                    
                    logger.info(f"Successfully enabled trail: {trail_name}")
                else:
                    logger.info(f"Trail {trail_name} is already enabled")
                    
            except ClientError as e:
                # If an error occurs while activating a trail, we continue with other trails
                logger.error(f"Error processing trail {trail_name}: {str(e)}")
                continue
        
        return {
            'statusCode': 200,
            'body': 'Successfully processed all trails'
        }
        
    except ClientError as e:
        logger.error(f"Error: {str(e)}")
        return {
            'statusCode': 500,
            'body': f"Error: {str(e)}"
        }

Event Triggering with EventBridge

We need to connect the Lambda function to an Event via EventBridge to automatically take action when the case we expect occurs. For this let’s create a new event. While creating our rule, we select the Config Rules Compliance Change option in the Sample event section. As the creation method, we will write our own rule by selecting Custom pattern again. Our rule will be as follows:

For this scenario, we want to trigger the Lambda function we wrote to recognize when a Trail is stopped. We need to create our EventBridge rule as follows:

{
  "source": ["aws.config"],
  "detail-type": ["Config Rules Compliance Change"],
  "detail": {
    "configRuleName": ["cloudtrail-enabled"],
    "newEvaluationResult": {
      "complianceType": ["NON_COMPLIANT"]
    }
  }
}

I can say that the writing format of Event Patterns is very clear and simple. If you have more questions about writing Custom Event Patterns, you can check AWS’s official documentation..

The EventBridge Rule summary we created should look like this: EventBridge Rule Review

That’s all. Now we have a mini automation that will reactivate any of the CloudTrail Trails in case any of them is deactivated. Of course, you can also develop different solutions specific to your organization. For example:

Test

Just deactivate an existing Trail. After a short time, you will see that the Trail has been reactivated. You can also observe your test by following these metrics after deactivating your Trail:

Also after a while you have to see Noncompliant Warning on the AWS Config.

AWS CloudTrail Noncompliant Warning

In fact, we could have triggered our Lambda function by selecting the Create custom Lambda rule option while creating our Config Rule without using EventBridge. I would like to state again that my goal here is to provide you with different perspectives. There are many different ways to create such mini security automations on AWS. Of course, you can create the most suitable architecture according to your needs and by getting to know AWS services.

Last Word

In this blog post, my goal was to give you a perspective on how you can set up mini automations to make your AWS environment more secure. I strongly encourage you to try building the other automations in the “What Else Can You Automate?” section or develop the automations mentioned in this blog post.

Depending on your business needs, the automations you can build will vary and change. The code you write may change and the AWS services you use may change.

If you have any suggestions for the article, please feel free to contact me through any communication channel (Linkedin, Twitter, Threema, etc.). I am constantly updating the articles in line with your feedback.