Evidence Collection Script for AWS Resources: GuardDuty

1 min read

Introduction

AWS GuardDuty is often enabled in all available regions. In that case, collecting evidence region by region is tedious, so I created the script below.

This script has been confirmed to work only in CloudShell.

Script

#!/bin/bash

# Get a list of all regions
regions=$(aws ec2 describe-regions --query 'Regions[].RegionName' --output text)

for region in $regions; do
    echo -e "\n Region: $region"
    
    # Create folders for each region
    mkdir -p "$region"
    
    # Check whether a GuardDuty detector exists in each region
    detector_ids=$(aws guardduty list-detectors --region $region --query 'DetectorIds[]' --output text)
    
    if [ -z "$detector_ids" ]; then
        echo "GuardDuty is not enabled"
    else
        # Get detector ID
        detector_id=$(echo $detector_ids | cut -f1 -d' ')
        
        # Get detailed information about the detector
        detector=$(aws guardduty get-detector --detector-id $detector_id --region $region)
        
        echo "Detector ID: $detector_id"
        echo "GuardDuty status: $(echo $detector | jq -r '.Status')"
        echo "Findings update frequency: $(echo $detector | jq -r '.FindingPublishingFrequency')"
        echo "Service role: $(echo $detector | jq -r '.ServiceRole')"
        
        # Get trust list and threat list settings
        ip_set_ids=$(aws guardduty list-ip-sets --detector-id $detector_id --region $region --query 'IpSetIds[]' --output text)
        threat_intel_set_ids=$(aws guardduty list-threat-intel-sets --detector-id $detector_id --region $region --query 'ThreatIntelSetIds[]' --output text)
        
        echo "Number of trust lists: $(echo $ip_set_ids | wc -w)"
        echo "Number of threat lists: $(echo $threat_intel_set_ids | wc -w)"

        # Get publishing destination settings
        destination_id=$(aws guardduty list-publishing-destinations --detector-id $detector_id --region $region --query 'Destinations[].DestinationId' --output text)
        publishing_destination=$(aws guardduty describe-publishing-destination --detector-id $detector_id --destination-id $destination_id --region $region)
        
        echo "Publishing destination status: $(echo $publishing_destination | jq -r '.Status')"
        echo "Bucket name: $(echo $publishing_destination | jq -r '.DestinationProperties.DestinationArn')"
        echo "Bucket encryption: $(echo $publishing_destination | jq -r '.DestinationProperties.KmsKeyArn')"

        # Get features
        features=$(echo $detector | jq -r '.Features')
        
        # Get S3 protection status
        s3_protection=$(echo $features | jq -r '.[] | select(.Name == "S3_DATA_EVENTS") | .Status')
        echo "S3 protection status: $s3_protection"
        
        # Get EKS protection status
        eks_protection=$(echo $features | jq -r '.[] | select(.Name == "EKS_AUDIT_LOGS") | .Status')
        echo "EKS protection status: $eks_protection"
        
        # Get runtime monitoring status
        runtime_monitoring=$(echo $features | jq -r '.[] | select(.Name == "RUNTIME_MONITORING") | .Status')
        echo "Runtime monitoring status: $runtime_monitoring"

        # Get Amazon EKS runtime automatic agent state
        eks_auto_agent=$(echo $features | jq -r '.[] | select(.Name == "RUNTIME_MONITORING") | .AdditionalConfiguration[] | select(.Name == "EKS_ADDON_MANAGEMENT") | .Status')
        echo "Amazon EKS runtime automatic agent state: $eks_auto_agent"

        # Get runtime automatic agent state for AWS Fargate (ECS only)
        fargate_auto_agent=$(echo $features | jq -r '.[] | select(.Name == "RUNTIME_MONITORING") | .AdditionalConfiguration[] | select(.Name == "ECS_FARGATE_AGENT_MANAGEMENT") | .Status')
        echo "AWS Fargate (ECS only) runtime automatic agent state: $fargate_auto_agent"

        # Get runtime automatic agent status for GuardDuty Agent Management (EC2)
        ec2_auto_agent=$(echo $features | jq -r '.[] | select(.Name == "RUNTIME_MONITORING") | .AdditionalConfiguration[] | select(.Name == "EC2_AGENT_MANAGEMENT") | .Status')
        echo "GuardDuty Agent Management (EC2) runtime automatic agent state: $ec2_auto_agent"
        
        # Get malware protection status
        malware_protection=$(echo $features | jq -r '.[] | select(.Name == "EBS_MALWARE_PROTECTION") | .Status')
        echo "Malware protection status: $malware_protection"

        # Get malware protection snapshot retention status
        malware_detail=$(aws guardduty get-malware-scan-settings --detector-id $detector_id --region $region)
        malware_snapshot=$(echo $malware_detail | jq -r '.EbsSnapshotPreservation')
        echo "Malware protection snapshot retention status: $malware_snapshot"

        # Get RDS protection status
        rds_protection=$(echo $features | jq -r '.[] | select(.Name == "RDS_LOGIN_EVENTS") | .Status')
        echo "RDS protection status: $rds_protection"

        # Get Lambda protection status
        lambda_protection=$(echo $features | jq -r '.[] | select(.Name == "LAMBDA_NETWORK_LOGS") | .Status')
        echo "Lambda protection status: $lambda_protection"
      	
      	# File output
        echo "$detector" > "$region/get-detector_$region.json"
        echo "$publishing_destination" > "$region/describe-publishing-destination_$region.json"
        echo "$malware_detail" > "$region/get-malware-scan-settings_$region.json"
    fi
done

How to use

Run the script with the command below.

sh get-guardduty.sh

Use redirection if you want to save the script execution log as a file.

sh get-guardduty.sh > get-guardduty.log

Output

The standard output looks like this. You can check the settings at a glance.

Region: ap-south-1
  Detector ID: XXXXXXXXXXXXXXXXXXXXXXXXXXX
  GuardDuty status: ENABLED
  Findings update frequency: FIFTEEN_MINUTES
  Service role: arn:aws:iam::XXXXXXXXXXX:role/aws-service-role/guardduty.amazonaws.com/AWSServiceRoleForAmazonGuardDuty
  Number of trust lists: 0
  Number of threat lists: 0
  Publishing destination status: PUBLISHING
    Bucket name: arn:aws:s3:::XXXXXXXXXXX/Logs/GuardDuty
    Bucket encryption: arn:aws:kms:ap-northeast-1:XXXXXXXXXXX:key/XXXXXXXXXXX
  S3 protection status: ENABLED
  EKS protection status: DISABLED
  Runtime monitoring status: ENABLED
    Amazon EKS runtime automatic agent state: ENABLED
    AWS Fargate (ECS only) runtime automatic agent state: DISABLED
    GuardDuty Agent Management (EC2) runtime automatic agent state: ENABLED
  Malware protection status: DISABLED
    Malware protection snapshot retention status: NO_RETENTION
  RDS protection status: DISABLED
  Lambda protection status: DISABLED

 --- Omitted ---

A directory will be created for each region as shown below.

[cloudshell-user@ip-XX-XXX-XXX-XXX ~]$ ls -l
total 128
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:42 ap-northeast-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:42 ap-northeast-2
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:42 ap-northeast-3
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:41 ap-south-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:43 ap-southeast-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:43 ap-southeast-2
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:42 ca-central-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:43 eu-central-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:41 eu-north-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:42 eu-west-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:41 eu-west-2
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:41 eu-west-3
-rw-r--r--. 1 cloudshell-user cloudshell-user 15129 May 31 07:44 get-guardduty.log
-rw-r--r--. 1 cloudshell-user cloudshell-user  4221 May 31 07:40 get-guardduty.sh
-rw-r--r--. 1 cloudshell-user cloudshell-user 34023 May 31 07:53 get-guardduty.zip
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:42 sa-east-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:43 us-east-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:43 us-east-2
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:43 us-west-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 May 31 07:44 us-west-2
[cloudshell-user@ip-XX-XXX-XXX-XXX ~]$ 

JSON will be saved in the region directory as shown below.

[cloudshell-user@ip-XX-XXX-XXX-XXX ~]$  ls -l ap-northeast-1/
total 12
-rw-r--r--. 1 cloudshell-user cloudshell-user  357 May 31 07:42 describe-publishing-destination_ap-northeast-1.json
-rw-r--r--. 1 cloudshell-user cloudshell-user 3455 May 31 07:42 get-detector_ap-northeast-1.json
-rw-r--r--. 1 cloudshell-user cloudshell-user  132 May 31 07:42 get-malware-scan-settings_ap-northeast-1.json
[cloudshell-user@ip-XX-XXX-XXX-XXX ~]$