Lab: Logging GuardDuty Findings to S3

How to export GuardDuty logs to Amazon S3

Already Know Terraform?

Overview

As of this writing, AWS GuardDuty keeps a history of findings from the past 90 days. Most companies will have logging standards to comply with various regulatory and compliance requirements, requiring you to store logs for a designated period, e.g., 1 year. To help comply with this standard, we can export GuardDuty findings to AWS S3 for both long-term storage and for storing more than 90 days' worth of events. Additionally, you may want the findings stored in S3 for ingesting into other platforms such as a SIEM (Security Information and Event Management) platform. Of course, integration specifics will vary by platform.


Deployment

Cost Alert

# clone the AWS Security Cookbook repository
git clone https://github.com/Ty182/AWS-Security-Cookbook-by-Tyler

# navigate to AWS GuardDuty directory
cd AWS_Cookbook_by_Tyler/recipes/aws_guardduty/Lab:Logging_GuardDuty_Findings_to_S3

# initialize the directory and download the required terraform providers
terraform init

# check formatting and validate the syntax is correct
terraform fmt && terraform validate

# check the resources that will be created
terraform plan 

# deploy the resources
terraform apply

Validating Deployment

Once deployed, we can navigate in the AWS Console to GuardDuty > Settingsand under Findings export optionswe should see our S3 bucket set up. Unless there are any errors here, the deployment should be successful.

Guardduty export settings

Generating and Exploring Findings

GuardDuty will automatically detect Kali Linux usage, so I generated some alerts by creating an IAM user, deleting S3 objects, and a bucket from a Kali Linux VM. We may look at this in an upcoming lab, but AWS provides a script that can trigger over 100 GuardDuty alerts.

Reviewing GuardDuty findings

Once you have some findings, head over to your S3 bucket, and you should start to see some findings trickle in. New alerts should pop in within 5 minutes, but you may just want to take a 15-20min break before checking.

Guardduty findings in s3

Download one of the objects to explore more. Please note that these files will contain sensitive data like IP addresses, so I've redacted some information in the output below.

```json
{
    "accountId": "111111111111",
    "arn": "arn:aws:guardduty:us-east-1:111111111111:detector/accb09178fdcb8e9fd6d2f4678727bd0/finding/f0cb095e1b018f0e7d390d373035710a",
    "createdAt": "2025-04-08T00:10:46.659Z",
    "id": "f0cb095e1b018f0e7d390d373035710a",
    "partition": "aws",
    "region": "us-east-1",
    "resource": {
        "accessKeyDetails": {
            "accessKeyId": "AKIA[SNIP]",
            "principalId": "AIDA[SNIP]",
            "userName": "kali",
            "userType": "IAMUser"
        },
        "resourceType": "S3Bucket",
        "s3BucketDetails": [
            {
                "name": "deletemekali-[SNIP]",
                "type": "Destination"
            }
        ]
    },
    "schemaVersion": "2.0",
    "service": {
        "action": {
            "actionType": "AWS_API_CALL",
            "awsApiCallAction": {
                "affectedResources": {},
                "api": "DeleteObject",
                "callerType": "Remote IP",
                "remoteIpDetails": {
                    "city": {
                        "cityName": "[SNIP]"
                    },
                    "country": {
                        "countryName": "United States"
                    },
                    "geoLocation": {
                        "lat": [SNIP],
                        "lon": [SNIP]
                    },
                    "ipAddressV4": "[SNIP]",
                    "organization": {
                        "asn": "[SNIP]",
                        "asnOrg": "[SNIP]",
                        "isp": "[SNIP]",
                        "org": "[SNIP]"
                    }
                },
                "serviceName": "s3.amazonaws.com"
            }
        },
        "additionalInfo": {
            "authenticationMethod": "AuthHeader",
            "value": {
                "authenticationMethod": "AuthHeader"
            },
            "type": "default"
        },
        "archived": false,
        "count": 1,
        "detectorId": "accb09178fdcb8e9fd6d2f4678727bd0",
        "eventFirstSeen": "2025-04-08T00:05:38.000Z",
        "eventLastSeen": "2025-04-08T00:05:38.000Z",
        "resourceRole": "TARGET",
        "serviceName": "guardduty"
    },
    "severity": 5,
    "type": "PenTest:S3/KaliLinux",
    "updatedAt": "2025-04-08T00:10:46.659Z",
    "title": "The API DeleteObject was invoked from a remote host potentially running Kali Linux.",
    "description": "An API was used to access an S3 Bucket from a remote host that is potentially running the Kali Linux penetration testing tool."
}
```

Cleanup

Clean up the resources

Last updated

Was this helpful?