ATT&CK Threat Hunting study materials
ATT&CK Threat Hunting study resources

Answering an S3 Question with CloudTrail That Cannot Answer It

ATT&CK Threat Hunting · Put your knowledge to work in context.

All case studies

Answering an S3 Question with CloudTrail That Cannot Answer It

GuardDuty raised UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS nine days ago against a role used by a Lambda function. You must answer one question: did anyone read S3 objects using that role's credentials? Environment: 42 AWS accounts under an Organizations trail sending management events to a central bucket in the log-archive account, S3 data events enabled on three buckets only, VPC flow logs only for the production VPC with 14-day retention, no Route 53 resolver logs, EDR not deployed on Fargate or Lambda, and a 30-day hot tier in the SIEM. Wrinkles: CloudTrail was disabled in two accounts for six hours during a maintenance window; one account's trail delivers to a separate bucket the SIEM does not ingest; and the SIEM's field mapping for userIdentity.sessionContext.sessionIssuer.userName is null for assumed-role events, so role sessions collapse into one principal.

1. Is the question answerable? Enumerate the specific gaps and classify the answer as yes, no, or partially.

Read the worked answer

Partially, and the difference matters. Reads are only logged as data events on the three instrumented buckets; a GetObject against any other bucket in 42 accounts leaves no CloudTrail record. So a definitive negative is impossible for the estate, and any 'no evidence of data access' statement must be scoped to those three buckets plus whatever S3 server access logs exist.

The specific gaps:

  • Data-event blind spot. Roughly the entire S3 footprint outside three buckets.
  • Trail outage. Six hours in two accounts where 'no events' and 'no logging' are indistinguishable. Get the maintenance change record and the stop/start times before drawing conclusions.
  • Ingestion break. One account's trail goes to a bucket the SIEM does not read - query that bucket directly in Athena or via the console.
  • Identity collapse. With sessionIssuer.userName null, every assumed-role session for that role looks like one principal, so you cannot tell a Lambda invocation from an external attacker session on identity alone. Pivot to source IP address, user agent, and the role-session name in the ARN.
  • Retention mismatch. Fourteen-day flow logs against a nine-day-old finding is workable now but expires within five days - copy them out today.

Say plainly which conclusions are supported and which are not.

2. Which queries do you run in the first two hours, and what does each prove or fail to prove?

Read the worked answer

Run in parallel, ordered by what can prove the most.

  1. AssumeRole chain for the role, 21 days back. eventName in AssumeRole, AssumeRoleWithWebIdentity, GetSessionToken; group by sourceIPAddress, userAgent, and role session name. Proves: whether the credential was minted from inside AWS or externally, and whether an unusual ASN or user agent appears. Fails to prove: anything about what was done with the session.
  2. Management-plane reconnaissance. GetCallerIdentity, ListBuckets, DescribeInstances, GetBucketAcl across the org. Proves: actor presence and possibly intent. Fails to prove: data access.
  3. GetObject on the three instrumented buckets, filtered by the role's ARN and by the suspicious source IPs from query 1. This is the only query that can produce a positive data-access finding.
  4. S3 server access logs, if any bucket has them enabled - check this first, because a bucket with access logging gives you the coverage the data events do not.
  5. GuardDuty finding detail and any related findings across the org, plus the 14-day VPC flow logs for connections to the S3 prefix list or gateway endpoint, which show volume even without object names.

Write down after each query what a null result means. For query 3, a null result means 'no reads on three buckets', not 'no reads'.

3. Which data-quality findings do you file, and what validation would have caught the identity-mapping defect before an incident?

Read the worked answer

Findings to file, each with an owner and a due date:

  • Trail coverage gap of six hours in two accounts, with no alert on StopLogging or DeleteTrail.
  • One account's trail is not ingested by the SIEM - an ingestion gap that would have been invisible until someone queried that account.
  • Null sessionIssuer.userName for assumed-role events, making role sessions unattributable.
  • S3 data events enabled on three buckets out of the estate's full footprint, with no inventory of which buckets matter.
  • Fourteen-day flow-log retention against a thirty-day SIEM tier and a nine-day detection lag.
  • No Route 53 resolver logging, which removes DNS as a pivot for both exfiltration and C2.

Validation that would have caught the mapping defect: a synthetic canary - assume the role from a known external IP, call GetObject on a dedicated canary bucket with data events on, then assert end-to-end that the SIEM record carries role session name, source IP, eventName and bucket, within a stated latency. Pair it with continuous assertions: an account-inventory reconciliation that fails if any org account stops appearing in the SIEM for an hour, a field-completeness dashboard on the ten fields your detections depend on, and an alert on CloudTrail configuration changes. Run the canary on a schedule and after any trail change.