Cloud-scale forensics requires tools capable of querying billions of log events in minutes. Amazon Athena, Splunk, and OpenSearch each provide this capability with different trade-offs. This article covers practical query patterns for forensic investigation.
Sign in to mark this article as read and track your progress.
A single AWS account with CloudTrail enabled across all regions and services can generate 10–100 million log events per day. A multi-account organisation with CloudTrail, VPC Flow Logs, S3 data events, and Lambda logs generates orders of magnitude more. Manual log analysis is not feasible at this scale.
Forensic investigation tools must be capable of:
Amazon Athena is a serverless SQL query service that analyses data stored in S3. For CloudTrail logs delivered to S3, Athena can query the raw JSON files directly using partition projection for performance.
-- Create external table for CloudTrail logs
CREATE EXTERNAL TABLE cloudtrail_logs (
eventversion STRING,
useridentity STRUCT<
type: STRING,
principalid: STRING,
arn: STRING,
accountid: STRING,
accesskeyid: STRING,
username: STRING,
sessioncontext: STRUCT<
attributes: STRUCT<
mfaauthenticated: STRING,
creationdate: STRING
>
>
>,
eventtime STRING,
eventsource STRING,
eventname STRING,
awsregion STRING,
sourceipaddress STRING,
useragent STRING,
errorcode STRING,
requestparameters STRING,
responseelements STRING,
requestid STRING,
eventid STRING,
resources ARRAY<STRUCT<ARN:STRING,accountId:STRING,type:STRING>>,
eventtype STRING,
apiversion STRING,
recipientaccountid STRING
)
COMMENT 'CloudTrail table'
PARTITIONED BY (region STRING, year STRING, month STRING, day STRING)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://your-cloudtrail-bucket/AWSLogs/ACCOUNTID/CloudTrail/'
TBLPROPERTIES ('classification'='cloudtrail');
1. All actions by a specific IAM access key (compromised key investigation):
SELECT eventtime, eventname, eventsource, awsregion, sourceipaddress
FROM cloudtrail_logs
WHERE useridentity.accesskeyid = 'AKIAIOSFODNN7EXAMPLE'
AND year = '2024' AND month = '07' AND day = '03'
ORDER BY eventtime ASC;
2. All S3 GetObject calls on a specific bucket (data exfiltration investigation):
SELECT eventtime,
useridentity.arn,
json_extract_scalar(requestparameters, '$.key') AS s3_key,
sourceipaddress
FROM cloudtrail_logs
WHERE eventname = 'GetObject'
AND eventsource = 's3.amazonaws.com'
AND json_extract_scalar(requestparameters, '$.bucketName') = 'sensitive-data-bucket'
AND year = '2024' AND month = '07'
ORDER BY eventtime ASC;
3. New IAM users created in the last 7 days (backdoor detection):
SELECT eventtime, useridentity.arn AS created_by,
json_extract_scalar(requestparameters, '$.userName') AS new_user
FROM cloudtrail_logs
WHERE eventname = 'CreateUser'
AND eventtime > to_iso8601(current_timestamp - interval '7' day)
ORDER BY eventtime DESC;
4. AssumeRole events to external accounts (lateral movement investigation):
SELECT eventtime,
useridentity.arn AS caller,
json_extract_scalar(requestparameters, '$.roleArn') AS assumed_role,
sourceipaddress
FROM cloudtrail_logs
WHERE eventname = 'AssumeRole'
AND json_extract_scalar(requestparameters, '$.roleArn')
NOT LIKE '%:123456789012:%' -- substitute your account ID
ORDER BY eventtime ASC;
OpenSearch (formerly Elasticsearch, open-sourced by AWS) provides full-text search and real-time dashboards over log data. AWS OpenSearch Service is the managed version.
For forensic investigations, OpenSearch provides:
| Feature | Forensic Use |
|---|---|
| Kibana/OpenSearch Dashboards | Timeline visualisations, IP frequency plots |
| Alerting | Real-time alerts on forensic patterns as new logs arrive |
| Full-text search | Find specific error messages, usernames, IP addresses across all logs |
| Anomaly detection | ML-based detection of unusual API call volumes or patterns |
| Cross-cluster search | Query logs from multiple OpenSearch domains in one query |
{
"query": {
"bool": {
"must": [
{"term": {"eventName": "ConsoleLogin"}},
{"term": {"responseElements.ConsoleLogin": "Failure"}}
],
"filter": {
"range": {"eventTime": {"gte": "now-1h"}}
}
}
},
"sort": [{"eventTime": "desc"}],
"size": 100
}
Splunk's Search Processing Language (SPL) is widely used in enterprise SOC environments. The Splunk Add-On for AWS enables ingestion of CloudTrail, VPC Flow Logs, GuardDuty, and S3 access logs.
SPL query — detect CloudTrail disabled and re-enabled within 30 minutes:
index=cloudtrail eventName=StopLogging OR eventName=StartLogging
| stats list(eventName) as actions list(_time) as times by userArn
| where mvcount(actions) >= 2
| eval duration_minutes = (mvindex(times, -1) - mvindex(times, 0)) / 60
| where duration_minutes <= 30
This detects a pattern of "disable trail → do something → re-enable trail" that attackers use to hide their API calls.
| Criterion | Athena | OpenSearch | Splunk |
|---|---|---|---|
| Cost model | Pay per query (TB scanned) | Instance-based (EC2) | Licence + ingestion volume |
| Data source | S3 (files) | OpenSearch index (ingested) | Splunk index (ingested) |
| Query language | Standard SQL | DSL / Lucene / PPL | SPL (proprietary) |
| Real-time capability | Near-real-time (log delivery lag) | Real-time (seconds) | Real-time |
| Historical analysis | Excellent (full log history in S3) | Limited by index retention | Limited by licence |
| Forensic use case | Historical investigation | Real-time detection + investigation | Real-time + historical |
| Indian deployment | AWS ap-south-1 native | AWS ap-south-1 | On-premises or BYOL cloud |
For a pure forensic investigation (historical analysis of an already-completed incident), Athena against the raw S3 CloudTrail logs is the most cost-effective and comprehensive tool. For real-time threat hunting during an ongoing incident, OpenSearch or Splunk provides faster results.