├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bucket-names.txt
└── sandcastle.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 |
5 | # C extensions
6 | *.so
7 |
8 | # Distribution / packaging
9 | bin/
10 | build/
11 | develop-eggs/
12 | dist/
13 | eggs/
14 | lib/
15 | lib64/
16 | parts/
17 | sdist/
18 | var/
19 | *.egg-info/
20 | .installed.cfg
21 | *.egg
22 |
23 | # Installer logs
24 | pip-log.txt
25 | pip-delete-this-directory.txt
26 |
27 | # Unit test / coverage reports
28 | .tox/
29 | .coverage
30 | .cache
31 | nosetests.xml
32 | coverage.xml
33 |
34 | # Translations
35 | *.mo
36 |
37 | # Mr Developer
38 | .mr.developer.cfg
39 | .project
40 | .pydevproject
41 |
42 | # Rope
43 | .ropeproject
44 |
45 | # Django stuff:
46 | *.log
47 | *.pot
48 |
49 | # Sphinx documentation
50 | docs/_build/
51 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 | All notable changes to the Sandcastle script will be documented in this file.
3 |
4 | ## 1.2.4 – 2017-05-28
5 | * Temporarily removed PyPi distribution channel
6 | * Shipping an updated bucket names wordlist
7 | * Script identifies potential matches and uses S3 CLI to check Read permissions
8 |
9 | ## 1.2.3 – 2017-04-09
10 | - PyPi distribution info not applicable; please see above
11 | - Removes "no match" display from Sandcastle script
12 |
13 | ## 1.2.2 – 2017-04-09
14 | - Sandcastle is now live on PyPi! This version fixes an import issue with `bucket-names.txt`.
15 |
16 | ## 1.2.1 – 2017-04-09
17 | - Sandcastle is being packaged and published on PyPi; this version is used for compatibility purposes.
18 |
19 | ## 1.2.0 – 2017-04-09
20 | - Sandcastle now supports the `-f` argument (text file)
21 | * The script defaults to `bucket-names.txt` if one is not given
22 | - Sandcastle now presents a line count for the specified text file
23 | - Adjusted ASCII header art and script wording
24 |
25 | ## 1.1.0 – 2017-04-09
26 | - Sandcastle now distinguishes between bucket status codes
27 | * Buckets returning 404 are hidden by default
28 | * Other status codes are displayed as potential "matches"
29 | - Sandcastle script and documentation improvements
30 | - Established `CHANGELOG.md` for update tracking
31 |
32 | ## 1.0.0 – 2017-04-08
33 | - Initial public release of the optimised bucketCrawler script
34 | - Initial `README.md` documentation and bucket permutations
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Yasin Soliman
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Inspired by a conversation with Instacart's [@nickelser](https://github.com/nickelser) on HackerOne, I've optimised and published Sandcastle – a Python script for AWS S3 bucket enumeration, formerly known as bucketCrawler.
6 |
7 | The script takes a target's name as the stem argument (e.g. `shopify`) and iterates through a file of bucket name permutations, such as the ones below:
8 |
9 | ```
10 | -training
11 | -bucket
12 | -dev
13 | -attachments
14 | -photos
15 | -elasticsearch
16 | [...]
17 | ```
18 |
19 | ## Getting started
20 | Here's how to get started:
21 |
22 | 1. Clone this repo (PyPi distribution temporarily disabled).
23 | 2. Run `sandcastle.py` with a target name and input file (grab an example from this repo)
24 | 3. Matching bucket permutations will be identified, and read permissions tested.
25 |
26 | ```
27 | usage: sandcastle.py [-h] -t targetStem [-f inputFile]
28 |
29 | arguments:
30 | -h, --help show this help message and exit
31 | -t targetStem, --target targetStem
32 | Select a target stem name (e.g. 'shopify')
33 | -f inputFile, --file inputFile
34 | Select a bucket permutation file (default: bucket-
35 | names.txt)
36 | ```
37 |
38 | ```
39 | ____ __ __ __
40 | / __/__ ____ ___/ /______ ____ / /_/ /__
41 | _\ \/ _ `/ _ \/ _ / __/ _ `(_- __/ / -_)
42 | /___/\_,_/_//_/\_,_/\__/\_,_/___/\__/_/\__/
43 |
44 | S3 bucket enumeration // release v1.2.4 // ysx
45 |
46 |
47 | [*] Commencing enumeration of 'shopify', reading 138 lines from 'bucket-names.txt'.
48 |
49 | [+] Checking potential match: shopify-content --> 403
50 |
51 | An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied
52 |
53 | ```
54 |
55 | ### Status codes and testing
56 |
57 | | Status code | Definition | Notes |
58 | | ------------- | ------------- | -----|
59 | | 404 | Bucket Not Found | Not a target for analysis (hidden by default)|
60 | | 403 | Access Denied | Potential target for analysis via the CLI |
61 | | 200 | Publicly Accessible | Potential target for analysis via the CLI |
62 |
63 | ### AWS CLI commands
64 | Here's a quick reference of some useful AWS CLI commands:
65 | * List Files: `aws s3 ls s3://bucket-name`
66 | * Download Files: `aws s3 cp s3://bucket-name/ `
67 | * Upload Files: `aws s3 cp/mv test-file.txt s3://bucket-name`
68 | * Remove Files: `aws s3 rm s3://bucket-name/test-file.txt`
69 |
70 | ## What is S3?
71 | From the Amazon [documentation](http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html), *Working with Amazon S3 Buckets*:
72 | > Amazon S3 [Simple Storage Service] is cloud storage for the Internet. To upload your data (photos, videos, documents etc.), you first create a bucket in one of the AWS Regions. You can then upload any number of objects to the bucket.
73 |
74 | > In terms of implementation, buckets and objects are resources, and Amazon S3 provides APIs for you to manage them.
75 |
76 | ## Closing remarks
77 | * This is my first public security project. Sandcastle is published under the MIT License.
78 | * Usage acknowlegements:
79 | * Castle (icon) by Andrew Doane from the Noun Project
80 | * Nixie One (logo typeface) free by Jovanny Lemonad
81 |
--------------------------------------------------------------------------------
/bucket-names.txt:
--------------------------------------------------------------------------------
1 | -vanity-production
2 | -vanity-staging
3 | -vanity-dev
4 | -vanity-development
5 | -media-uploads
6 | -datasets
7 | -dataset
8 | -website-assets
9 | -logos
10 | -avatars
11 | -backgrounds
12 | -share
13 | -matrix
14 | -s3-connector-test
15 | -media
16 | -terraform-binaries
17 | -consultant
18 | -consultants
19 | -consulting
20 | -consumer
21 | -contact
22 | -content
23 | -contracts
24 | -gemini
25 | -general
26 | -kerberos
27 | -keynote
28 | -loadbalancer
29 | -local
30 | -localhost
31 | -splunk
32 | -git
33 | -subversion
34 | -mercurial
35 | -design
36 | -package
37 | -packages
38 | -ios
39 | -android
40 | -betas
41 | -bugs
42 | -bugzilla
43 | -build
44 | -bulletins
45 | -corporate
46 | -training
47 | -conference
48 | -conferencing
49 | -confidential
50 | -cloud
51 | -club
52 | -clubs
53 | -cluster
54 | -clusters
55 | -developer
56 | -developers
57 | -engineer
58 | -engineering
59 | -fileserv
60 | -fileserver
61 | -filestore
62 | -intranet
63 | -invalid
64 | -investor
65 | -investors
66 | -member
67 | -members
68 | -operations
69 | -products
70 | -profiles
71 | -project
72 | -projects
73 | -research
74 | -reseller
75 | -reserved
76 | -static
77 | -statistics
78 | -stats
79 | -reports
80 | -bugbounty
81 | -bucket
82 | -dev
83 | -attachments
84 | -photos
85 | -pics
86 | -attach
87 | -tmp
88 | -temp
89 | -devel
90 | -prod
91 | -assets
92 | -admin
93 | -devops
94 | -apollo
95 | -files
96 | -production
97 | -development
98 | -uploads
99 | -aws
100 | -marketing
101 | -partners
102 | -company
103 | -data
104 | -web
105 | -web-assets
106 | -web-static
107 | -web-data
108 | -ops
109 | -billing
110 | -documents
111 | -spreadsheets
112 | -presentations
113 | -images
114 | -onboarding
115 | -finance
116 | -kafka
117 | -ux
118 | -ui
119 | -users
120 | -react
121 | -angular
122 | -website
123 | -rest
124 | -graphite
125 | -logstash
126 | -kibana
127 | -logexport
128 | -api
129 | -delivery-app-storage
130 | -elasticsearch
131 | -cloudtrail
132 | -aws-logs
133 | -administration
134 | -administrator
135 | -beta
136 | -alpha
137 | -maven
138 | -github
139 | .vanity.production
140 | .vanity.staging
141 | .vanity.dev
142 | .vanity.development
143 | .media.uploads
144 | .datasets
145 | .dataset
146 | .website.assets
147 | .logos
148 | .avatars
149 | .backgrounds
150 | .share
151 | .matrix
152 | .s3.connector.test
153 | .media
154 | .terraform.binaries
155 | .consultant
156 | .consultants
157 | .consulting
158 | .consumer
159 | .contact
160 | .content
161 | .contracts
162 | .gemini
163 | .general
164 | .kerberos
165 | .keynote
166 | .loadbalancer
167 | .local
168 | .localhost
169 | .splunk
170 | .git
171 | .subversion
172 | .mercurial
173 | .design
174 | .package
175 | .packages
176 | .ios
177 | .android
178 | .betas
179 | .bugs
180 | .bugzilla
181 | .build
182 | .bulletins
183 | .corporate
184 | .training
185 | .conference
186 | .conferencing
187 | .confidential
188 | .cloud
189 | .club
190 | .clubs
191 | .cluster
192 | .clusters
193 | .developer
194 | .developers
195 | .engineer
196 | .engineering
197 | .fileserv
198 | .fileserver
199 | .filestore
200 | .intranet
201 | .invalid
202 | .investor
203 | .investors
204 | .member
205 | .members
206 | .operations
207 | .products
208 | .profiles
209 | .project
210 | .projects
211 | .research
212 | .reseller
213 | .reserved
214 | .static
215 | .statistics
216 | .stats
217 | .reports
218 | .bugbounty
219 | .bucket
220 | .dev
221 | .attachments
222 | .photos
223 | .pics
224 | .attach
225 | .tmp
226 | .temp
227 | .devel
228 | .prod
229 | .assets
230 | .admin
231 | .devops
232 | .apollo
233 | .files
234 | .production
235 | .development
236 | .uploads
237 | .aws
238 | .marketing
239 | .partners
240 | .company
241 | .data
242 | .web
243 | .web.assets
244 | .web.static
245 | .web.data
246 | .ops
247 | .billing
248 | .documents
249 | .spreadsheets
250 | .presentations
251 | .images
252 | .onboarding
253 | .finance
254 | .kafka
255 | .ux
256 | .ui
257 | .users
258 | .react
259 | .angular
260 | .website
261 | .rest
262 | .graphite
263 | .logstash
264 | .kibana
265 | .logexport
266 | .api
267 | .delivery.app.storage
268 | .elasticsearch
269 | .cloudtrail
270 | .aws.logs
271 | .administration
272 | .administrator
273 | .beta
274 | .alpha
275 | .maven
276 | .github
--------------------------------------------------------------------------------
/sandcastle.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | import sys, os, commands, requests
5 | from argparse import ArgumentParser
6 |
7 | print """
8 | ____ __ __ __
9 | / __/__ ____ ___/ /______ ____ / /_/ /__
10 | _\ \/ _ `/ _ \/ _ / __/ _ `(_- __/ / -_)
11 | /___/\_,_/_//_/\_,_/\__/\_,_/___/\__/_/\__/
12 |
13 | S3 bucket enumeration // release v1.2.4 // ysx
14 |
15 | """
16 | targetStem = ""
17 | inputFile = ""
18 |
19 | parser = ArgumentParser()
20 | parser.add_argument("-t", "--target", dest="targetStem",
21 | help="Select a target stem name (e.g. 'shopify')", metavar="targetStem", required="True")
22 | parser.add_argument("-f", "--file", dest="inputFile",
23 | help="Select a bucket permutation file (default: bucket-names.txt)", default="bucket-names.txt", metavar="inputFile")
24 | args = parser.parse_args()
25 |
26 | with open(args.inputFile, 'r') as f:
27 | bucketNames = [line.strip() for line in f]
28 | lineCount = len(bucketNames)
29 |
30 | print "[*] Commencing enumeration of '%s', reading %i lines from '%s'." % (args.targetStem, lineCount, f.name)
31 |
32 | for name in bucketNames:
33 | r = requests.head("http://%s%s.s3.amazonaws.com" % (args.targetStem, name))
34 | if r.status_code != 404:
35 | # macOS, coming soon: os.system("notify Potential match found! %s%s: %s" % (args.targetStem, name, r.status_code))
36 | print "[+] Checking potential match: %s%s --> %s" % (args.targetStem, name, r.status_code)
37 | check = commands.getoutput("/usr/local/bin/aws s3 ls s3://%s%s" % (args.targetStem, name))
38 | print check
39 | else:
40 | sys.stdout.write('')
41 |
42 | print "[*] Enumeration of '%s' buckets complete." % (args.targetStem)
43 | # macOS, coming soon: os.system("notify Enumeration of %s buckets complete." % (args.targetStem))
44 |
--------------------------------------------------------------------------------