Skip to content

Commit 67f16a3

Browse files
authored
Logging, breakout, and azure region change
* implemented logging * limited to 1 region for azure VMs (by default, can change) * Added Ctrl-C breakout
1 parent 7f7af26 commit 67f16a3

File tree

7 files changed

+74
-26
lines changed

7 files changed

+74
-26
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ optional arguments:
7777
Threads for HTTP brute-force. Default = 5
7878
-ns NAMESERVER, --nameserver NAMESERVER
7979
DNS server to use in brute-force.
80+
-l LOGFILE, --logfile LOGFILE
81+
Will APPEND found items to specified file.
8082
--disable-aws Disable Amazon checks.
8183
--disable-azure Disable Azure checks.
8284
--disable-gcp Disable Google checks.

cloud_enum.py

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from enum_tools import aws_checks
1717
from enum_tools import azure_checks
1818
from enum_tools import gcp_checks
19+
from enum_tools import utils
1920

2021
BANNER = '''
2122
##########################
@@ -25,6 +26,8 @@
2526
2627
'''
2728

29+
LOGFILE = False
30+
2831
def parse_arguments():
2932
"""
3033
Handles user-passed parameters
@@ -64,6 +67,9 @@ def parse_arguments():
6467
default='8.8.8.8',
6568
help='DNS server to use in brute-force.')
6669

70+
parser.add_argument('-l', '--logfile', type=str, action='store',
71+
help='Will APPEND found items to specified file.')
72+
6773
parser.add_argument('--disable-aws', action='store_true',
6874
help='Disable Amazon checks.')
6975

@@ -96,6 +102,25 @@ def parse_arguments():
96102
with open(args.keyfile) as infile:
97103
args.keyword = [keyword.strip() for keyword in infile]
98104

105+
# Ensure log file is writeable
106+
if args.logfile:
107+
if os.path.isdir(args.logfile):
108+
print("[!] Can't specify a directory as the logfile, exiting.")
109+
sys.exit()
110+
if os.path.isfile(args.logfile):
111+
target = args.logfile
112+
else:
113+
target = os.path.dirname(args.logfile)
114+
if target == '':
115+
target = '.'
116+
117+
if not os.access(target, os.W_OK):
118+
print("[!] Cannot write to log file, exiting")
119+
sys.exit()
120+
121+
# Set the global in the utils file, where logging needs to happen
122+
utils.init_logfile(args.logfile)
123+
99124
return args
100125

101126
def print_status(args):
@@ -163,9 +188,6 @@ def main():
163188
Main program function.
164189
"""
165190
args = parse_arguments()
166-
167-
168-
169191
print(BANNER)
170192

171193
# Generate a basic status on targets and parameters
@@ -176,12 +198,16 @@ def main():
176198
names = build_names(args.keyword, mutations)
177199

178200
# All the work is done in the individual modules
179-
if not args.disable_aws:
180-
aws_checks.run_all(names, args.threads)
181-
if not args.disable_azure:
182-
azure_checks.run_all(names, args.brute, args.threads, args.nameserver)
183-
if not args.disable_gcp:
184-
gcp_checks.run_all(names, args.threads)
201+
try:
202+
if not args.disable_aws:
203+
aws_checks.run_all(names, args)
204+
if not args.disable_azure:
205+
azure_checks.run_all(names, args)
206+
if not args.disable_gcp:
207+
gcp_checks.run_all(names, args)
208+
except KeyboardInterrupt:
209+
print("Thanks for playing!")
210+
sys.exit()
185211

186212
# Best of luck to you!
187213
print("\n[+] All done, happy hacking!\n")

enum_tools/aws_checks.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
github.com/initstring/cloud_enum
44
"""
55

6-
import sys
76
from enum_tools import utils
87

98
BANNER = '''
@@ -86,7 +85,7 @@ def check_s3_buckets(names, threads):
8685
# Stop the time
8786
utils.stop_timer(start_time)
8887

89-
def run_all(names, threads):
88+
def run_all(names, args):
9089
"""
9190
Function is called by main program
9291
"""
@@ -95,5 +94,5 @@ def run_all(names, threads):
9594
# Use user-supplied AWS region if provided
9695
#if not regions:
9796
# regions = AWS_REGIONS
98-
check_s3_buckets(names, threads)
97+
check_s3_buckets(names, args.threads)
9998
return ''

enum_tools/azure_checks.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,17 @@ def check_azure_vms(names, nameserver):
276276
# Stop the timer
277277
utils.stop_timer(start_time)
278278

279-
def run_all(names, brute_list, threads, nameserver):
279+
def run_all(names, args):
280280
"""
281281
Function is called by main program
282282
"""
283283
print(BANNER)
284284

285-
valid_accounts = check_storage_accounts(names, threads, nameserver)
285+
valid_accounts = check_storage_accounts(names, args.threads,
286+
args.nameserver)
286287
if valid_accounts:
287-
brute_force_containers(valid_accounts, brute_list, threads)
288+
brute_force_containers(valid_accounts, args.brute, args.threads)
288289

289-
check_azure_websites(names, nameserver)
290-
check_azure_databases(names, nameserver)
291-
check_azure_vms(names, nameserver)
290+
check_azure_websites(names, args.nameserver)
291+
check_azure_databases(names, args.nameserver)
292+
check_azure_vms(names, args.nameserver)

enum_tools/azure_regions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@
2323

2424

2525
# And here I am limiting the search by overwriting this variable:
26-
REGIONS = ['eastus', 'australiaeast']
26+
REGIONS = ['eastus',]

enum_tools/gcp_checks.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ def check_appspot(names, threads):
107107
# Stop the time
108108
utils.stop_timer(start_time)
109109

110-
def run_all(names, threads):
110+
def run_all(names, args):
111111
"""
112112
Function is called by main program
113113
"""
114114
print(BANNER)
115115

116-
check_gcp_buckets(names, threads)
117-
check_appspot(names, threads)
116+
check_gcp_buckets(names, args.threads)
117+
check_appspot(names, args.threads)
118118
return ''

enum_tools/utils.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import time
66
import sys
77
import subprocess
8+
import datetime
89
import re
910
import requests
1011
try:
@@ -15,6 +16,20 @@
1516
print("[!] You'll need to pip install requests_futures for this tool.")
1617
sys.exit()
1718

19+
LOGFILE = False
20+
21+
def init_logfile(logfile):
22+
"""
23+
Initialize the global logfile if specified as a user-supplied argument
24+
"""
25+
if logfile:
26+
global LOGFILE
27+
LOGFILE = logfile
28+
29+
now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S")
30+
with open(logfile, 'a') as log_writer:
31+
log_writer.write("\n\n#### CLOUD_ENUM {} ####\n"
32+
.format(now))
1833

1934
def get_url_batch(url_list, use_ssl=False, callback='', threads=5):
2035
"""
@@ -156,12 +171,12 @@ def list_bucket_contents(bucket):
156171

157172
# Format them to full URLs and print to console
158173
if keys:
159-
print(" FILES:")
174+
printc(" FILES:\n", 'none')
160175
for key in keys:
161176
url = bucket + key
162-
print(" {}".format(url))
177+
printc(" ->{}\n".format(url), 'none')
163178
else:
164-
print(" ...empty bucket, so sad. :(")
179+
printc(" ...empty bucket, so sad. :(\n", 'none')
165180

166181
def printc(text, color):
167182
"""
@@ -182,6 +197,12 @@ def printc(text, color):
182197
sys.stdout.write(bold + red + text + end)
183198
if color == 'black':
184199
sys.stdout.write(bold + text + end)
200+
if color == 'none':
201+
sys.stdout.write(text)
202+
203+
if LOGFILE:
204+
with open(LOGFILE, 'a') as log_writer:
205+
log_writer.write(text.lstrip())
185206

186207
def start_timer():
187208
"""
@@ -201,6 +222,5 @@ def stop_timer(start_time):
201222

202223
# Print some statistics
203224
print("")
204-
printc(" DONE", 'black')
205225
print(" Elapsed time: {}".format(formatted_time))
206226
print("")

0 commit comments

Comments
 (0)