def create(self, user_id, zone_id=None, domain=None): provider = Provider() zones = provider.dns_zones() restrictions = provider.dns_restrictions() zone = zones.get(zone_id, user_id) if zone_id is not None else zones.find( domain, user_id=user_id) if not zone: return self.send_not_found_response() required_fields = ['type', 'enabled', 'ip_or_range'] data = self.get_json(required_fields) if data is False: return self.send_error_response( 5000, 'Missing fields', 'Required fields are: {0}'.format(', '.join(required_fields))) if data['type'] not in ['allow', 'block']: return self.send_error_response(5005, 'Invalid restriction type', '') elif len( data['ip_or_range'] ) == 0 or not restrictions.is_valid_ip_or_range(data['ip_or_range']): return self.send_error_response(5005, 'Invalid IP or Range', '') data['enabled'] = True if data['enabled'] else False data['type'] = 1 if data['type'] == 'allow' else 2 restriction = restrictions.create(zone_id=zone.id) restriction = restrictions.save(restriction, zone.id, data['ip_or_range'], data['type'], data['enabled']) return self.one(user_id, restriction.id, zone_id=zone.id)
def device_profile_save(id): provider = Provider() device_profile_manager = provider.device_profiles() name = request.form['name'].strip() if 'name' in request.form else '' enabled = True if 'enabled' in request.form else False devices = request.form.getlist('devices', int) if len(name) == 0: flash('Profile name cannot be empty', 'error') return redirect(url_for('config.device_profile_edit', id=id)) elif len(devices) == 0: flash('Please select at least one device', 'error') return redirect(url_for('config.device_profile_edit', id=id)) for device_id in devices: if not device_profile_manager.is_valid_device(device_id): flash('Invalid device selected', 'error') return redirect(url_for('config.device_profile_edit', id=id)) profile = device_profile_manager.save(id, name, devices, enabled) if not profile: flash('Could not save profile', 'error') return redirect(url_for('config.device_profile_edit', id=id)) flash('Device profile created', 'success') return redirect(url_for('config.device_profiles'))
def cli_records_list(domain, type, id): provider = Provider() zones = provider.dns_zones() records = provider.dns_records() if type is None and id is None: print("At least one of --type and --id has to be used") return False zone = zones.find(domain) if not zone: print("Could not find domain") return False results = records.get_zone_records(zone.id, order_column='type') record_deleted = False for record in results: if type is not None: if record.type == type.upper(): record_deleted = True records.delete(record) elif id is not None: if record.id == id: record_deleted = True records.delete(record) message = "Record deleted" if record_deleted else "Record not found" print(message) return True
def set_mode(self, user_id, session_id): required_fields = ['mode'] data = self.get_json(required_fields) if data is False: return self.send_error_response( 5000, 'Missing fields', 'Required fields are: ' + ', '.join(required_fields)) provider = Provider() sessions = provider.sessions() session = sessions.get(user_id=user_id, session_id=session_id) if not session: return self.send_access_denied_response() mode = 0 if data['mode'] == 'wordlist': mode = 0 elif data['mode'] == 'mask': mode = 3 else: return self.send_error_response(5004, 'Invalid mode selected', '') sessions.set_hashcat_setting(session_id, 'mode', mode) return self.send_success_response()
def start(self): app_for_context = create_app() dns_logging = DatabaseDNSLogging(app_for_context) clients = [ DatabaseDNSResolver(app_for_context, Provider().dns_manager(), dns_logging) ] if self.__forwarding_enabled and len(self.__forwarders) > 0: clients.append(client.Resolver(servers=self.__forwarders)) factory = DatabaseDNSFactory(clients=clients, verbose=2) factory.app = app_for_context factory.logging = dns_logging factory.restrictions = Provider().dns_restrictions() factory.csv_location = self.__csv_location observer = log.PythonLoggingObserver() observer.start() logging.basicConfig() logger = logging.getLogger() logger.setLevel(logging.DEBUG) reactor.listenUDP(self.__port, DNSDatagramProtocol(factory), interface=self.__host) reactor.listenTCP(self.__port, factory, interface=self.__host) reactor.run()
def zone_edit(dns_zone_id): provider = Provider() zones = provider.dns_zones() tags = provider.tags() zone = None dns_zone_id = 0 if dns_zone_id < 0 else dns_zone_id if dns_zone_id > 0: if not zones.can_access(dns_zone_id, current_user.id): flash('Access Denied', 'error') return redirect(url_for('home.index')) zone = zones.get(dns_zone_id) if not zone: flash('Zone not found', 'error') return redirect(url_for('home.index')) username = current_user.username if zone is None else zone.username user_id = zone.user_id if dns_zone_id > 0 else current_user.id return render_template('dns/zones/edit.html', dns_zone_id=dns_zone_id, user_domain=zones.get_user_base_domain(username), zone=zone, tags=tags.all(user_id=user_id, order_column='name', order_by='asc'))
def setup_hashcat(session_id): provider = Provider() sessions = provider.sessions() hashcat = provider.hashcat() system = provider.system() if not sessions.can_access(current_user, session_id): flash('Access Denied', 'error') return redirect(url_for('home.index')) user_id = 0 if current_user.admin else current_user.id session = sessions.get(user_id=user_id, session_id=session_id)[0] supported_hashes = hashcat.get_supported_hashes() # We need to process the array in a way to make it easy for JSON usage. supported_hashes = hashcat.compact_hashes(supported_hashes) if len(supported_hashes) == 0: home_directory = system.get_system_user_home_directory() flash('Could not get the supported hashes from hashcat', 'error') flash( 'If you have compiled hashcat from source, make sure %s/.hashcat directory exists and is writable' % home_directory, 'error') return render_template('sessions/setup/hashcat.html', session=session, hashes_json=json.dumps(supported_hashes, indent=4, sort_keys=True, default=str))
def login_2fa(): next = urllib.parse.unquote_plus(request.args.get('next', '').strip()) provider = Provider() users = provider.users() id = int(session['otp_userid']) if 'otp_userid' in session else 0 otp_time = int(session['otp_time']) if 'otp_time' in session else 0 can_continue = True if id <= 0: can_continue = False elif int(time.time()) > (otp_time + 120): # This page is valid for 2 minutes. can_continue = False if not can_continue: session.pop('otp_userid', None) session.pop('otp_time', None) return redirect(url_for('auth.login', next=next)) user = users.get_user(id) if not user: return redirect(url_for('auth.login', next=next)) return render_template('auth/login_2fa.html', next=request.args.get('next', ''))
def api(): provider = Provider() apiman = provider.api() apikeys = apiman.get(current_user.id) return render_template('config/account/api.html', apikeys=apikeys)
def cli_restrictions_update(domain, id, iprange, type, enabled): provider = Provider() zones = provider.dns_zones() restrictions = provider.dns_restrictions() zone = zones.find(domain) if not zone: print("Could not find domain") return False restriction = zone.restrictions.get(id) if not restriction: print("Could not find restriction") return False iprange = restriction.ip_range if iprange is None else iprange if len(iprange) == 0 or not restrictions.is_valid_ip_or_range(iprange): print("Invalid IP Range") return False enabled = restriction.enabled if enabled is None else enabled in ['yes', 'true'] type = restriction.type if type is None else (1 if type == 'allow' else 2) restrictions.save(restriction, zone.id, iprange, type, enabled) print("Restriction updated") return True
def cli_restrictions_delete(domain, iprange, id): provider = Provider() zones = provider.dns_zones() if iprange is None and id is None: print("One of --iprange or --id should be used") return False zone = zones.find(domain) if not zone: print("Could not find domain") return False if id is not None: restriction = zone.restrictions.get(id) if not restriction: print("Could not find restriction with id {0}".format(id)) return False elif iprange is not None: for restriction in zone.restrictions.all(): if iprange == 'all': restriction.delete() elif iprange == restriction.ip_range: restriction.delete() print("Restriction(s) deleted") return True
def set_remote(self, user_id, session_id): required_fields = ['file'] data = self.get_json(required_fields) if data is False: return self.send_error_response( 5000, 'Missing fields', 'Required fields are: ' + ', '.join(required_fields)) provider = Provider() sessions = provider.sessions() hashes = provider.hashes() session = sessions.get(user_id=user_id, session_id=session_id) if not session: return self.send_access_denied_response() elif not hashes.is_valid_uploaded_hashfile(data['file']): return self.send_error_response(5002, 'Invalid file selected', '') save_as = sessions.session_filesystem.get_hashfile_path( user_id, session_id) local_path = hashes.get_uploaded_hashes_path(data['file']) if not hashes.copy_file(local_path, save_as): return self.send_error_response( 5003, 'Could not copy hashes file to data directory', '') return self.send_success_response()
def set_type(self, user_id, session_id): required_fields = ['type'] data = self.get_json(required_fields) if data is False: return self.send_error_response(5000, 'Missing fields', 'Required fields are: ' + ', '.join(required_fields)) provider = Provider() sessions = provider.sessions() session = sessions.get(user_id=user_id, session_id=session_id) if not session: return self.send_access_denied_response() elif not data['type'] in ['global', 'custom', 'cracked']: return self.send_error_response(5010, 'Invalid wordlist type', '') type = 0 if data['type'] == 'global': type = 0 elif data['type'] == 'custom': type = 1 elif data['type'] == 'cracked': type = 2 sessions.set_hashcat_setting(session_id, 'wordlist_type', type) return self.send_success_response()
def webpush_save(): provider = Provider() settings = provider.settings() vapid_private = request.form['vapid_private'].strip() vapid_public = request.form['vapid_public'].strip() webpush_enabled = True if int(request.form.get('webpush_enabled', 0)) == 1 else False if len(vapid_private) == 0: flash('Please enter a VAPID Private Key', 'error') return redirect(url_for('config.webpush')) elif vapid_private == '********' and len(settings.get('vapid_private', '')) == 0: flash('Please enter a VAPID Private Key', 'error') return redirect(url_for('config.webpush')) elif len(vapid_public) == 0: flash('Please enter a VAPID Public Key', 'error') return redirect(url_for('config.webpush')) if vapid_private != '********': settings.save('vapid_private', vapid_private) settings.save('vapid_public', vapid_public) settings.save('webpush_enabled', webpush_enabled) flash('Settings saved', 'success') return redirect(url_for('config.webpush'))
def __zone_create(): provider = Provider() zones = provider.dns_zones() dns_zone_id = 0 domain = request.form['domain'].strip().lower() active = True if int(request.form.get('active', 0)) == 1 else False catch_all = True if int(request.form.get('catch_all', 0)) == 1 else False forwarding = True if int(request.form.get('forwarding', 0)) == 1 else False regex = True if int(request.form.get('regex', 0)) == 1 else False tags = request.form.getlist('tags') zone = zones.new(domain, active, catch_all, forwarding, regex, current_user.id, update_old_logs=True) if isinstance(zone, list): for error in zone: flash(error, 'error') return redirect(url_for('dns.zone_edit', dns_zone_id=dns_zone_id)) zone = zones.save_tags(zone, tags) if not zone: flash('Could not save zone tags', 'error') return redirect(url_for('dns.zone_edit', dns_zone_id=dns_zone_id)) flash('Zone created', 'success') return redirect(url_for('dns.zone_view', dns_zone_id=zone.id))
def cli_zones_export(output, user_id, search, tags, include_records): provider = Provider() zones = provider.dns_zones() tags = tags.split(',') if tags is not None else None result = zones.export(user_id=user_id, search=search, tags=tags, export_zones=True, export_records=include_records) if not result: print("Could not export data") return False os.rename(result['zones'], output) print("Zone export saved as: {0}".format(output)) if include_records: path = os.path.dirname(output) file = os.path.basename(output).split('.') if len(file) > 1: extension = file[-1] del file[-1] file.append('records') file.append(extension) else: file.append('records') save_records_as = os.path.join(path, '.'.join(file)) os.rename(result['records'], save_records_as) print("Record export saved as: {0}".format(save_records_as)) return True
def zone_create_from_log(query_log_id): provider = Provider() logging = provider.dns_logs() zones = provider.dns_zones() log = logging.get(query_log_id) if not log: flash('Could not retrieve log record', 'error') return redirect(url_for('home.index')) if log.dns_zone_id > 0: # This means that the zone exists. if not zones.can_access(log.dns_zone_id, current_user.id): # This error is misleading on purpose to prevent zone enumeration. Not that it's important by meh. flash('Could not retrieve log record', 'error') return redirect(url_for('home.index')) flash('Zone already exists', 'error') return redirect(url_for('dns.zone_view', dns_zone_id=log.dns_zone_id)) zone = zones.new(log.domain, True, False, False, current_user.id, update_old_logs=True) if isinstance(zone, list): for error in zone: flash(error, 'error') return redirect(url_for('dns.zone_edit', dns_zone_id=0)) flash('Zone created', 'success') return redirect(url_for('dns.zone_view', dns_zone_id=zone.id))
def cli_zones_import(file, user_id): provider = Provider() import_manager = provider.dns_import() users = provider.users() user = users.get_user(user_id) if not user: print("Could not find user with ID: {0}".format(user_id)) return False import_type = import_manager.identify(file) if import_type != import_manager.IMPORT_TYPE_ZONE: print("Invalid import file: {0}".format(import_manager.last_error)) return False data = import_manager.review(file, import_type, user.id, show_progressbar=True) if not data: print("Could not load file: {0}".format(import_manager.last_error)) return False if len(data['errors']) > 0: errors = [] for error in data['errors']: errors.append([error['row'], error['error']]) print(tabulate.tabulate(errors, ['row', 'error'])) return False result = import_manager.run(data['data'], import_type, user.id, show_progressbar=True) if result: return True for error in result: print(error) return False
def index(): results_per_page = 20 provider = Provider() zones = provider.dns_zones() tags = provider.tags() search = request.args.get('search', '').strip() search_tags = request.args.getlist('tags') page = int(request.args.get('page', 1)) if page <= 0: page = 1 user_id = None if current_user.admin else current_user.id page_url = 'tags=' + '&tags='.join(search_tags) page_url += "&search={0}&page=".format(search) return render_template('dns/zones/index.html', zones=zones.get_user_zones_paginated( user_id, order_by='domain', page=page, per_page=results_per_page, search=search, tags=search_tags), page=page, per_page=results_per_page, page_url=page_url, search=search, search_tags=search_tags, tags=tags.all(user_id=user_id, order_by='asc', order_column='name'))
def cli_zones_update(domain, active, catch_all, forwarding, regex): provider = Provider() zones = provider.dns_zones() zone = zones.find(domain) if not zone: print("Could not find domain") return False if active is not None: zone.active = (active in ['yes', 'true']) if catch_all is not None: zone.catch_all = (catch_all in ['yes', 'true']) if forwarding is not None: zone.forwarding = (forwarding in ['yes', 'true']) if regex is not None: zone.regex = (regex in ['yes', 'true']) zone.save() print("Zone updated") return True
def settings_save(session_id): provider = Provider() sessions = provider.sessions() if not sessions.can_access(current_user, session_id): flash('Access Denied', 'error') return redirect(url_for('home.index')) termination_date = request.form['termination_date'].strip() termination_time = request.form['termination_time'].strip() notifications_enabled = int(request.form.get('notifications_enabled', 0)) if len(termination_date) == 0: flash('Please enter a termination date', 'error') return redirect(url_for('sessions.settings', session_id=session_id)) if len(termination_time) == 0: # Default to 23:59. termination_time = '23:59' if not sessions.set_termination_datetime(session_id, termination_date, termination_time): flash('Invalid termination date/time entered', 'error') return redirect(url_for('sessions.settings', session_id=session_id)) sessions.set_notifications(session_id, notifications_enabled) flash('Settings saved', 'success') return redirect(url_for('sessions.view', session_id=session_id))
def save(): provider = Provider() users = provider.users() if users.get_user_count() > 0: flash('Application has already been configured.', 'error') return redirect(url_for('home.index')) username = request.form['username'].strip() password = request.form['password'].strip() full_name = request.form['full_name'].strip() email = request.form['email'].strip() if len(username) == 0 or len(password) == 0 or len(full_name) == 0 or len( email) == 0: flash('Please fill in all the fields', 'error') return redirect(url_for('install.index')) if not users.save(0, username, password, full_name, email, 1, 0, 1): flash( 'Could not create user - make sure the database file is writable', 'error') return redirect(url_for('install.index')) flash('Please login as the newly created administrator', 'success') return redirect(url_for('home.index'))
def zone_restrictions_edit_save(dns_zone_id, restriction_id): provider = Provider() zones = provider.dns_zones() restrictions = provider.dns_restrictions() if not zones.can_access(dns_zone_id, current_user.id): flash('Access Denied', 'error') return redirect(url_for('home.index')) zone = zones.get(dns_zone_id) if not zone: flash('Zone not found', 'error') return redirect(url_for('home.index')) ip_range = request.form['ip_range'].strip() type = int(request.form['type'].strip()) enabled = True if int(request.form.get('enabled', 0)) == 1 else False if len(ip_range) == 0 or not restrictions.is_valid_ip_or_range(ip_range): flash('Invalid IP/Range', 'error') return redirect(url_for('dns.zone_restrictions', dns_zone_id=zone.id)) elif type not in [1, 2]: flash('Invalid type', 'error') return redirect(url_for('dns.zone_restrictions', dns_zone_id=zone.id)) restriction = restrictions.create(zone_id=zone.id) if restriction_id == 0 else zone.restrictions.get(restriction_id) if not restriction: flash('Could not load restriction', 'error') return redirect(url_for('dns.zone_restrictions', dns_zone_id=zone.id)) restrictions.save(restriction, zone.id, ip_range, type, enabled) flash('Restriction saved', 'success') return redirect(url_for('dns.zone_restrictions', dns_zone_id=zone.id))
def logout(): provider = Provider() users = provider.users() users.logout_session(current_user.id) logout_user() return redirect(url_for('auth.login'))
def zone_notifications_settings(dns_zone_id, item): provider = Provider() zones = provider.dns_zones() notifications = provider.notifications() if not zones.can_access(dns_zone_id, current_user.id): flash('Access Denied', 'error') return redirect(url_for('dns.index')) zone = zones.get(dns_zone_id) if not zone: flash('Zone not found', 'error') return redirect(url_for('dns.index')) notification_provider = notifications.providers.get(item) if not notification_provider: flash('Invalid notification provider', 'error') return redirect(url_for('dns.index')) elif not notification_provider.enabled: flash('Notification provider is not enabled', 'error') return redirect(url_for('dns.index')) elif not notification_provider.has_settings: flash('Notification provider has no settings', 'error') return redirect(url_for('dns.index')) return render_template( 'dns/zones/view.html', zone=zone, tab='notifications', section='{0}_settings'.format(item), has_enabled_providers=notifications.providers.has_enabled(), subscription=zone.notifications.get(item) )
def alias_edit_save(alias_id): provider = Provider() aliases = provider.aliases() ip = request.form['ip'].strip() name = request.form['name'].strip() if len(name) == 0: flash('Please enter an alias name', 'error') return redirect(url_for('dns.alias_index')) elif not aliases.is_valid_ip_or_range(ip): flash('Please enter a valid IP address', 'error') return redirect(url_for('dns.alias_index')) alias_with_same_ip = aliases.get(None, user_id=current_user.id, ip=ip) if alias_with_same_ip and alias_with_same_ip.id != alias_id: flash('An alias with this IP address already exists', 'error') return redirect(url_for('dns.alias_index')) user_id = None if current_user.admin else current_user.id if alias_id > 0: if not aliases.can_access(alias_id, user_id): flash('You cannot access the selected alias', 'error') return redirect(url_for('dns.alias_index')) alias = aliases.update(alias_id, ip=ip, name=name) else: alias = aliases.save(current_user.id, ip, name) flash('Alias Created' if alias_id == 0 else 'Alias Updated', 'success') return redirect(url_for('dns.alias_index'))
def device_profile_delete(id): provider = Provider() device_profile_manager = provider.device_profiles() device_profile_manager.delete(id) flash('Device profile deleted', 'success') return redirect(url_for('config.device_profiles'))
def zones_import_run(): provider = Provider() import_manager = provider.dns_import() file = import_manager.get_user_data_path(current_user.id, filename='import.csv') if not os.path.isfile(file): flash('No file uploaded', 'error') return redirect(url_for('dns.zones_import')) import_type = import_manager.identify(file) if import_type is False: flash("Error: {0}".format(import_manager.last_error), 'error') return redirect(url_for('dns.zones_import')) data = import_manager.review(file, import_type, current_user.id) if not data: flash("Error: {0}".format(import_manager.last_error), 'error') return redirect(url_for('dns.zones_import')) elif len(data['errors']) > 0: flash("Please fix all the uploaded file's errors before importing it", 'error') return redirect(url_for('dns.zones_import_review')) result = import_manager.run(data['data'], import_type, current_user.id) if result is True: # Delete file after process. os.remove(file) flash('Data has been successfully imported', 'success') return redirect(url_for('dns.index')) for error in result: flash(error, 'error') return redirect(url_for('dns.zones_import_review'))
def export(): provider = Provider() search = provider.search() logs = provider.dns_logs() users = provider.users() # Prepare names and variables. filename = str(int(time.time())) + '.csv' download_filename = "snitch_logs_" + filename save_results_as = users.get_user_data_path(current_user.id, filename=filename) # Perform the search. results = search.search_from_request(request, paginate=False, method='get') rows = results['results'] # Export to disk. if not logs.save_results_csv(rows, save_results_as, overwrite=True): flash('Could not generate CSV file.', 'error') return redirect(url_for('logs.index')) # And download. return send_file(save_results_as, attachment_filename=download_filename, as_attachment=True)
def record_edit(dns_zone_id, dns_record_id): provider = Provider() zones = provider.dns_zones() records = provider.dns_records() if not zones.can_access(dns_zone_id, current_user.id): flash('Access Denied', 'error') return redirect(url_for('home.index')) elif dns_record_id > 0: if not records.can_access(dns_zone_id, dns_record_id): flash('Access Denied', 'error') return redirect(url_for('home.index')) zone = zones.get(dns_zone_id) if not zone: flash('Zone not found', 'error') return redirect(url_for('home.index')) record = records.get(dns_record_id, zone.id) if dns_record_id > 0: if not record: flash('Could not load record', 'error') return redirect(url_for('home.index')) dns_types = records.get_types() dns_classes = records.get_classes() return render_template('dns/zones/view.html', dns_record_id=dns_record_id, dns_types=dns_types, dns_classes=dns_classes, zone=zone, record=record, section='records_edit', tab='records')