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 ~]$