Test GuardDuty’s integration with Radiant

Test your AWS integration with a GuardDuty automation script.

To test your AWS integration with Radiant Security, use the provided script to generate sample GuardDuty findings. After running the script, contact your Radiant Security representative to confirm that findings were successfully received from all connected AWS accounts.

The following script is designed to automate the one-time generation of AWS GuardDuty sample findings across multiple AWS accounts and regions. It logs messages and errors, fetches enabled regions, and processes GuardDuty operations by creating sample findings.

Use this guide to understand the script’s components and functionality.

Requirements

Bash script

#!/bin/bash

# Path to the credentials file
CREDENTIALS_FILE="credentials.txt"
# Path to the log file
LOG_FILE="results.log"

# Function to log messages
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Function to log errors
log_error() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: $1" >> "$LOG_FILE"
}

# Function to fetch enabled regions for the organization
fetch_enabled_regions() {
    echo $(aws ec2 describe-regions --query "Regions[*].RegionName" --output text)
}

# Function to process each account's GuardDuty operations
function process_guardduty_for_account() {
    local account_id="$1"
    local key_id="$2"
    local access_key="$3"
    local session_token="$4"
    local region="$5"

    log_message "Processing for Account ID $account_id in region $region..."

    # Fetch the first GuardDuty detector ID in the region
    local output
    output=$(AWS_ACCESS_KEY_ID="$key_id" AWS_SECRET_ACCESS_KEY="$access_key" AWS_SESSION_TOKEN="$session_token" AWS_DEFAULT_REGION="$region" aws guardduty list-detectors --query "DetectorIds[0]" --output text --region "$region" 2>&1)
    local status=$?
    if [ "$status" -ne 0 ]; then
        log_error "Failed to list detectors for Account ID $account_id in region $region: $output"
        return
    elif [ "$output" == "None" ]; then
        log_message "No GuardDuty detectors found for Account ID $account_id in region $region."
        return
    fi

    local detector_id="$output"
    log_message "Generating sample findings for Detector ID $detector_id..."
    output=$(AWS_ACCESS_KEY_ID="$key_id" AWS_SECRET_ACCESS_KEY="$access_key" AWS_SESSION_TOKEN="$session_token" AWS_DEFAULT_REGION="$region" aws guardduty create-sample-findings --detector-id "$detector_id" --finding-types 'UnauthorizedAccess:EC2/SSHBruteForce' --region "$region" 2>&1)
    status=$?
    if [ "$status" -ne 0 ]; then
        log_error "Failed to create sample findings for Account ID $account_id: $output"
    else
        log_message "Sample findings generated for Account ID: $account_id in region $region."
    fi
}

# Main function to initiate processing
function main() {
    log_message "Starting GuardDuty operations..."
    # Assigns the first argument to credentials_path, or defaults to $CREDENTIALS_FILE if not provided.
    local credentials_path="$1"
    if [ -z "$credentials_path" ]; then
        credentials_path="$CREDENTIALS_FILE"
    fi

    # Assigns the second argument to accounts_list, or defaults to all accounts if not provided.
    local accounts_list=(${@:2})

    local enabled_regions=($(fetch_enabled_regions))

    local current_account_id
    local aws_access_key_id
    local aws_secret_access_key
    local aws_session_token

    while IFS= read -r line || [[ -n "$line" ]]; do
        case "$line" in
            \[*\]*)
                # Process the previous account if all data is available
                if [[ -n "$current_account_id" ]]; then
                    if [ ${#accounts_list[@]} -eq 0 ] || [[ " ${accounts_list[*]} " =~ " $current_account_id " ]]; then
                        for region in "${enabled_regions[@]}"; do
                            process_guardduty_for_account "$current_account_id" "$aws_access_key_id" "$aws_secret_access_key" "$aws_session_token" "$region"
                        done
                    fi
                fi
                # Start new account block
                current_account_id=$(echo "$line" | sed -e 's/\[\(.*\)_.*\]/\1/')
                aws_access_key_id=""
                aws_secret_access_key=""
                aws_session_token=""
                ;;
            aws_access_key_id=*)
                aws_access_key_id="${line#*=}"
                ;;
            aws_secret_access_key=*)
                aws_secret_access_key="${line#*=}"
                ;;
            aws_session_token=*)
                aws_session_token="${line#*=}"
                ;;
        esac
    done < "$credentials_path"

    # Process the last account if all data is available
    if [[ -n "$current_account_id" ]] && [ ${#accounts_list[@]} -eq 0 ] || [[ " ${accounts_list[*]} " =~ " $current_account_id " ]]; then
        for region in "${enabled_regions[@]}"; do
            process_guardduty_for_account "$current_account_id" "$aws_access_key_id" "$aws_secret_access_key" "$aws_session_token" "$region"
        done
    fi

    log_message "GuardDuty operations completed."
}

# If no arguments are provided, the script will use the default credentials file and process all accounts.
main "$@"

Script components

Variable

Description

CREDENTIALS_FILE

Path to the credentials file.

LOG_FILE

Path to the log file where all operations will be logged.

Function

Description

log_message()

Logs error messages with a timestamp into the log file.

log_error()

Path to the log file where all operations will be logged.

fetch_enabled_regions()

Returns a list of AWS regions where services are enabled for the organization.

process_guardduty_for_account()

Processes GuardDuty operations for a specific account in a given region using the account's AWS credentials. It fetches the first GuardDuty detector and generates sample findings.

main()

Main function that initiates the processing. It reads the credentials file, determines the list of accounts to process (all or specified ones), and iterates over each account and enabled region to process GuardDuty operations.

Script operation

  1. Logging: The script maintains a detailed log of all operations, including errors, in results.log.

  2. Credentials Handling: The script reads AWS credentials from a specified local file. It expects credentials to be in a specific format, where each account's credentials are separated by headers like [account_id_region]. Consult the example in this guide for more detail.

  3. Region Handling: The script fetches the list of enabled AWS regions and processes each account for those regions.

  4. GuardDuty Processing: For each account and each enabled region, the script attempts to list and create sample findings for GuardDuty detectors.

Configuration

Credentials file

  • Store AWS credentials in credentials.txt by default.

  • The format should be as follows for each account:

    [account_id_1_name]
    aws_access_key_id=YOUR_ACCESS_KEY_1
    aws_secret_access_key=YOUR_SECRET_KEY_1
    aws_session_token=YOUR_SESSION_TOKEN_1
    
    [account_id_2_name]
    aws_access_key_id=YOUR_ACCESS_KEY_2
    aws_secret_access_key=YOUR_SECRET_KEY_2
    aws_session_token=YOUR_SESSION_TOKEN_2

Log File

  • All operations are logged in results.log.

Usage

Run the script by using the following command in the terminal:

./generate_guardduty_findings.sh [credentials_file_path] [account_id1 account_id2 ...]
  • credentials_file_path: Optional. Specify the path to your credentials file. Defaults to credentials.txt.

  • account_id1 account_id2 ...: Optional. Specify the list of account IDs to process. If omitted, the script processes all accounts listed in the credentials file.

Example

To process all accounts with the default credentials file, simply run:

./generate_guardduty_findings.sh

To process specific accounts (e.g., 123456789012 and 987654321098), use:

./generate_guardduty_findings.sh credentials.txt 123456789012 987654321098

Last updated