Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ This project uses [uv](https://github.com/astral-sh/uv) for dependency managemen
uv sync
```

Or install it as a standalone tool:

```sh
uv tool install git+https://github.com/initstring/cloud_enum
```

### Running
The only required argument is at least one keyword. You can use the built-in fuzzing strings, but you will get better results if you supply your own with `-m` and/or `-b`.

Expand All @@ -71,32 +77,34 @@ HTTP scraping and DNS lookups use 5 threads each by default. You can try increas
uv run cloud_enum -k keyword -t 10
```

**IMPORTANT**: Some resources (Azure Containers, GCP Functions) are discovered per-region. To save time scanning, there is a "REGIONS" variable defined in `cloudenum/azure_regions.py and cloudenum/gcp_regions.py` that is set by default to use only 1 region. You may want to look at these files and edit them to be relevant to your own work.
**IMPORTANT**: Some resources (Azure Containers, GCP Functions) are discovered per-region. To save time scanning, there is a "REGIONS" variable defined in `enum_tools/azure_regions.py` and `enum_tools/gcp_regions.py` that is set by default to use only 1 region. You may want to look at these files and edit them to be relevant to your own work.

**Complete Usage Details**
```
usage: cloud_enum.py [-h] -k KEYWORD [-m MUTATIONS] [-b BRUTE]
usage: cloud_enum [-h] (-k KEYWORD | -kf KEYFILE) [-m MUTATIONS] [-b BRUTE] [-t THREADS]
[-ns NAMESERVER] [-nsf NAMESERVERFILE] [-l LOGFILE] [-f FORMAT] [--disable-aws]
[--disable-azure] [--disable-gcp] [-qs]

Multi-cloud enumeration utility. All hail OSINT!

optional arguments:
options:
-h, --help show this help message and exit
-k KEYWORD, --keyword KEYWORD
-k, --keyword KEYWORD
Keyword. Can use argument multiple times.
-kf KEYFILE, --keyfile KEYFILE
-kf, --keyfile KEYFILE
Input file with a single keyword per line.
-m MUTATIONS, --mutations MUTATIONS
-m, --mutations MUTATIONS
Mutations. Default: enum_tools/fuzz.txt
-b BRUTE, --brute BRUTE
List to brute-force Azure container names. Default: enum_tools/fuzz.txt
-t THREADS, --threads THREADS
-b, --brute BRUTE List to brute-force Azure container names. Default: enum_tools/fuzz.txt
-t, --threads THREADS
Threads for HTTP brute-force. Default = 5
-ns NAMESERVER, --nameserver NAMESERVER
DNS server to use in brute-force.
-l LOGFILE, --logfile LOGFILE
Will APPEND found items to specified file.
-f FORMAT, --format FORMAT
Format for log file (text,json,csv - defaults to text)
-ns, --nameserver NAMESERVER
DNS server to use in brute-force. Default: 1.1.1.1
-nsf, --nameserverfile NAMESERVERFILE
Path to the file containing nameserver IPs
-l, --logfile LOGFILE
Appends found items to specified file.
-f, --format FORMAT Format for log file (text,json,csv) - default: text
--disable-aws Disable Amazon checks.
--disable-azure Disable Azure checks.
--disable-gcp Disable Google checks.
Expand Down
8 changes: 5 additions & 3 deletions cloud_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ def parse_arguments():
desc = "Multi-cloud enumeration utility. All hail OSINT!"
parser = argparse.ArgumentParser(description=desc)

# Grab the current dir of the script, for setting some defaults below
script_path = os.path.split(os.path.abspath(sys.argv[0]))[0]
# Grab the install dir of this module, for setting some defaults below.
# Not sys.argv[0]: console-script entry points live in the venv's bin dir.
script_path = os.path.dirname(os.path.abspath(__file__))

kw_group = parser.add_mutually_exclusive_group(required=True)

Expand Down Expand Up @@ -64,7 +65,8 @@ def parse_arguments():

parser.add_argument('-ns', '--nameserver', type=str, action='store',
default='1.1.1.1',
help='DNS server to use in brute-force.')
help='DNS server to use in brute-force.'
' Default: 1.1.1.1')
parser.add_argument('-nsf', '--nameserverfile', type=str,
help='Path to the file containing nameserver IPs')
parser.add_argument('-l', '--logfile', type=str, action='store',
Expand Down
2 changes: 1 addition & 1 deletion enum_tools/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from requests_futures.sessions import FuturesSession
from concurrent.futures._base import TimeoutError
except ImportError:
print("[!] Please pip install requirements.txt.")
print("[!] Missing dependencies, please run 'uv sync'.")
sys.exit()

LOGFILE = False
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ dev = [
py-modules = ["cloud_enum"]
packages = ["enum_tools"]

[tool.setuptools.package-data]
enum_tools = ["fuzz.txt"]

[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"
18 changes: 18 additions & 0 deletions tests/test_cloud_enum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import os
import sys

import cloud_enum


def test_default_wordlists_resolve_when_run_as_console_script(monkeypatch):
"""
`uv run cloud_enum` launches the console-script shim in .venv/bin, so the
default wordlists must not be located relative to sys.argv[0].
"""
shim = os.path.join(os.sep, 'nonexistent', '.venv', 'bin', 'cloud_enum')
monkeypatch.setattr(sys, 'argv', [shim, '-k', 'test'])

args = cloud_enum.parse_arguments()

assert os.access(args.mutations, os.R_OK)
assert os.access(args.brute, os.R_OK)
Loading