DEV Community

Cover image for AWS Security Essentials: From Prevention to Detection
vikasbanage for AWS Community Builders

Posted on • Edited on • Originally published at Medium

AWS Security Essentials: From Prevention to Detection

As businesses moves on cloud, ensuring the security of cloud environment is crucial. So monitoring security events is an essential part of maintaining a secure AWS infrastructure.

AWS offers a range of security services like AWS Security Hub, AWS GuardDuty, Amazon Inspector, Amazon Macie etc. designed to help you monitor and respond to security events for your workload and infra.

At the same time, it’s also important to ensure that your security services themselves are always active and functioning correctly.

In this blog, I have outlined how we can monitor AWS security services themselves.

Below architecture explains how we can monitor these services:

security-service-monitoring

  1. I have created EventRule that gets triggered as soon as if any one of the Security services get deactivated/disabled/deleted.
  2. Event rule target is Lambda function, that extract details from corresponding event. Details like username — who disabled service, source ip, timestamp, eventname, eventsource. This will help us in investigation.
  3. Once event is processed by Lambda, lambda publish message to SNS.
  4. With SNS, depending on subscription (Email, SMS, HTTPs) we will get notified. Here we can cofigure any communication channel thats feasible for us. For this blog and demo, I’m using only Email and OpsGenie.

Below Python code shows event processing and SNS publish.

In order find complete CloudFormation stack and code, refer repo :

import json
import boto3
import os

sns = boto3.client('sns')

def handler(event, context):
    detail = event['detail']
    eventName = detail['eventName']
    userType = detail['userIdentity']['type']
    eventSource = detail['eventSource']

    if eventName == 'ConsoleLogin' and userType == 'Root':
        accountId = detail['userIdentity']['accountId']
        timestamp = detail['eventTime']
        sourceIp = detail['sourceIPAddress']
        loginStatus = detail.get('responseElements', {}).get('ConsoleLogin')
        mfaUsed = detail.get('additionalEventData', {}).get('MFAUsed', 'No')

        # Log the event details
        print(f"Root login attempt: AccountId={accountId}, Timestamp={timestamp}, SourceIp={sourceIp}, Status={loginStatus}, MFAUsed={mfaUsed}")
        # Create JSON message
        message = {
            "AccountId": accountId,
            "Timestamp": timestamp,
            "SourceIp": sourceIp,
            "LoginStatus": loginStatus,
            "MFAUsed": mfaUsed,
            "Message": "Root login attempt detected"
        }
        # Publish message to SNS topic
        messageToPublish = json.dumps(message)
        messageHeader = f"Root login attempt detected\nAccountId: {accountId}\nTimestamp: {timestamp}\nSourceIp: {sourceIp}\nStatus: {loginStatus}\nMFAUsed: {mfaUsed}"
        sns.publish(
            TopicArn=f"arn:aws:sns:{os.environ['REGION']}:{os.environ['ACCOUNT_ID']}:SecurityAlarmsTopic",
            Message=messageToPublish,
            Subject=messageHeader
        )

    elif eventName == 'DisableSecurityHub':
        accountId = detail['userIdentity']['accountId']
        timestamp = detail['eventTime']
        sourceIp = detail['sourceIPAddress']
        userid = detail['userIdentity']['sessionContext']['sessionIssuer']['userName']

        # Create JSON message
        message = {
            "AccountId": accountId,
            "Timestamp": timestamp,
            "SourceIp": sourceIp,
            "UserID": userid,
            "EventSource": eventSource,
            "Message": "Security Hub has been Disabled"
        }
        # Publish message to SNS topic
        messageToPublish = json.dumps(message)
        messageHeader = f"Security Hub Disabled for Account: {accountId}"
        sns.publish(
            TopicArn=f"arn:aws:sns:{os.environ['REGION']}:{os.environ['ACCOUNT_ID']}:SecurityAlarmsTopic",
            Message=messageToPublish,
            Subject=messageHeader
        )
      # Alarm - GuardDuty Disable
    elif eventName == 'DeleteDetector' and eventSource == 'guardduty.amazonaws.com':
        accountId = detail['userIdentity']['accountId']
        timestamp = detail['eventTime']
        eventsource = detail['eventSource']
        sourceIp = detail['sourceIPAddress']
        userid = detail['userIdentity']['sessionContext']['sessionIssuer']['userName']

        # Create JSON message
        message = {
            "AccountId": accountId,
            "Timestamp": timestamp,
            "SourceIp": sourceIp,
            "UserID": userid,
            "EventSource": eventSource,
            "Message": "GuardDuty has been Disabled"
        }
        # Publish message to SNS topic
        messageToPublish = json.dumps(message)
        messageHeader = f"GuardDuty Disabled for Account: {accountId}"
        sns.publish(
            TopicArn=f"arn:aws:sns:{os.environ['REGION']}:{os.environ['ACCOUNT_ID']}:SecurityAlarmsTopic",
            Message=messageToPublish,
            Subject=messageHeader
        )

        # Alarm - Inspector Disabled   
    elif eventName == 'Disable' and eventSource == 'inspector2.amazonaws.com':
        accountId = detail['userIdentity']['accountId']
        timestamp = detail['eventTime']
        eventsource = detail['eventSource']
        sourceIp = detail['sourceIPAddress']
        userid = detail['userIdentity']['sessionContext']['sessionIssuer']['userName']

        # Create JSON message
        message = {
            "AccountId": accountId,
            "Timestamp": timestamp,
            "SourceIp": sourceIp,
            "UserID": userid,
            "EventSource": eventSource,
            "Message": "AWS Inspector has been Disabled"
        }
        # Publish message to SNS topic
        messageToPublish = json.dumps(message)
        messageHeader = f"AWS Inspector Disabled for Account: {accountId}"
        sns.publish(
            TopicArn=f"arn:aws:sns:{os.environ['REGION']}:{os.environ['ACCOUNT_ID']}:SecurityAlarmsTopic",
            Message=messageToPublish,
            Subject=messageHeader
        )
        # Alarm - Config Disabled    
    elif eventName == 'DeleteConfigurationRecorder' and eventSource == 'config.amazonaws.com':
        accountId = detail['userIdentity']['accountId']
        timestamp = detail['eventTime']
        eventsource = detail['eventSource']
        sourceIp = detail['sourceIPAddress']
        userid = detail['userIdentity']['sessionContext']['sessionIssuer']['userName']

        # Create JSON message
        message = {
            "AccountId": accountId,
            "Timestamp": timestamp,
            "SourceIp": sourceIp,
            "UserID": userid,
            "EventSource": eventSource,
            "Message": "AWS Config has been Disabled"
        }
        # Publish message to SNS topic
        messageToPublish = json.dumps(message)
        messageHeader = f"AWS Config Disabled for Account: {accountId}"
        sns.publish(
            TopicArn=f"arn:aws:sns:{os.environ['REGION']}:{os.environ['ACCOUNT_ID']}:SecurityAlarmsTopic",
            Message=messageToPublish,
            Subject=messageHeader
        )
Enter fullscreen mode Exit fullscreen mode

We can easily simulate this by publishing below JSON via event bus or you can Enable/Disable this corresponding security service in test environment.

In order simulate, Go to EventBridge → Event Buses → Default event bus → Send Event

With successful simulation, you should able to get notification over channel that you have configured in SNS. In this case, I have configured only Email.

email-notification

In case , if no notification is received :

  1. Make sure SNS subscription have status Confirmed.
  2. Check Cloudwatch logs for lambda function for further error.

If you would like to extend this monitoring for other services, you can update lambda and event rule by referring below table.

Security Service Description CloudTrail Event Source EventName (when disabled)
AWS CloudTrail Tracks API calls and user activity within your AWS account. cloudtrail.amazonaws.com StopLogging
Amazon GuardDuty Threat detection service that continuously monitors for malicious activity. guardduty.amazonaws.com StopMonitoringMembers
Amazon GuardDuty Threat detection service that continuously monitors for malicious activity. guardduty.amazonaws.com DeleteDetector
AWS Config Monitors and records configurations of AWS resources and evaluates resource compliance. config.amazonaws.com StopConfigurationRecorder
AWS Security Hub Provides a comprehensive view of security alerts and security posture across AWS accounts. securityhub.amazonaws.com DisableSecurityHub
AWS Shield Managed DDoS protection service that safeguards applications. shield.amazonaws.com DeleteSubscription
Amazon Macie Uses machine learning to discover, classify, and protect sensitive data. macie2.amazonaws.com DisableMacie
AWS Firewall Manager Centrally configures and manages firewall rules across accounts and applications. fms.amazonaws.com DeletePolicy
AWS IAM Access Analyzer Helps identify resources that are shared with external entities. access-analyzer.amazonaws.com DeleteAnalyzer
Amazon Inspector Automated security assessment service to help improve the security and compliance of applications deployed on AWS. inspector.amazonaws.com DeleteAssessmentTarget
AWS WAF Web application firewall that helps protect web applications from common web exploits. waf.amazonaws.com DeleteWebACL

I hope this blog gave you an idea how we can monitor security services in AWS. Remember to monitor the status of these security monitoring services themselves to ensure continuous protection. Embracing automation further enhances your security posture, ensuring swift and efficient incident response.

Stay proactive, stay secure, and make the most of AWS’s powerful security monitoring capabilities.

Top comments (0)