In 2021 Ben Bridts published a highly inventive method for finding the AWS Account ID of a public S3 bucket.
This post describes a technique to find the Account ID of any S3 bucket (both private and public).
I'd highly recommend reading Ben's technique first as we will re-use a lot of concepts.
S3 Bucket to AWS Account ID
Shell output can be worth a thousand words, here's what our technique enables - finding the previously unknown AWS Account ID for the bucket bucket-alpha:
How exactly does this work?
When exploring possibilities for this technique, I started by breaking down exactly why Ben's method works. There are three key elements which combine to make it work:
- The ability to apply an IAM policy to the request
In the Ben's technique, this is achieved by applying a custom policy when assuming the role.
- The ability to infer whether this IAM policy permitted the request or not
In the case of public buckets, this is quite simple. If our policy blocked the request, the request will fail with AccessDenied. Otherwise, the request will succeed as expected with requests to public buckets.
- The ability to apply a wildcard match on the
s3:ResourceAccountcondition key
This allows us to discover the Account ID incrementally, one digit at a time, reducing the search space from trillions to hundreds.
A solution
After exploring a few different ideas, I found a solution which works. It involves using a VPC Endpoint for S3, and a difference of behavior in CloudTrail when a request is denied by a VPC Endpoint policy.

- The ability to apply an IAM policy to the request
Creating a VPC Endpoint of type "Interface" for S3 will allow us to apply an IAM policy to the request. This policy intersects with the other policies which apply to the request (e.g. the bucket policy, the IAM policy of the principal making the request etc) when the request is made through the VPC Endpoint.
- The ability to infer whether this IAM policy permitted the request or not
As the target bucket is owned by a third party and is a private bucket, we're (thankfully) going to receive an AccessDenied response, regardless of whichever policies we apply to the request. However, we can infer whether the VPC Endpoint policy blocked or permitted the request by whether it appears in our own CloudTrail logs.
- If the request does appear in our CloudTrail logs, it was permitted by our VPC Endpoint policy but blocked as expected by the bucket policy.
- If the request does not appear in our CloudTrail logs, it was blocked by our VPC Endpoint policy.
- The ability to apply a wildcard match on the
s3:ResourceAccountcondition key
We can use the full power of IAM policy conditions, including StringLike wildcards and resource condition keys in a VPC Endpoint policy, so the same basic technique will work here.
Step-by-step
Let's say that we want to find the Account ID of the bucket bucket-alpha.
Note that some of our activities here will be visible to the owner of the bucket in their own CloudTrail logs.
Determine the bucket region
We need to find the region in which the bucket lives so that we can create a VPC in the same region. This can be done by curling the bucket's HTTP endpoint and examining the x-amz-bucket-region header (which is returned despite the request being forbidden).
Deploy a VPC and VPC Endpoint in the same region
We need to deploy a VPC and a VPC Endpoint for S3 in the same region as the target bucket. It's best to create a VPC specifically for this purpose as our VPC Endpoint will interfere with requests to S3 from the VPC. The VPC Endpoint should be of type "Interface" so we can apply a policy to the request.
Launch an EC2 instance within the VPC and confirm that it's using the VPC Endpoint for S3
We'll need to send requests to S3 from within the VPC so that the VPC Endpoint is used. An EC2 instance is a convenient way of doing so.
Modify the VPC Endpoint policy to determine whether the account ID of the target bucket starts with "0"
Apply a policy to the VPC Endpoint which performs a wildcard match on the s3:ResourceAccount condition key. This will only permit requests through the endpoint if the bucket's Account ID starts with "0".
Make a request to the target bucket
Via the EC2 instance, make a request to the target bucket. This request will be denied as expected. It's best to use a "Management" request rather than a "Data" request so we don't need to do anything special with our CloudTrail setup. In this case I used GetBucketAcl.
Check whether the request appears in CloudTrail
Now we want to check whether our request appears in CloudTrail.
If we find our request in CloudTrail, it means that the VPC Endpoint policy permitted the request - i.e. the Account ID of the bucket starts with 0. If we don't find the request, then the VPC Endpoint policy blocked the request - i.e. the Account ID of the bucket does not start with 0.
Bear in mind that it will take a few minutes for the request to appear in CloudTrail. To be safe, I'd recommend waiting 10 minutes before deciding the event won't appear in CloudTrail.
Rinse and repeat
Depending on the result of the previous step, modify the VPC Endpoint policy to discover more information about the account ID. For instance, if the event didn't appear in CloudTrail, modify the condition to test whether the first digit is 1:
If it did appear in CloudTrail (so the first digit of the account ID is 0), we can start work on the second digit:
Bear in mind, it takes a few minutes for policy changes to fully propagate and take effect. I've found waiting 5 minutes after modifying the policy to work well.
Results
I wrote a script to automate this process and it could reliably find the Account ID of a bucket. As it's quite a slow process, I used a slightly modified technique of performing a binary search on each digit so fewer tests were needed, e.g:
Leaving it for a few hours returned the account ID successfully:
Making it faster
Waiting for the VPC Endpoint policy to take effect, and waiting for long enough to determine whether the request appears in CloudTrail is quite a slow process. Even using a binary search, it will take approximately (40 * 12 minutes = 8 hours) to find the Account ID.
To make this process faster, and eliminate the need to wait between each step, I modified the VPC endpoint policy like so:
There are 120 statements in the policy - one for each possible digit in each possible position. The condition on aws:userid is used to match particular values of the RoleSessionName parameter (which we can freely specify) used in an STS AssumeRole call. In effect this means we can selectively choose which policy statement (i.e. a particular digit in a particular position) we want to test for each request, by assuming a role with a particular RoleSessionName before doing so.

As this policy (only just!) fits within the maximum character length of a VPC Endpoint policy, we can test all 120 possibilities in parallel, without modifying the policy or waiting for the results individually in CloudTrail.
This reduced the time taken to find the Account ID to less than 10 minutes:
Remarks
- I consulted the AWS Security team before publishing this blog post.
- There has already been a lot of interesting discussion about whether AWS account IDs should be considered sensitive. It's noteworthy that in the CloudTrail events themselves, AWS has chosen to leave the third-party account ID
HIDDEN_DUE_TO_SECURITY_REASONS. You've probably also spotted that I've chosen to redact my own account ID from the examples in this post! - This technique should also work to uncover other resource condition keys (e.g.
aws:ResourceOrgID,aws:ResourceOrgPaths,aws:ResourceTag) associated with the bucket - or indeed for services other than S3 to which this technique could be applied - It's possible that by creating mutually peered VPCs and VPC Endpoints in all regions you could create a setup which works regardless of the particular region of the target bucket.
- These techniques are only feasible due to the ability to use
StringLikeconditions againsts3:ResourceAccountin a policy. I can't think of a use case where a partial match against a randomly-generated identifier is necessary. - It seems like it might otherwise be beneficial for events which are denied by VPC Endpoint policies to be logged in CloudTrail.
Acknowledgments
- Ben Bridts’ original technique inspired this work.
- I'm very grateful to Chris Farris for his invaluable help and advice.

