def get_cpe_aliases(cpe): cparts = cpe.split(':') cpebase = ':'.join(cparts[:3]) version = ':'.join(cparts[3:]) aliases = [] for row in c.execute( 'select cpe from aliases where class = (select class from aliases where cpe like ?)', [cpebase]): alias = row[0] if version: alias += ':' + version aliases.append(alias) if verbose: if len(aliases) > 0: debug('Resolved aliases: {byellow}cpe:/' + ('{rst}, {byellow}cpe:/'.join(aliases)) + '{rst}.') else: debug('No known aliases.') return aliases
def dump_pipe(self, stream, stop_event=None, tag='?', color=Fore.BLUE): while stream.readable() and (stop_event is not None and not stop_event.is_set()): line = stream.readline().decode('utf-8').rstrip() if len(line) != 0 and self.verbose >= 1: debug(color + '[' + Style.BRIGHT + tag + Style.NORMAL + '] ' + Fore.RESET + '{line}', color=color)
def serve(self): loop = asyncio.get_event_loop() tcp_success = 0 for port in self.tcp_ports: if self.verbose >= 2: debug('Starting listener for TCP port {byellow}{port}{rst}...') try: tcp_socket = socket.socket(family=socket.AF_INET6, type=socket.SOCK_STREAM) tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) tcp_socket.bind(('::', int(port))) loop_server = loop.run_until_complete( loop.create_server( lambda: HoneypotServerTCP(self), sock=tcp_socket)) loop.create_task(loop_server.serve_forever()) tcp_success += 1 except: error('Failed to bind to TCP port {port}.') info('Started listening on {byellow}{tcp_success}{rst} TCP ports.') udp_success = 0 for port in self.udp_ports: if self.verbose >= 3: debug('Starting listener for UDP port {byellow}{port}{rst}...') try: udp_socket = socket.socket(family=socket.AF_INET6, type=socket.SOCK_DGRAM) udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) udp_socket.bind(('::', int(port))) transport, protocol = loop.run_until_complete( loop.create_datagram_endpoint( lambda: HoneypotServerUDP(self), sock=udp_socket)) udp_success += 1 except: error('Failed to bind to UDP port {port}.') info('Started listening on {byellow}{udp_success}{rst} UDP ports.') try: loop.run_forever() except: pass
def download_nvd_dbs(): os.makedirs('nvd', exist_ok=True) if os.path.exists('nvd/cpe-dict.xml.gz') and ( datetime.datetime.today() - datetime.datetime.fromtimestamp( os.path.getmtime('nvd/cpe-dict.xml.gz'))).days > 1: os.unlink('nvd/cpe-dict.xml.gz') if not os.path.exists('nvd/cpe-dict.xml.gz'): info('Downloading CPE dictionary...') download_archives( 'https://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.3.xml.gz', 'nvd/cpe-dict.xml.gz') else: debug( 'Not downloading CPE dictionary: file is less than 24 hours old.') if os.path.exists('nvd/cpe-aliases.lst') and ( datetime.datetime.today() - datetime.datetime.fromtimestamp( os.path.getmtime('nvd/cpe-aliases.lst'))).days > 1: os.unlink('nvd/cpe-aliases.lst') if not os.path.exists('nvd/cpe-aliases.lst'): info('Downloading CPE aliases...') download_archives( 'https://salsa.debian.org/dlange/debian_security_security-tracker_split_files_v2/-/raw/master/data/CPE/aliases', 'nvd/cpe-aliases.lst') else: debug('Not downloading CPE aliases: file is less than 24 hours old.') currentyear = datetime.datetime.now().year for year in range(2002, currentyear): if os.path.exists('nvd/cve-items-' + str(year) + '.json.gz'): debug( 'Not downloading CVE entries for year {year}: file already exists.' ) continue info('Downloading CVE entries for year {year}...') download_archives( 'https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-' + str(year) + '.json.gz', 'nvd/cve-items-' + str(year) + '.json.gz') if os.path.exists('nvd/cve-items-' + str(currentyear) + '.json.gz') and ( datetime.datetime.today() - datetime.datetime.fromtimestamp( os.path.getmtime('nvd/cve-items-' + str(currentyear) + '.json.gz'))).days > 1: os.unlink('nvd/cve-items-' + str(currentyear) + '.json.gz') if not os.path.exists('nvd/cve-items-' + str(currentyear) + '.json.gz'): info('Downloading CVE entries for year {currentyear}...') download_archives( 'https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-' + str(currentyear) + '.json.gz', 'nvd/cve-items-' + str(currentyear) + '.json.gz') else: debug( 'Not downloading CVE entries for year {currentyear}: file is less than 24 hours old.' )
def load_probes(self): if not os.path.exists('data/service-probes'): error('Could not find {bgreen}data/service-probes{rst}.') return False self.probes = {'UDP': {}, 'TCP': {}} self.payloads = {'UDP': {}, 'TCP': {}} with open('data/service-probes', 'r') as f: lines = f.readlines() current = None for line in lines: line = line.strip() lowline = line.lower() if not line: continue if lowline.startswith('probe '): probe_type, proto, name, payload = line.split(' ', 3) payload = payload[2:-1].encode('utf-8').decode('unicode_escape') self.probes[proto][name] = payload current = (proto, name) elif lowline.startswith('match ') or lowline.startswith('softmatch '): if not current: continue action, name, regex = line.split(' ', 2) # check what separator is being used for the regex # and extract the regex itself rgxsep = regex[1] rgxend = regex[2:].find(rgxsep) + 2 regex = regex[2:rgxend] if current[1] not in self.payloads[current[0]]: self.payloads[current[0]][current[1]] = [] self.payloads[current[0]][current[1]].append(regex) if self.verbose >= 1: tcp_probes = len(self.probes['TCP']) udp_probes = len(self.probes['UDP']) debug('Loaded {bgreen}{tcp_probes}{rst} TCP and {bgreen}{udp_probes}{rst} UDP probes.') return len(self.probes['UDP']) > 0 and len(self.probes['TCP']) > 0
def _scan_host(self, scanner_group, address, results): for idx, scanner in enumerate(scanner_group): name = scanner.name() cache = scanner.code() result = None if idx > 0: info( 'Re-trying {bblue}{name}{rst}/{byellow}{address}{rst} with next implementation...' ) if self.has_cached_result(address, cache): if self.verbose >= 1: debug( 'Returning {bblue}{name}{rst}/{byellow}{address}{rst} from recent cache.' ) result = self.read_result(address, cache) if result is None and not self.no_query: if self.verbose >= 1: debug( 'Getting fresh {bblue}{name}{rst}/{byellow}{address}{rst} data...' ) result = scanner.get(address) if result is not None: self.write_result(address, cache, result) if result is None: error( 'Failed to get passive scan data for {byellow}{address}{rst}.' ) continue parsed = scanner.enum(result) if self.verbose >= 1: for svc in parsed: debug( 'Discovered service {bgreen}{svc[service]}{rst} on port {bgreen}{svc[port]}{rst}/{bgreen}{svc[transport]}{rst} running {bgreen}{svc[product]}{rst}/{bgreen}{svc[version]}{rst}.' ) results[name] = parsed break
def datagram_received(self, data, addr): lport = self.transport.get_extra_info('sockname')[1] if self.server.verbose >= 1: debug('Data on {byellow}udp:{lport}{rst} from {byellow}{addr[0]}{rst}: {bblue}{data}{rst}') proto, reply, error = self.server.handle_message(data, 'UDP') if reply is not None: if self.server.verbose >= 1: trunc = reply if self.server.verbose < 2 and len(trunc) > self.truncation_length: trunc = trunc[:60] + self.truncation_marker debug('Replying to {byellow}{addr[0]}{rst} with {bgreen}{proto}{rst}: {bblue}{trunc}{rst}') else: info('Data on {byellow}udp:{lport}{rst} from {byellow}{addr[0]}{rst}, replying with {bgreen}{proto}{rst}.') self.transport.sendto(reply, addr) else: if self.server.verbose >= 1: debug('Closing connection on {byellow}udp:{lport}{rst} with {byellow}{addr[0]}{rst}: {bred}{error}{rst}') else: info('Refusing connection on {byellow}udp:{lport}{rst} from {byellow}{addr[0]}{rst}: {bred}{error}{rst}')