def exploit(self): """ Starts the exploiting phase, you should run setup before running this function. if auto is set, this function will fire the exploit to all systems. Otherwise a curses interface is shown. """ search = ServiceSearch() host_search = HostSearch() services = search.get_services(tags=['MS17-010']) services = [service for service in services] if len(services) == 0: print_error("No services found that are vulnerable for MS17-010") return if self.auto: print_success("Found {} services vulnerable for MS17-010".format( len(services))) for service in services: print_success("Exploiting " + str(service.address)) host = host_search.id_to_object(str(service.address)) system_os = '' if host.os: system_os = host.os else: system_os = self.detect_os(str(service.address)) host.os = system_os host.save() text = self.exploit_single(str(service.address), system_os) print_notification(text) else: service_list = [] for service in services: host = host_search.id_to_object(str(service.address)) system_os = '' if host.os: system_os = host.os else: system_os = self.detect_os(str(service.address)) host.os = system_os host.save() service_list.append({ 'ip': service.address, 'os': system_os, 'string': "{ip} ({os}) {hostname}".format(ip=service.address, os=system_os, hostname=host.hostname) }) draw_interface(service_list, self.callback, "Exploiting {ip} with OS: {os}")
def parse_domain_computers(filename): """ Parse the file and extract the computers, import the computers that resolve into jackal. """ with open(filename) as f: data = json.loads(f.read()) hs = HostSearch() count = 0 entry_count = 0 print_notification("Parsing {} entries".format(len(data))) for system in data: entry_count += 1 parsed = parse_single_computer(system) if parsed.ip: host = hs.id_to_object(parsed.ip) host.description.append(parsed.description) host.hostname.append(parsed.dns_hostname) if parsed.os: host.os = parsed.os host.domain_controller = parsed.dc host.add_tag('domaindump') host.save() count += 1 sys.stdout.write('\r') sys.stdout.write("[{}/{}] {} resolved".format(entry_count, len(data), count)) sys.stdout.flush() sys.stdout.write('\r') return count
def main(): hs = HostSearch() arg = argparse.ArgumentParser(parents=[hs.argparser], conflict_handler='resolve') arg.add_argument('-c', '--count', help="Only show the number of results", action="store_true") arg.add_argument('-a', '--add', help="Add a new range", action="store_true") arguments = arg.parse_args() if arguments.add: print_notification("Adding new host") address = input("What host do you want to add? ") host = hs.id_to_object(address) print_success("Added a new host:") print_json(host.to_dict(include_meta=True)) elif arguments.count: print_line("Number of hosts: {}".format(hs.argument_count())) else: response = hs.get_hosts() for hit in response: print_json(hit.to_dict(include_meta=True))
def import_smb(database_path): print_notification("Importing SMB database") conn = sqlite3.connect(database_path) host_search = HostSearch(use_pipe=False) host_map = {} # Inserting the hosts computer_count = 0 for computer in conn.execute("SELECT id, ip, hostname, domain, os, dc FROM computers"): host = host_search.id_to_object(computer[1]) if computer[2]: host.hostname.append(computer[2]) if computer[4]: host.os = computer[4] if computer[5]: host.domain_controller = computer[5] host_map[computer[0]] = computer[1] host.add_tag("cme_import") host.save() computer_count += 1 # Inserting the retrieved users, services and credentials. user_count = 0 admin_count = 0 user_search = UserSearch(use_pipe=False) for user in conn.execute("SELECT id, domain, username, password, credtype, pillaged_from_computerid FROM users"): # Add user jackal_user = user_search.id_to_object(user[2]) if user[1]: jackal_user.domain.append(user[1]) jackal_user.add_tag("cme_import") jackal_user.save() user_count += 1 try: address = host_map[user[5]] except KeyError: address = None # Add credential add_credential(user[2], user[3], user[1], address, user[4], port=445) for admin_host in conn.execute("SELECT computerid FROM admin_relations WHERE userid=?", (int(user[0]),)): admin_count += 1 admin_pc = host_map[admin_host[0]] add_credential(user[2], user[3], user[1], admin_pc, user[4], port=445, access_level='Administrator') conn.close() # Log the info stats = {} stats['hosts'] = computer_count stats['users'] = user_count stats['admins'] = admin_count stats['file'] = database_path Logger().log('cme_smb', "Imported CME smb database: {}".format(database_path), stats)
def import_nmap(result, tag, check_function=all_hosts, import_services=False): """ Imports the given nmap result. """ host_search = HostSearch(arguments=False) service_search = ServiceSearch() parser = NmapParser() report = parser.parse_fromstring(result) imported_hosts = 0 imported_services = 0 for nmap_host in report.hosts: if check_function(nmap_host): imported_hosts += 1 host = host_search.id_to_object(nmap_host.address) host.status = nmap_host.status host.add_tag(tag) if nmap_host.os_fingerprinted: host.os = nmap_host.os_fingerprint if nmap_host.hostnames: host.hostname.extend(nmap_host.hostnames) if import_services: for service in nmap_host.services: imported_services += 1 serv = Service(**service.get_dict()) serv.address = nmap_host.address service_id = service_search.object_to_id(serv) if service_id: # Existing object, save the banner and script results. serv_old = Service.get(service_id) if service.banner: serv_old.banner = service.banner # TODO implement # if service.script_results: # serv_old.script_results.extend(service.script_results) serv_old.save() else: # New object serv.address = nmap_host.address serv.save() if service.state == 'open': host.open_ports.append(service.port) if service.state == 'closed': host.closed_ports.append(service.port) if service.state == 'filtered': host.filtered_ports.append(service.port) host.save() if imported_hosts: print_success("Imported {} hosts, with tag {}".format( imported_hosts, tag)) else: print_error("No hosts found") return {'hosts': imported_hosts, 'services': imported_services}
def parse_ips(ips, netmask, include_public): """ Parses the list of ips, turns these into ranges based on the netmask given. Set include_public to True to include public IP adresses. """ hs = HostSearch() rs = RangeSearch() ranges = [] ips = list(set(ips)) included_ips = [] print_success("Found {} ips".format(len(ips))) for ip in ips: ip_address = ipaddress.ip_address(ip) if include_public or ip_address.is_private: # To stop the screen filling with ranges. if len(ips) < 15: print_success("Found ip: {}".format(ip)) host = hs.id_to_object(ip) host.add_tag('dns_discover') host.save() r = str(ipaddress.IPv4Network("{}/{}".format(ip, netmask), strict=False)) ranges.append(r) included_ips.append(ip) else: print_notification("Excluding ip {}".format(ip)) ranges = list(set(ranges)) print_success("Found {} ranges".format(len(ranges))) for rng in ranges: # To stop the screen filling with ranges. if len(ranges) < 15: print_success("Found range: {}".format(rng)) r = rs.id_to_object(rng) r.add_tag('dns_discover') r.save() stats = {} stats['ips'] = included_ips stats['ranges'] = ranges return stats
class Sniffer(object): """ Sniffer class """ def __init__(self, netmask='255.255.255.0', include_public=False, own_ip=None): self.ip_list = set() self.ip_ranges = set() self.rs = RangeSearch() self.hs = HostSearch() self.netmask = netmask self.include_public = include_public if own_ip: self.ip_list.add(own_ip) def callback(self, pkt): """ Callback for the scapy sniffer """ if ARP in pkt: self.parse_ip(pkt.sprintf("%ARP.psrc%")) if TCP in pkt or UDP in pkt: self.parse_ip(pkt.sprintf("%IP.src%")) self.parse_ip(pkt.sprintf("%IP.dst%")) def parse_ip(self, ip): """ Parses an ip to extract the range. Calls new_ip and new_range when a new ip is found. Excludes ranges that are multicast and loopback. """ if not ip in self.ip_list: try: ip_address = ipaddress.ip_address(ip) use = not (ip_address.is_multicast or ip_address.is_unspecified or ip_address.is_reserved or ip_address.is_loopback or ip_address.is_link_local) if use and (self.include_public or ip_address.is_private): self.new_ip(ip) network = ipaddress.IPv4Network("{}/{}".format( ip, self.netmask), strict=False) self.new_range(str(network)) except ValueError: pass def new_ip(self, ip): """ Function called when a new IP address was seen """ if not ip in self.ip_list: self.ip_list.add(ip) host = self.hs.id_to_object(ip) host.add_tag('sniffer') host.save() print_success("New ip address: {}".format(ip)) def new_range(self, ip_range): """ Function called when a new range was seen """ if not ip_range in self.ip_ranges: self.ip_ranges.add(ip_range) doc = self.rs.id_to_object(ip_range) doc.add_tag('sniffer') doc.save() print_success("New ip range: {}".format(ip_range)) def start(self, timeout=None): """ Starts the sniffing """ if timeout: print_notification( "Starting sniffer for {} seconds".format(timeout)) else: print_notification("Starting sniffer") print_notification("Press ctrl-c to stop sniffing") try: sniff(prn=self.callback, store=0, timeout=timeout) except PermissionError: print_error("Please run this tool as root")