Python | Lambda Function to Track Open Security Group in AWS

Lambda Function to track open security group in was


What is an Open Security Group in AWS? 

AWS is one of the most popular and broadly adopted Cloud Services Providers which provide over 200 featured services. When we try to launch an EC2 Instance (virtual machine) in AWS, we have to provide various configurations for our server. One of those configurations is Security Group which is used to provide the traffic Inbound & Outbound on the server through TCP ports. An Open Security Group denotes that any port is configured to be accessible from anywhere in the world (0.0.0.0/0). This needs to be tracked and removed as it makes our server vulnerable to outside attacks by exposing it to the world.

Today's Agenda

In this post, we will learn how to keep a track of all the Open Security Groups in an AWS Region. This blog will provide you with 2 approaches to keep track.
  1. To check already existing security groups with such Vulnerability in the AWS Region we are working on.
  2. To track an Open Security Group Vulnerability and send an alert as soon as it is created by someone in AWS.
You can also read Lambda Function on Docker Container Image in AWS.

Prerequisite

This post has been prepared for the audience who : 
  1. You should have an AWS account with access to create a Lambda Function and IAM Role.
  2. Have basic hands-on on Python Scripting language.
  3. And finally, are eager to learn and try something new.

Let's get started

Step 1: Create a new Lambda Function with required permissions and config.

Go to AWS home page > Services > Compute > Lambda.

Create a new Lambda Function with Python 3.x version and new basic Lambda permissions Role.

Lambda Function to Track Open Security Group in AWS


Configure that Lambda Function to use 256MB of RAM and 5 minutes timeout (can be adjusted according to your project resources).

Lambda Function to Track Open Security Group in AWS


Add the below-mentioned policies to the new Role created by lambda.

arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess

     arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess


Step 2 : 
            A.    Add this Static Code that will do the job.

NOTE:

  • This snippet will track all the existing Security Groups that are Open, i. e. mentioned in Agenda 1.
  • If you just want to get a List of existing vulnerabilities, you need not to follow the rest of the steps after this.

Add below mentioned code to lambda_function.py file and save the file.
(Change the AWS Region that you are working in line 5).
import boto3
from botocore.vendored import requests
import json
Client = boto3.resource('ec2')
client = boto3.client('ec2', region_name='eu-central-1')
def lambda_handler(event, context):
    count = 0
    sgs=client.describe_security_groups()["SecurityGroups"]
    for sg in sgs:
     
        sg_details = Client.SecurityGroup(sg["GroupId"])
        if '0.0.0.0/0' in str(sg_details.ip_permissions):
            count=count+1
            print ("SecurityGroupId:", sg["GroupId"], "SecurityGroupName:", sg["GroupName"])
            response = client.describe_network_interfaces(Filters=[
                {
                    'Name': 'group-id',
                    'Values': [
                        sg["GroupId"],
                    ]
                },
            ])
            if (len(response['NetworkInterfaces']) > 0):
                if 'InstanceId' in response['NetworkInterfaces'][0]['Attachment'].keys():
                    print("InstanceId is:", response['NetworkInterfaces'][0]['Attachment']['InstanceId'])
                    print("***********************************")
                       
                else:
                    print("Resource associated:", response['NetworkInterfaces'][0]['Attachment']['InstanceOwnerId'], "Resource description:", response['NetworkInterfaces'][0]['Description'])
                    print("***********************************")
                   
            else:
                #print("This Security Group is Not associated with any resource yet!")
                print ("No information found for this Security Group!")
                print("***********************************")
                   
    print ("Total Vulnerabilities Found: ", count)

Step 2 :
             B.    Add this Dynamic Code that will do the job.

NOTE:

  • This snippet will track an Open Security Group Vulnerability and send an alert as soon as it is created by someone in AWS, i. e. mentioned in Agenda 2.
  • If you just want to follow this approach, you must follow the rest of the steps after this.
Add below mentioned code to lambda_function.py file and save the file.
(This code sends the report to a slack channel, you can either replace the url and token with your values in line 52 or use SNS topics as well).
import boto3
from botocore.vendored import requests
import json
client1 = boto3.client('ec2')
def lambda_handler(event, context):
   
    security_groupId = event['detail']['requestParameters']['groupId']
    cidr_string = str(event['detail']['requestParameters']['ipPermissions'])
    if '0.0.0.0/0' in cidr_string:
       
        response = client1.describe_security_groups(Filters=[
            {
                'Name': 'group-id',
                'Values': [
                    security_groupId,
                ]
            },
        ])
        print(response)
        SecurityGroupName = response['SecurityGroups'][0]['GroupName']
        OwnerId = response['SecurityGroups'][0]['OwnerId']
        VPC_Id = response['SecurityGroups'][0]['VpcId']
       
        message = "Open Security Group Found in AWS:\n"+"Security GroupName: "+SecurityGroupName+"\nSecurity GroupId: "+security_groupId+"\nVPC Id: "+VPC_Id+"\nOwner Id: "+OwnerId
       
        response = client1.describe_network_interfaces(Filters=[
            {
                'Name': 'group-id',
                'Values': [
                    security_groupId,
                ]
            },
        ])
        print(response)
        if (len(response['NetworkInterfaces']) > 0):
            if 'InstanceId' in response['NetworkInterfaces'][0]['Attachment'].keys():
                print("InstanceId is:", response['NetworkInterfaces'][0]['Attachment']['InstanceId'])
                InstanceId = response['NetworkInterfaces'][0]['Attachment']['InstanceId']
                message = message+"\nInstance Id (using this Security Group): "+InstanceId
                   
            else:
                print("Resource associated:", response['NetworkInterfaces'][0]['Attachment']['InstanceOwnerId'])
                print("Resource description:", response['NetworkInterfaces'][0]['Description'])
                ResourceAssociated = response['NetworkInterfaces'][0]['Attachment']['InstanceOwnerId']
                ResourceDescription = response['NetworkInterfaces'][0]['Description']
                message = message+"\nResource Associated: "+ResourceAssociated+"\nResource Description: "+ResourceDescription
                   
        else:
            print("This Security Group is Not associated with any resource yet!")
            message = message+"\nThis Security Group is not associated with any resource yet!"
           
        webhook_url = 'https://hooks.slack.com/services/<slack-webhook-url>/<webhook token>'
        slack_message = {'text':message}
        requests.post(webhook_url,data=json.dumps(slack_message))
   
    else:
        print("Everything seems to be fine!")

Step 3: Create and Add Cloudwatch Trigger to Lambda (Required only if you with Agenda 2).

Create a Rule in Cloudwatch Events that will be used as Trigger.
{
    "source": [
        "aws.ec2"
    ],
    "detail-type": [
        "track open permissions in sg"
    ],
    "detail": {
        "eventSource": [
            "ec2.amazonaws.com"
        ],
        "eventName": [
            "AuthorizeSecurityGroupEgress",
            "AuthorizeSecurityGroupIngress",
            "DescribeSecurityGroups",
            "RevokeSecurityGroupIngress",
            "CreateSecurityGroup"
        ]
    }
}
In this side, you should see an option to add a Trigger that will be used as Target for above Rule. Select you Lambda Function there and click on Configure details button at the bottom.

Lambda Function to Track Open Security Group in AWS

Now, you should see that a Trigger has been added to your Lambda Function.

Lambda Function to Track Open Security Group in AWS

Thats all, You did a great job !!
Now you can test this function by creating a new Security Group with Open permissions.

If you face any issues of need any suggestions, please comment down below and hit the like button to appreciate the efforts.

Further readings
You can also read Lambda Function on Docker Container Image in AWS.






Comments