def get_crack_mode(login_list, password_list, user, password):
    """Checks the mode the brute forcer will use, i.e. Whether
    nested loops are used for guessign or not"""

    #Check files exist and set mode
    if password_list and login_list:
        if not exists(password_list):
            bc.err("Password list : {} does not exist!".format(password_list))
            return False
        elif not exists(login_list):
            bc.err("User list : {} does not exist!".format(login_list))
            return False
        else:
            return 'double'
    elif password_list and user:
        if not exists(password_list):
            bc.err("Password list : {} does not exist!".format(password_list))
            return False
        else:
            return "password"
    elif login_list and password:
        if not exists(login_list):
            bc.err("User list : {} does not exist!".format(login_list))
            return False
        else:
            return "user"
    else:
        bc.err(
            "No valid brute force options. Try supplying a userlist, passwordlist or both."
        )
        return
def check_config(args, config):
    """Parse all our settings and return sanitised hook information, also check
            for argument and config file correct-ness"""

    # Work out what hook is being used and report
    if args.web_hook_url:
        job_hook = args.web_hook_url
        nm = job_hook
    else:
        try:
            nm = config[
                'default_hook'] if args.web_hook == 'default' else args.web_hook
            job_hook = config['hook_urls'][nm]
        except Exception as e:
            bcolors.err(
                "Error parsing webhook from config file:\n{}".format(e))
            bcolors.warn("Exiting")
            exit()

    # Get user information from config

    try:
        job_user = config['instance_info']
    except Exception as e:
        bcolors.err("Error getting User Config:\n{}".format(e))
        bcolors.warn("Continuing without user information")
        job_user = None

    return nm, job_hook, job_user
def get_crack_mode(login_list, password_list, user, password):

    #Check files exist and set mode
    if password_list and login_list:
        if not exists(password_list):
            bc.err("Password list : {} does not exist!".format(password_list))
            return False
        elif not exists(login_list):
            bc.err("User list : {} does not exist!".format(login_list))
            return False
        else:
            return 'double'
    elif password_list and user:
        if not exists(password_list):
            bc.err("Password list : {} does not exist!".format(password_list))
            return False
        else:
            return "password"
    elif login_list and password:
        if not exists(login_list):
            bc.err("User list : {} does not exist!".format(login_list))
            return False
        else:
            return "user"
    else:
        bc.err("No valid brute force options. Try supplying a userlist, passwordlist or both.")
        return
Exemple #4
0
def knock(host, ports, syn, default_proto, delay, verbose):
    for port in ports:
        #Handle tcp vs udp settings, either getting from global or port-specific setting
        if len(port.split(':')) == 2:
            port, proto = port.split(':')
        else:
            proto = default_proto

        #Now we're rid of proto, convert ports to integer
        try:
            port = int(port)
        except:
            bc.info("Unexpected error in port integer conversion:",
                    sys.exc_info()[0])
            raise
        if verbose:
            bc.info("Hitting Port {} with Proto {}".format(
                port, proto.upper()))
        if proto.lower() == "tcp" and not syn:
            result = tcp_connect(host, port)
        elif proto.lower() == "tcp":
            result = send_syn(host, port)
        elif proto.lower() == "syn":
            result = send_syn(host, port)
        elif proto.lower() == "udp":
            result = send_udp(host, port, b"")
        else:
            bc.err("Improper protocol '{}' set for port {}.".format(
                proto, port))

        #Wait
        if delay > 0:
            time.sleep(delay)
    return result
def get_config(config_file):
    try:
        with open(config_file, 'r') as y:
            config = yaml.load(y, Loader=yaml.FullLoader)
    except Exception as e:
        bcolors.err("Error getting yaml configuration:\n{}".format(e))
        bcolors.warn("Exiting")
        exit()
    return config
Exemple #6
0
def send_syn(host, port):
    syn_response = None
    try:
        #Send it, no waiting!
        syn_response = sr(IP(dst=host) / TCP(dport=port, flags='S'), timeout=0)
    except Exception as e:
        bc.err("Could not send SYN to {}:{} : \n{}".format(host, port, e))
        bc.warn("Check you have permissions to craft packets.")
        bc.err("Exiting.")
        sys.exit(0)
    #TODO validate Syn response and return 0 open, or 1 for closed/filtered
    return syn_response
Exemple #7
0
def check_root():
    if os.getuid() != 0:
        bc.err(
            "You're not running at root, you may not be able to knock properly."
        )
        decision = 'decision_placeholder'
        while decision != "y" or decision != "n":
            decision = input("Would you like to continue anyway?(y/n)").lower()
            if decision.lower() == "n":
                sys.exit(0)
            elif decision.lower() == 'y':
                break
Exemple #8
0
def tcp_connect(host, port):
    try:
        #Instantiate socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setblocking(False)  #Timeouts are bad
        socket_addr = (host, port)  #Setting up socket address
        result = s.connect_ex(socket_addr)
        if not s.connect_ex(socket_addr):
            return 0
        #select.select([s], [s], [s], self.timeout)
        #Close socket
        s.close()
    except:
        bc.err("Could not TCP connect to host on port {}.".format(port))

    return 1
Exemple #9
0
def main():
    #CLI Parsing - simple and dirty:
    if len(argv[1:]) != 1:
        app = basename(__file__)
        print("Usage: {} [number]".format(app))
        exit(0)

#Set up variables from CLI
    try:
        num = int(argv[1])
    except:
        bc.err('Cannot process argument. Is your input an integer?')
        exit(0)
    if is_prime(num):
        bc.success('Yes, {} is prime!'.format(num), True)
    else:
        bc.info('No, {} is not prime, sorry!'.format(num), True)
def format_hash(hash_string, hash_dict):
    """Takes the input hash string from our file and rationalises it
    into the algo salt, digest and if applicable, iterations for HMAC."""

    # We know mosquitto_passwd bans colons in the name and B64 is safe, so split
    user, hash_info = hash_string.split(":")
    if hash_info.count("$") == 4:
        junk, morejunk, salt, iterations, digest = hash_info.split("$")
        hash_type = 'pw_sha512_pbkdf2'
    elif hash_info.count("$") == 3:
        junk, morejunk, salt, digest = hash_info.split("$")
        hash_type = 'sha512'
        iterations = "1"
    else:
        bc.err("Error parsing hash - bad format:\n{}".format(hash_string))
        exit(0)

    return [hash_type, b64decode(salt), digest, user, iterations]
Exemple #11
0
def main():

    args = get_args()
    print_banner()
    check_root()

    #Set scan type, remove default TCP connect if Syn Scan
    #Also setup default protocols and TCP flags (if applicable)
    if args.syn:
        args.tcp_connect = False
    if args.udp:
        default_proto = "udp"
    else:
        default_proto = "tcp"

    #Format ports into list, check number of ports first
    if len(args.knock_ports.split(',')) < 2:
        bc.err("Error parsing knock ports!\t" + bc.UNDERLINE + \
                "Did you supply comma delimited ports?" + bc.ENDC)
        sys.exit(0)
    else:
        knock_ports = args.knock_ports.split(',')

#If not brute, knock
    if not args.brute:
        if args.verbose:
            bc.success("Starting knock against ports: {}".format(knock_ports))
        knock(args.host, knock_ports, args.syn, default_proto, args.delay,
              args.verbose)
    else:
        #BRUTE!
        bc.info("Bruting...")

    #If port to test - NOTE syn set to False, because we're looking for connection
    if args.target_port and knock(args.host, [args.target_port], False, \
            default_proto, args.delay, args.verbose) == 0:
        bc.success("Knock complete - {}, test port open!".format(
            bc.bold_format("success")))
    elif args.target_port:
        bc.err(
            "Knock complete - {} - test port filtered or closed... BEWARE UDP."
            .format(bc.bold_format("Failure")))
    else:
        bc.info("Knock complete.")
Exemple #12
0
def send_udp(host, port, message):
    #Todo - consider ICMP dest unreach as a filtered option
    try:
        #Instantiate socket
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        socket_addr = (host, port)  #Setting up socket address
        data = b'/?help\n'
        s.sendto(data, socket_addr)
        #Test for UDP response - Quick and dirty
        s.settimeout(5)
        try:
            s.recvfrom(1024)
            return 0
        except:
            return 1
        #Close socket
        s.close()
    except:
        bc.err("Could not send UDP packet to host on port {}.".format(port))
def single_crack(bruter, single, single_first, login_q, len_q):
    i = 0
    try:
        n_bruter = file_len(bruter)
        if single_first:
            bc.info("Attempting login for 1 user and {} passwords.".format(n_bruter), True)
        else:
            bc.info("Attempting login for {} users and 1 password.".format(n_bruter), True)
        len_q.put(n_bruter)
        #For each line in the file, bang it in the queue
        with open(bruter, 'r', encoding='latin-1') as bl:
        #with open(bruter, 'r', encoding='utf-8') as bl:
            for b in bl:
                b = b.strip()
                if not b: continue
                i+=1
                if single_first:
                    login_q.put([single, b])
                else:
                    login_q.put([b, single])
    except UnicodeDecodeError as e:
        bc.err("Error decoding on wordlist line {}\n{}.".format(i, e))
        bc.warn("Skipping guess")
    except BrokenPipeError as e:
        bc.err("Error communicating between processes : {}".format(e))
        bc.info("Continuing")
    except ConnectionResetError as e:
        bc.err("Error communicating between processes : {}".format(e))
        bc.info("Continuing")
    except KeyboardInterrupt:
        return
def double_crack(login_list, password_list, login_q, len_q):
    i = 0
    j = 0
    try:
        n_login = file_len(login_list)
        n_pass = file_len(password_list)
        bc.info("Attempting login for {} users and {} passwords.".format(n_login, n_pass), True)
        len_q.put(n_login*n_pass)
        #For each line in the file, bang it in the queue
        with open(login_list, 'r', encoding='latin-1') as ul:
            for u in ul:
                u = u.strip()
                if not u: continue
                i += 1
                with open(password_list, 'r', encoding='latin-1') as pl:
                    for p in pl:
                        p = p.strip()
                        if not p: continue
                        j += 1
                        login_q.put([u, p])
    except UnicodeDecodeError as e:
        bc.err("Error decoding at login_list line {} & password_list line {}\n{}.".format(i,j, e))
        bc.warn("Skipping guess")
    except BrokenPipeError as e:
        bc.err("Error communicating between processes : {}".format(e))
        bc.info("Continuing")
    except ConnectionResetError as e:
        bc.err("Error communicating between processes : {}".format(e))
        bc.info("Continuing")
    except KeyboardInterrupt:
        return
def main():
    #Mega basic command line parsing will do fine for our purposes
    try:
        if len(sys.argv[1:]) == 1:
            addresses = scrape_emails(sys.argv[1])
            if addresses is not None:
                bc.success("Found addresses :")
                for a in addresses:
                    print("\t{}".format(a))
        elif len(sys.argv[1:]) == 2:
            addresses = scrape_emails(sys.argv[1])
            if addresses is not None and not exists(sys.argv[2]):
                with open(sys.argv[2], "w") as f:
                    for address in addresses:
                        f.write(address + '\n')
            elif addresses is not None and exists(sys.argv[2]):
                answer = 'placeholder'
                fmt_str = bc.blue_format(
                        "[!] ", "- {} exists, overwrite, append or cancel [o/a/c]? :".format(
                                sys.argv[2]))
                while answer.lower() not in ['o','a','c']:
                    answer = input(fmt_str)
                if answer == 'c':
                    bc.info("Exiting.")
                    sys.exit(0)
                else:
                    mode = 'w' if answer == 'o' else 'a'
                    with open(sys.argv[2], mode) as f:
                        for address in addanswerresses:
                            f.write(address + '\n')

        else:
            app = basename(__file__)
            print('Usage: {} [target_url] [outfile (optional)]'.format(app))
    except Exception as e:
        bc.err("Error parsing emails: {}".format(e))
def main():

    #Setup initial variables
    args = get_args()

    #HTML Request Variables

    #Request data
    fmt_str = "{}={}&{}={}".format(args.user_param, "{}", args.pass_param, "{}")
    if args.extra_param:
        for a in args.extra_param:
            fmt_str = fmt_str + "&{}".format(a[0])
    #Headers
    hdr = {
            "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246",
            "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language" : "en-US,en;q=0.5",
            "Accept-Encoding" : "gzip, deflate",
            "Referer" : args.url,
            "Content-Type" : "application/x-www-form-urlencoded",
            "Connection" : "close",
            }

    #Get crack mode
    crack_mode = get_crack_mode(args.login_list, \
        args.password_list, args.login, args.password)

        #If there's a bad file provided or some other error in crack_mode derivation
    if not crack_mode : exit(0)

    #Instantiate workers
    m = multiprocessing.Manager()
    login_q = m.Queue()
    done_q = m.Queue()
    len_q = m.Queue()
    struck_gold = multiprocessing.Event()
    kill_flag = multiprocessing.Event()
    start_time = time()

    for i in range(args.threads):
         t = multiprocessing.Process(target=guesser, args=(args.url, fmt_str, hdr, \
            login_q, args.success_match, args.success_exclude, \
            kill_flag, struck_gold, done_q))
         t.start()

    #Now we have mode, carry out attack in whatever way specified
    if crack_mode == 'double':
        #double_crack(args.login_list, args.password_list, login_q, len_q)
        t = multiprocessing.Process(target=double_crack, args=(
            args.login_list, args.password_list, login_q, len_q, ))
    elif crack_mode == 'user':
        #single_crack(args.login_list, args.password, False, login_q, len_q)
        t = multiprocessing.Process(target=single_crack, args=(
            args.login_list, args.password, False, login_q, len_q, ))
    elif crack_mode == 'password':
        #single_crack(args.password_list, args.login, True, login_q, len_q)
        t = multiprocessing.Process(target=single_crack, args=(
            args.password_list, args.login, True, login_q, len_q, ))
    else:
        bc.err("Brute force mode invalid - {}. Exiting.".format(crack_mode))
        kill_flag.set()
        sleep(0.5)
        exit(0)

    bc.info("Workers initialised. Calculating effort required.")
    #Start the bruteforce thread, reading passwords into the worker queue
    t.start()

    #When available get the number of guesses
    n_guesses = len_q.get()
    #bc.info("guesses total : {}".format(n_guesses))
    last_progress = 0.0

    with progressbar.ProgressBar(max_value= n_guesses) as bar:
        while True:
            try:
                done = done_q.qsize()
            except Exception as e:
                bc.warn("Error when checking progress : {}".format(e))
                bc.info("Continuing")
            progress = round( (done / n_guesses ) * 100 , 0)
            if struck_gold.is_set() and not args.cont:
                kill_flag.set()
                bc.info("Creds found, continue flag not set. Finishing.")
                break
            elif progress >= 100.0 and login_q.empty():
                kill_flag.set()
                sleep(1)
                print()
                bc.info("Brute complete. Shutting down...")
                break
            else:
                #Just waiting for a mate
                bar.update(done)
                sleep(1)

    #Gracefully kill everything
    for p in multiprocessing.active_children():
        p.join(0.5)
Exemple #17
0
def main():
    """ACtually do the bruting"""

    #Setup initial variables
    args = get_args()

    #SMB variables
    t = args.timeout
    #Get crack mode
    crack_mode = get_crack_mode(args.login_list, \
        args.password_list, args.login, args.password)

    #If there's a bad file provided or some other error in crack_mode derivation
    if not crack_mode: exit(0)

    #Instantiate workers
    m = multiprocessing.Manager()
    login_q = m.Queue()
    done_q = m.Queue()
    len_q = m.Queue()
    struck_gold = multiprocessing.Event()
    kill_flag = multiprocessing.Event()
    start_time = time()

    for i in range(args.threads):
        t = multiprocessing.Process(target=guesser, args=(args.host,\
               args.domain, args.port, login_q, args.timeout, kill_flag, \
               struck_gold, done_q))
        t.start()

    #Now we have mode, carry out attack in whatever way specified
    if crack_mode == 'double':
        double_mode = double_crack if not args.spray else spray
        #double_crack(args.login_list, args.password_list, login_q, len_q)
        t = multiprocessing.Process(target=double_mode,
                                    args=(
                                        args.login_list,
                                        args.password_list,
                                        login_q,
                                        len_q,
                                    ))
    elif crack_mode == 'user':
        #single_crack(args.login_list, args.password, False, login_q, len_q)
        t = multiprocessing.Process(target=single_crack,
                                    args=(
                                        args.login_list,
                                        args.password,
                                        False,
                                        login_q,
                                        len_q,
                                    ))
    elif crack_mode == 'password':
        #single_crack(args.password_list, args.login, True, login_q, len_q)
        t = multiprocessing.Process(target=single_crack,
                                    args=(
                                        args.password_list,
                                        args.login,
                                        True,
                                        login_q,
                                        len_q,
                                    ))
    else:
        bc.err("Brute force mode invalid - {}. Exiting.".format(crack_mode))
        kill_flag.set()
        sleep(0.5)
        exit(0)

    bc.info("Workers initialised. Calculating effort required.")
    #Start the bruteforce thread, reading passwords into the worker queue
    t.start()

    #When available get the number of guesses
    n_guesses = len_q.get()
    #bc.info("guesses total : {}".format(n_guesses))
    last_progress = 0.0

    with progressbar.ProgressBar(max_value=n_guesses) as bar:
        while True:
            try:
                done = done_q.qsize()
            except Exception as e:
                bc.warn("Error when checking progress : {}".format(e))
                bc.info("Continuing")
            progress = round((done / n_guesses) * 100, 0)
            if struck_gold.is_set() and not args.cont:
                kill_flag.set()
                bc.info("Creds found, continue flag not set. Finishing.")
                break
            elif progress >= 100.0 and login_q.empty():
                kill_flag.set()
                sleep(1)
                print()
                bc.info("Brute complete. Shutting down...")
                break
            else:
                #Just waiting for a mate
                bar.update(done)
                sleep(1)

    #Gracefully kill everything
    for p in multiprocessing.active_children():
        p.join(0.5)
Exemple #18
0
            if struck_gold.is_set() and not args.cont:
                kill_flag.set()
                bc.info("Creds found, continue flag not set. Finishing.")
                break
            elif progress >= 100.0 and login_q.empty():
                kill_flag.set()
                sleep(1)
                print()
                bc.info("Brute complete. Shutting down...")
                break
            else:
                #Just waiting for a mate
                bar.update(done)
                sleep(1)

    #Gracefully kill everything
    for p in multiprocessing.active_children():
        p.join(0.5)

    #login_q.close()
    #login_q.join_thread()


if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        bc.err("Keyboard interrupt.Exiting.")
        for p in multiprocessing.active_children():
            p.join(0.5)
def main():
    """Do the main lifting!"""

    # Configuration and config stuff
    args = get_args()
    if args.config == 'resources/discordnotify.yml':
        config_file = dirname(realpath(__file__)) + \
                '/resources/discordnotify.yml'
    config = get_config(config_file)
    hook_name, hook, user = check_config(args, config)
    bcolors.info("Executing job: {}".format(bcolors.bold_format(args.command)),
                 strong=True)

    #Create main webhook for proc completion
    wh = DiscordWebhook(url=hook, \
            content="You've just started a job. Brace for updates...",\
            username=user['username'])
    embed = DiscordEmbed(title="Process running",\
            description="Full command line: {}".format(args.command), color=242424)
    if user['image']:
        embed.set_author(name="Job: {}".format(args.command.split(' ')[0]),
                         icon_url=user['image'])
    else:
        embed.set_author(name="Job: {}".format(args.command.split(' ')[0]))
    embed.set_footer(
        text="Sent with DiscordNotify by @blackf3ll - [email protected]")
    wh.add_embed(embed)
    sent_wh = wh.execute()

    #Pre-ampble and process start
    t1 = time()
    t2 = time()
    worker = False
    start_time = ctime()  #Human friendly :)
    output = ''
    p = subprocess.Popen(
            args.command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,\
            shell=True , encoding='utf-8', errors='replace')

    # Manage beat updates
    if args.beat:
        worker = True
        embed.add_embed_field(name="Job ongoing",
                              value="No updates yet...",
                              inline=False)
        stdout_q = multiprocessing.Queue()
        stdout_worker = multiprocessing.Process(target=stdout_reader,
                                                args=(p, stdout_q))
        stdout_worker.start()
        while p.poll() == None:
            try:
                while not stdout_q.empty():
                    output += stdout_q.get()
                t3 = time()
                if round(t3 - t2) >= args.beat:
                    t2 = int(t3)
                    # update embed summary data with stdout summary and time info
                    embed.fields[0]['value'] = \
                            "Started: {} Elapsed : {}s Output summary:\n{}".format(
                            start_time, round(t3-t1),trim_output(
                            output, config['instance_info']['max_embed_lines']))
                    wh.edit(sent_wh)  # and send it
            except Exception as e:
                bcolors.err("Error sending update:\n{}".format(e))

    # Mop up any un-read stdout and print to console
    output += p.stdout.read()  #.decode()
    duration = round(time() - t1)
    print(output)

    #Configure final report & embed in webhook
    was_error = "with errors" if p.returncode != 0 else "without errors"
    embed.add_embed_field(name="Process Complete",
                          value="Completed {} \
            (exit code {}) in {} Seconds".format(was_error, p.returncode,
                                                 duration),
                          inline=False)
    if output:
        out_summary = trim_output(output,
                                  config['instance_info']['max_embed_lines'])
    else:
        out_summary = "No data on STDOUT or STDERR."
    embed.add_embed_field(name="Stdout Summary",
                          value=out_summary,
                          inline=False)

    # Add any requested image - TODO - fix this so it works - add to file attachment?
    if args.image:
        embed.set_thumbnail(url='attachment://{}'.format(args.image))
    # Now send
    try:
        wh.edit(sent_wh)
    except Exception as e:
        bcolors.err("Failed to send update to Discord:\n{}".format(e))

    # Send any file on afterwards, to avoid conflictings file space/embed requirements
    if args.file:
        # Use a fresh webhook to avoid API limits and issues with large embeds
        filewh = DiscordWebhook(url=hook, \
                content="Here's the associated file for your job: {}.".format(
                args.command), username=user['username'])
        try:
            with open(args.file, "rb") as f:
                filewh.add_file(file=f.read(), filename=args.file)
                filewh.execute()
        except Exception as e:
            bcolors.err("Couldn't attach file : {} :\n{}".format(args.file, e))

    # Worker process cleanup
    if worker:
        stdout_worker.terminate()
        stdout_worker.join(5)