Example #1
0
    def save_handshake(self, handshake):
        '''
            Saves a copy of the handshake file to hs/
            Args:
                handshake - Instance of Handshake containing bssid, essid, capfile
        '''
        # Create handshake dir
        if not os.path.exists(Configuration.wpa_handshake_dir):
            os.mkdir(Configuration.wpa_handshake_dir)

        # Generate filesystem-safe filename from bssid, essid and date
        essid_safe = re.sub('[^a-zA-Z0-9]', '', handshake.essid)
        bssid_safe = handshake.bssid.replace(':', '-')
        date = time.strftime('%Y-%m-%dT%H-%M-%S')
        cap_filename = 'handshake_%s_%s_%s.cap' % (essid_safe, bssid_safe,
                                                   date)
        cap_filename = os.path.join(Configuration.wpa_handshake_dir,
                                    cap_filename)

        Color.p('{+} saving copy of {C}handshake{W} to {C}%s{W} ' %
                cap_filename)
        copy(handshake.capfile, cap_filename)
        Color.pl('{G}saved{W}')

        # Update handshake to use the stored handshake file for future operations
        handshake.capfile = cap_filename
Example #2
0
 def fake_auth(self):
     '''
         Attempts to fake-authenticate with target.
         Returns: True if successful,
                  False is unsuccesful.
     '''
     Color.p('\r{+} attempting {G}fake-authentication{W} with {C}%s{W}...' % self.target.bssid)
     fakeauth = Aireplay.fakeauth(self.target, timeout=AttackWEP.fakeauth_wait)
     if fakeauth:
         Color.pl(' {G}success{W}')
     else:
         Color.pl(' {R}failed{W}')
         if Configuration.require_fakeauth:
             # Fakeauth is requried, fail
             raise Exception(
                 'Fake-authenticate did not complete within' +
                 ' %d seconds' % AttackWEP.fakeauth_wait)
         else:
             # Warn that fakeauth failed
             Color.pl('{!} {O}' +
                 'unable to fake-authenticate with target' +
                 ' (%s){W}' % self.target.bssid)
             Color.pl('{!} continuing attacks because' +
                 ' {G}--require-fakeauth{W} was not set')
     return fakeauth
Example #3
0
 def deauth(self, target_bssid, station_bssid=None):
     '''
         Sends deauthentication request.
         Args:
             target_bssid  - AP BSSID to deauth
             station_bssid - Client BSSID to deauth
                             Deauths 'broadcast' if no client is specified.
     '''
     # TODO: Print that we are deauthing and who we are deauthing!
     target_name = station_bssid
     if target_name == None:
         target_name = 'broadcast'
     command = [
         'aireplay-ng',
         '-0',  # Deauthentication
         '1',  # Number of deauths to perform.
         '-a',
         self.target.bssid
     ]
     command.append('--ignore-negative-one')
     if station_bssid:
         # Deauthing a specific client
         command.extend(['-c', station_bssid])
     command.append(Configuration.interface)
     Color.p(' {C}sending deauth{W} to {C}%s{W}' % target_name)
     return Process(command)
Example #4
0
    def forge_packet(xor_file, bssid, station_mac):
        ''' Forges packet from .xor file '''
        forged_file = 'forged.cap'
        cmd = [
            'packetforge-ng',
            '-0',
            '-a',
            bssid,  # Target MAC
            '-h',
            station_mac,  # Client MAC
            '-k',
            '192.168.1.2',  # Dest IP
            '-l',
            '192.168.1.100',  # Source IP
            '-y',
            xor_file,  # Read PRNG from .xor file
            '-w',
            forged_file,  # Write to
            Configuration.interface
        ]

        cmd = '"%s"' % '" "'.join(cmd)
        (out, err) = Process.call(cmd, cwd=Configuration.temp(), shell=True)
        if out.strip() == 'Wrote packet to: %s' % forged_file:
            return forged_file
        else:
            from Color import Color
            Color.pl('{!} {R}failed to forge packet from .xor file{W}')
            Color.pl('output:\n"%s"' % out)
            return None
Example #5
0
 def test_should_correct_minimum_average(self):
     # given
     color_low_average = Color(rgb=(20, 20, 20))
     # when
     color_low_average.correct_minimum_average(60)
     # then
     self.assertGreaterEqual(color_low_average.sum(), 60)
Example #6
0
class Colors(object):

    #This is a class that holds a list of colors.
    #To make a new color, name the color and type...
    #yellow=Color(255,255,0,255);
    """
    YOU:
        Define any colors you want here and get their values by calling
        Ex)Colors.red.getColor();
    """
    red=Color(255,0,0,255);
    green=Color(0,255,0,255);
    blue=Color(0,0,255,255);

    white=Color(255,255,255,255);
    black=Color(0,0,0,255);
        
    def __init__(self):
        pass;

    def getRandomColor(self):
        """
        Get a randomly generated color.
        """
        return ColorUtilities.randomColor();
Example #7
0
 def fake_auth(self):
     '''
         Attempts to fake-authenticate with target.
         Returns: True if successful,
                  False is unsuccesful.
     '''
     Color.p('\r{+} attempting {G}fake-authentication{W} with {C}%s{W}...' %
             self.target.bssid)
     fakeauth = Aireplay.fakeauth(self.target,
                                  timeout=AttackWEP.fakeauth_wait)
     if fakeauth:
         Color.pl(' {G}success{W}')
     else:
         Color.pl(' {R}failed{W}')
         if Configuration.require_fakeauth:
             # Fakeauth is requried, fail
             raise Exception('Fake-authenticate did not complete within' +
                             ' %d seconds' % AttackWEP.fakeauth_wait)
         else:
             # Warn that fakeauth failed
             Color.pl('{!} {O}' +
                      'unable to fake-authenticate with target' +
                      ' (%s){W}' % self.target.bssid)
             Color.pl('{!} continuing attacks because' +
                      ' {G}--require-fakeauth{W} was not set')
     return fakeauth
Example #8
0
    def print_targets(self):
        '''
            Prints targets to console
        '''
        if len(self.targets) == 0:
            Color.p('\r')
            return

        if self.previous_target_count > 0:
            # We need to "overwrite" the previous list of targets.
            if Configuration.verbose <= 1:
                # Don't clear screen buffer in verbose mode.
                if self.previous_target_count > len(self.targets) or \
                   Scanner.get_terminal_height() < self.previous_target_count + 3:
                    # Either:
                    # 1) We have less targets than before, so we can't overwrite the previous list
                    # 2) The terminal can't display the targets without scrolling.
                    # Clear the screen.
                    from Process import Process
                    Process.call('clear')
                else:
                    # We can fit the targets in the terminal without scrolling
                    # "Move" cursor up so we will print over the previous list
                    Color.pl(Scanner.UP_CHAR * (3 + self.previous_target_count))

        self.previous_target_count = len(self.targets)

        # Overwrite the current line
        Color.p('\r')

        Target.print_header()
        for (index, target) in enumerate(self.targets):
            index += 1
            Color.clear_entire_line()
            Color.pl('   {G}%s %s' % (str(index).rjust(3), target))
Example #9
0
    def run(self):
        '''
            Initiates full WPA hanshake capture attack.
        '''

        # Check if user only wants to run PixieDust attack
        if Configuration.wps_only and self.target.wps:
            Color.pl('\r{!} {O}--wps-only{R} set, ignoring WPA-handshake attack on {O}%s{W}' % self.target.essid)
            self.success = False
            return self.success

        handshake = None

        # Capture the handshake ("do it live!")
        if handshake is None:
            handshake = self.capture_handshake()

        if handshake is None:
            # Failed to capture handshake
            self.success = False
            return self.success

        # Analyze handshake
        Color.pl('\n{+} analysis of captured handshake file:')
        handshake.analyze()

        # Crack it
        key = self.crack_handshake(handshake, Configuration.wordlist)
        if key is None:
            self.success = False
        else:
            self.crack_result = CrackResultWPA(handshake.bssid, handshake.essid, handshake.capfile, key)
            self.crack_result.dump()
            self.success = True
        return self.success
Example #10
0
def initialize(app, params):
    # Set GPIO pins for R, G, B wires
    params["PIN_R"] = 17
    params["PIN_G"] = 22
    params["PIN_B"] = 24

    # Create Actions
    actionWhite = app.addAction(ActionColor(params))
    actionBlue = app.addAction(ActionColor(params, Color(0, 0, 255)))
    actionStrobe = app.addAction(ActionStrobe(params))
    actionStrobeMute = app.addAction(ActionStrobeMute(params))
    actionMute = app.addAction(ActionMute(params))
    actionChaos = app.addAction(ActionChaos(params))

    # Bind Inputs to Actions
    app.addInput(actionMute, "hold", 45, "On")
    app.addInput(actionChaos, "hold", 44, "Intensity")
    app.addInput(actionWhite, "hold", 46, "Intensity")
    app.addInput(actionStrobeMute, "hold", 47, "On")

    app.addInput(actionBlue, "knob", 3, "Intensity")
    app.addInput(actionStrobe, "knob", 7, "Intensity")
    app.addInput(actionStrobe, "knob", 8, "Speed")
    app.addInput(actionStrobeMute, "knob", 10, "Speed")

    # Use ActionBuilder (optional)
    ActionBuilder.buildKeys(app, 48, 72, Color.red(), Color.blue())
Example #11
0
 def check_win_condition(self):
     blue_territories = self.board.find_territories_with_color(Color.Blue)
     red_territories = self.board.find_territories_with_color(Color.Red)
     if not blue_territories:
         self.winner = Color.to_str(Color.Red)
     if not red_territories:
         self.winner = Color.to_str(Color.Blue)
def setPixelAlphasFromIntsRandom(image, ints):
    """
    Encrypt the message into the image's alpha values starting in a random order.
    """
    cleanImage(image)
    pixelData = list(image.getdata())

    length = len(ints)
    rand = int(len(pixelData) / length)

    position = 0

    randomPosition = []
    for i in range(length):
        value = random.randint(position, (rand - 1) + position)
        randomPosition.append(value)
        position += value - position

    for x in range(len(ints)):
        r = 0
        g = 0
        b = 0
        a = 0
        try:
            r, g, b, a = pixelData[randomPosition[x]]
        except:
            r, g, b = pixelData[randomPosition[x]]
            a = 255
        color = Color(r, g, b, a)
        color.alpha = ints[x]
        pixelData[randomPosition[x]] = color.getColor()
    image.putdata(pixelData)
Example #13
0
 def __init__(self, n):
     self.n = n
     self.size = Hexagon.size
     self.width = self.size
     self.height = self.size * 3 // 4
     # 正六角形の左下の頂点から反時計回りに座標を取得する際のオフセット
     self.vertexes_offset = [[0, 0], [self.width // 3, 0],
                             [self.width * 2 // 3, -self.height // 2],
                             [self.width // 3, -self.height],
                             [0, -self.height],
                             [-self.width // 3, -self.height // 2]]
     self.hexagons = []
     self.rank = []
     self.coordinate_offset = [[1, 1], [1, 0], [0, -1], [-1, -1], [-1, 0],
                               [0, 1]]
     self.vertex_index = {}
     colors = Color(n)
     k = self.n - 1
     l = 0
     ct = 0
     for i in range(2 * n - 1):  # x成分
         if i < n:
             k += 1
         else:
             l += 1
         for j in range(l, k):  # y成分
             if i == 0 or i == 2 * n - 2 or j == 0 or j == 2 * n - 2 or j == l or j == k - 1:
                 self.hexagons.append(Hexagon(i, j, Color.WALL_COLOR, True))
             else:
                 self.hexagons.append(
                     Hexagon(i, j, colors.get_color(), False))
             self.vertex_index[(i, j)] = ct
             ct += 1
Example #14
0
    def select_targets(self):
        ''' Asks user to select target(s) '''

        if len(self.targets) == 0:
            # TODO Print a more-helpful reason for failure.
            # 1. Link to wireless drivers wiki,
            # 2. How to check if your device supporst monitor mode,
            # 3. Provide airodump-ng command being executed.
            raise Exception("No targets found."
                + " You may need to wait longer,"
                + " or you may have issues with your wifi card")

        self.print_targets()
        Color.clear_entire_line()
        input_str  = '{+} select target(s)'
        input_str += ' ({G}1-%d{W})' % len(self.targets)
        input_str += ' separated by commas, dashes'
        input_str += ' or {G}all{W}: '

        chosen_targets = []
        for choice in raw_input(Color.s(input_str)).split(','):
            if choice == 'all':
                chosen_targets = self.targets
                break
            if '-' in choice:
                # User selected a range
                (lower,upper) = [int(x) - 1 for x in choice.split('-')]
                for i in xrange(lower, min(len(self.targets), upper)):
                    chosen_targets.append(self.targets[i])
            elif choice.isdigit():
                choice = int(choice) - 1
                chosen_targets.append(self.targets[choice])
            else:
                pass
        return chosen_targets
Example #15
0
    def __init__(self, fileName):
        f = open(fileName, 'r')
        x = f.readline().strip()
        if ('P3' != x):
            print('Exception')

        x = f.readline().strip()
        dimensions = x.split(' ')
        self.collumns = int(dimensions[0])
        self.rows = int(dimensions[1])
        self.colorSize = int(f.readline().strip())

        print self.collumns
        print self.rows
        print self.colorSize
        print ""

        self.data = [[Color()] * self.collumns] * self.rows

        self.data = np.array(self.data)
        print np.shape(self.data)

        for i in range(self.rows):
            x = f.readline().strip().split(' ')
            for j in range(self.collumns):
                self.data[i][j] = Color(int(x[j * 3]), int(x[j * 3 + 1]),
                                        int(x[j * 3 + 2]))
Example #16
0
    def files_with_definitions_dependencies(self, path):
        file_names = FilesDependencies.find_files_in_directory(self, path)
        names = []
        sizes = []
        graph = Digraph('filesMethodsDefinitionsGraph', strict=True, format='pdf', filename='filesMethodsDefinitionsGraph',
                        node_attr={'color': 'khaki', 'style': 'filled', 'shape': 'doublecircle'})
        graph.attr(size='50', labelloc='b', label='Version: \n' + HashCommit.get_commit_hash(path))
        color = Color()
        for i in file_names:
            tmp = i.split(" ")
            names.append(tmp[0])
            sizes.append(tmp[1])

        for file, size in zip(names, sizes):
            same_function_dependencies = FilesWithDefinitionsDependencies.methods_in_file(self, path, file)
            graph.node(file, **{'width': str(float(size) / 15000), 'height': str(float(size) / 15000),
                                'color': color.__str__()})
            for i in same_function_dependencies[file]:
                graph.edge(i, file)
            color.h += 0.05
        try:
            graph.view(tempfile.mktemp('.filesMethodsDefinitionsGraph'))
        except Exception:
            from gui.Window import Window
            Window.show_error(Window)
Example #17
0
 def stderr(self):
     ''' Waits for process to finish, returns stderr output '''
     self.get_output()
     if Configuration.verbose > 1 and self.err.strip() != '':
         Color.pe("{P} [stderr] %s{W}" %
                  '\n [stderr] '.join(self.err.split('\n')))
     return self.err
Example #18
0
 def dump(self):
     if self.essid:
         Color.pl('{+} %s: {C}%s{W}' % (      'ESSID'.rjust(12), self.essid))
     Color.pl('{+} %s: {C}%s{W}'     % (      'BSSID'.rjust(12), self.bssid))
     Color.pl('{+} %s: {C}WPA{W} ({C}WPS{W})' % 'Encryption'.rjust(12))
     Color.pl('{+} %s: {G}%s{W}'     % (     'WPS PIN'.rjust(12), self.pin))
     Color.pl('{+} %s: {G}%s{W}'     % ('PSK/Password'.rjust(12), self.psk))
Example #19
0
 def __init__(self, master, *ap, **an):
     """Инициализация с параметрами по умолчанию:
         круглая кисть;
         случайная палитра;
         константная функция масштаба;
         8 симметричных отображений"""
     Canvas.__init__(self, master, *ap, **an)
     self.fig_size = START_FIGURE_SIZE
     self.fig_type = 'circle'
     # None в color_pick означает, что будет выбираться автоматически
     self.color_pick = None
     # стартовый цвет
     self.color = Color()
     # привязки функций-обработчиков
     self.binding_functions()
     # загрузка палитры
     self.color.define_palette(-1)
     # выбор функции масштаба
     self.set_scale_function("constant")
     # число симметричных отображений
     self.num_symm = 16
     # история - список из HistoryRecord
     self.history = []
     # время (каждый клик мышкой увеличивает время на 1)
     self.time = 0
     self.recalculate_coefficients()
Example #20
0
    def run(self):
        ''' Run all WPS-related attacks '''

        # Drop out if user specified to not use Reaver
        if Configuration.no_reaver:
            self.success = False
            return self.success

        # Run Pixie-Dust attack
        if self.is_pixiedust_supported():
            if self.run_pixiedust_attack():
                # Pixie-Dust attack succeeded. We're done.
                self.success = True
                return self.success
        else:
            Color.pl(
                '{!} {R}your version of "reaver" does not' +
                ' support the {O}WPS pixie-dust attack{W}')

        if Configuration.pixie_only:
            Color.pl('{!} {O}--pixie{R} set, ignoring WPS-PIN attack{W}')
            self.success = False
        else:
            # Run WPS-PIN attack
            self.success = self.run_wps_pin_attack()
        return self.success
Example #21
0
 def __init__(self):
     self.baseColor = Color((1, 1, 1))  #white
     self.otherColor = Color((0, 0, 0))  #black
     self.ambientComp = 1.0
     self.diffusComp = 0.6
     self.specularComp = 0.4
     self.checkSize = 2.5
Example #22
0
    def found_target(self):
        '''
            Check if we discovered the target AP
            Returns: the Target if found,
                     Otherwise None.
        '''
        bssid = Configuration.target_bssid
        essid = Configuration.target_essid

        if bssid == None and essid == None:
            return False

        for target in self.targets:
            if bssid and bssid.lower() == target.bssid.lower():
                self.target = target
                break
            if essid and essid.lower() == target.essid.lower():
                self.target = target
                break

        if self.target:
            Color.pl('\n{+} {C}found target{G} %s {W}({G}%s{W})'
                % (self.target.bssid, self.target.essid))
            return True

        return False
Example #23
0
class TestColor(unittest.TestCase):
    """Palette is used in color"""
    def setUp(self):
        self.color = Color()

    def test_color(self):
        self.assertEqual(self.color.code, "#969696")
        self.assertEqual(self.color.color_dif, 30)

    def test_color_decode(self):
        self.color.code = "#000000"
        self.color.decode()
        self.assertEqual([self.color.red, self.color.green, self.color.blue],
                         [0, 0, 0])

    def test_color_next(self):
        self.assertEqual(next(self.color), "#969696")
        self.assertEqual(len(next(self.color)), 7)

    def test_color_mut(self):
        self.color.random_color = -2
        next(self.color)
        for i in range(10):
            self.assertLess(self.color.red, 181)
            self.assertLess(self.color.green, 181)
            self.assertLess(self.color.blue, 181)
            self.assertGreater(self.color.red, 119)
            self.assertGreater(self.color.green, 119)
            self.assertGreater(self.color.blue, 119)

    def test_define_palette(self):
        self.color.define_palette(1)
        self.assertEqual(next(self.color.palette), "#000040")
        self.assertEqual(next(self.color.palette), "#00003D")
Example #24
0
    def run(self):
        ''' Run all WPS-related attacks '''

        # Drop out if user specified to not use Reaver
        if Configuration.no_reaver:
            self.success = False
            return self.success

        # Run Pixie-Dust attack
        if self.is_pixiedust_supported():
            if self.run_pixiedust_attack():
                # Pixie-Dust attack succeeded. We're done.
                self.success = True
                return self.success
        else:
            Color.pl(
                "{!} {R}your version of 'reaver' does not support the {O}WPS pixie-dust attack{W}"
            )

        if Configuration.pixie_only:
            Color.pl('\r{!} {O}--pixie{R} set, ignoring WPS-PIN attack{W}')
            self.success = False
        else:
            # Run WPS-PIN attack
            self.success = self.run_wps_pin_attack()
        return self.success
Example #25
0
    def found_target(self):
        '''
            Check if we discovered the target AP
            Returns: the Target if found,
                     Otherwise None.
        '''
        bssid = Configuration.target_bssid
        essid = Configuration.target_essid

        if bssid == None and essid == None:
            return False

        for target in self.targets:
            if bssid and bssid.lower() == target.bssid.lower():
                self.target = target
                break
            if essid and essid.lower() == target.essid.lower():
                self.target = target
                break

        if self.target:
            Color.pl('\n{+} {C}found target{G} %s {W}({G}%s{W})'
                % (self.target.bssid, self.target.essid))
            return True

        return False
Example #26
0
    def __init__(self,
                 command,
                 devnull=False,
                 stdout=PIPE,
                 stderr=PIPE,
                 cwd=None,
                 bufsize=0):
        ''' Starts executing command '''

        if type(command) is str:
            # Commands have to be a list
            command = command.split(' ')

        self.command = command

        if Configuration.verbose > 1:
            Color.pe("\n {C}[?] {W} Executing: {B}%s{W}" % ' '.join(command))

        self.out = None
        self.err = None
        if devnull:
            sout = Process.devnull()
            serr = Process.devnull()
        else:
            sout = stdout
            serr = stderr

        self.start_time = time.time()

        self.pid = Popen(command,
                         stdout=sout,
                         stderr=serr,
                         cwd=cwd,
                         bufsize=bufsize)
Example #27
0
    def __init__(self, lado, color):
        #Ya no puedo usar super porque los padres
        #tienen distinta prioridad pero siempre figura sera donde busque

        Figura.__init__(
            self, lado, lado
        )  #Debo pasar self porque desde la clase padre toco una referencia que es de un hijo
        Color.__init__(self, color)
Example #28
0
 def crack_handshake(self, handshake):
     cap_file = os.path.realpath(handshake["handshake_file"])
     Color.pl("{+} Different ways to crack {C}%s{W}:" % cap_file)
     self.print_aircrack(cap_file)
     self.print_pyrit(cap_file)
     self.print_john(cap_file)
     self.print_oclhashcat(cap_file)
     Color.pl("")
Example #29
0
 def crack_handshake(self, handshake):
     cap_file = os.path.realpath(handshake["handshake_file"])
     Color.pl("{+} Different ways to crack {C}%s{W}:" % cap_file)
     self.print_aircrack(cap_file)
     self.print_pyrit(cap_file)
     self.print_john(cap_file)
     self.print_oclhashcat(cap_file)
     Color.pl("")
Example #30
0
 def dump(self):
     if self.essid:
         Color.pl('{+}      ESSID: {C}%s{W}' % self.essid)
     Color.pl('{+}      BSSID: {C}%s{W}' % self.bssid)
     Color.pl('{+} Encryption: {C}%s{W}' % self.result_type)
     Color.pl('{+}    Hex Key: {G}%s{W}' % self.hex_key)
     if self.ascii_key:
         Color.pl('{+}  Ascii Key: {G}%s{W}' % self.ascii_key)
Example #31
0
 def dump(self):
     if self.essid:
         Color.pl('{+}      ESSID: {C}%s{W}' % self.essid)
     Color.pl('{+}      BSSID: {C}%s{W}' % self.bssid)
     Color.pl('{+} Encryption: {C}%s{W}' % self.result_type)
     Color.pl('{+}    Hex Key: {G}%s{W}' % self.hex_key)
     if self.ascii_key:
         Color.pl('{+}  Ascii Key: {G}%s{W}' % self.ascii_key)
 def colorEvolution(img1, contour1, img2, contour2):
     '''
         returns the evolution of color
     '''
     nbColors1 = Color.colorHSVIntervals(img1, contour1)
     nbColors2 = Color.colorHSVIntervals(img2, contour2)
     evolutionC = abs(nbColors1 - nbColors2)
     return evolutionC
Example #33
0
    def create_timed(self, blueprint):
        """ Create a Target that disappears after some time. """
        attr = blueprint.attributes

        # WHEN SHOT AT
        # ===================================================================
        actions = [
            self.actions[AC.REWARD], self.actions[AC.SPAWN],
            self.actions[AC.DESPAWN_GOOD]
        ]
        blueprint.events[TR.SHOT_AT] = actions[:]

        # WHEN TIMED OUT
        # ===================================================================
        actions = [
            self.actions[AC.SPAWN], self.actions[AC.PENALTY],
            self.actions[AC.DESPAWN_BAD]
        ]
        blueprint.events[TR.TIME_EXPIRED] = actions[:]

        # COLOR
        # ===================================================================
        attr[AT.COLORS] = {
            'frame': Color(rgb=Color.WHITE),
            'bg': Color(rgb=Color.BLACK),
            'text': random_text_color()
        }

        # INTERACTIONS
        # ===================================================================
        attr[AT.VALUE_STRATEGY] = ValueStrategy.RANDOM_BY_STRENGTH

        vc = ValueChanger()
        vc.strategy = RewardStrategy.TIME_LEFT
        strength = int(attr[AT.STRENGTH])
        vc.stiff_value = max(1, 20 * (strength - 3) * (1 + strength / 10))
        vc.base_value = 20 + strength * 10
        vc.base_multiplier = 1
        attr[AT.REWARD] = vc

        vc = ValueChanger()
        vc.strategy = PenaltyStrategy.HARD_SET
        vc.stiff_value = strength * strength * -1
        vc.base_value = strength * -5
        vc.base_multiplier = 1
        attr[AT.PENALTY] = vc
        attr[AT.TIME_TO_EXPIRE] = (strength + 1) * 1500

        # SPAWN
        # ===================================================================
        spawn_blueprint = TargetBlueprint()
        spawn_attr = spawn_blueprint.attributes
        spawn_attr[AT.TARGET_TYPE] = TargetType.TIMED
        spawn_attr[AT.STRENGTH] = min(attr[AT.STRENGTH] + STRENGTH_INCREASE, 9)
        spawn_attr[AT.POSITION] = attr[AT.POSITION]
        attr[AT.SPAWN_BLUEPRINT] = spawn_blueprint

        return blueprint
Example #34
0
 def assert_greater(self, case1, case2, message):
     if case1 > case2:
         return True
     else:
         Color.print_red_text("%s::::Assert %s is greater than %s.\n" %
                              (message, str(case1), str(case2)))
         self.success = False
         print_trace_back()
         return False
Example #35
0
 def assert_not_equal(self, case1, case2, message):
     if not case1 == case2:
         return True
     else:
         Color.print_red_text("%s::::Assert %s isn't equal to %s.\n" %
                              (message, str(case1), str(case2)))
         self.success = False
         print_trace_back()
         return False
Example #36
0
 def print_oclhashcat(self, cap_file):
     if not Process.exists("hashcat"): return
     Color.pl("\n  {O}# OCLHASHCAT: GPU-based cracking. Fast.")
     hccapx_file = "generated.hccapx"
     if Process.exists("cap2hccapx"):
         Color.pl("  {G}cap2hccapx {C}%s %s{W}" % (cap_file, hccapx_file))
     else:
         Color.pl("  {O}# Visit https://hashcat.net/cap2hccapx to generate a .hccapx file{W}")
         Color.pl("  {O}# Browse -> %s -> Convert" % cap_file)
     Color.pl("  {G}hashcat {W}-m 2500 {C}%s %s{W}" % (hccapx_file, self.wordlist))
Example #37
0
    def start(iface):
        '''
            Starts an interface (iface) in monitor mode
            Args:
                iface - The interface to start in monitor mode
                        Either an instance of Interface object,
                        or the name of the interface (string).
            Returns:
                Name of the interface put into monitor mode.
            Throws:
                Exception - If an interface can't be put into monitor mode
        '''
        # Get interface name from input
        if type(iface) == Interface:
            iface = iface.name
        Airmon.base_interface = iface

        # Call airmon-ng
        Color.p("{+} enabling {G}monitor mode{W} on {C}%s{W}... " % iface)
        (out,err) = Process.call('airmon-ng start %s' % iface)

        # Find the interface put into monitor mode (if any)
        mon_iface = None
        for line in out.split('\n'):
            if 'monitor mode' in line and 'enabled' in line and ' on ' in line:
                mon_iface = line.split(' on ')[1]
                if ']' in mon_iface:
                    mon_iface = mon_iface.split(']')[1]
                if ')' in mon_iface:
                    mon_iface = mon_iface.split(')')[0]
                break

        if mon_iface == None:
            # Airmon did not enable monitor mode on an interface
            Color.pl("{R}failed{W}")

        mon_ifaces = Airmon.get_interfaces_in_monitor_mode()

        # Assert that there is an interface in monitor mode
        if len(mon_ifaces) == 0:
            Color.pl("{R}failed{W}")
            raise Exception("iwconfig does not see any interfaces in Mode:Monitor")

        # Assert that the interface enabled by airmon-ng is in monitor mode
        if mon_iface not in mon_ifaces:
            Color.pl("{R}failed{W}")
            raise Exception("iwconfig does not see %s in Mode:Monitor" % mon_iface)

        # No errors found; the device 'mon_iface' was put into MM.
        Color.pl("{G}enabled {C}%s{W}" % mon_iface)

        Configuration.interface = mon_iface

        return mon_iface
Example #38
0
 def save(self):
     ''' Adds this crack result to the cracked file and saves it. '''
     name = CrackResult.cracked_file
     json = []
     if os.path.exists(name):
         f = open(name, 'r')
         text = f.read()
         f.close()
         try:
             json = loads(text)
         except Exception, e:
             Color.pl('{!} error while loading %s: %s' % (name, str(e)))
Example #39
0
    def print_pairs(pairs, capfile, tool=None):
        '''
            Prints out BSSID and/or ESSID given a list of tuples (bssid,essid)
        '''
        tool_str = ''
        if tool:
            tool_str = '{C}%s{W}: ' % tool.rjust(8)

        if len(pairs) == 0:
            Color.pl("{!} %s.cap file {R}does not{O} contain a valid handshake{W}"
                % (tool_str))
            return

        for (bssid, essid) in pairs:
            if bssid and essid:
                Color.pl('{+} %s.cap file' % tool_str +
                         ' {G}contains a valid handshake{W}' +
                         ' for {G}%s{W} ({G}%s{W})' % (bssid, essid))
            elif bssid:
                Color.pl('{+} %s.cap file' % tool_str +
                         ' {G}contains a valid handshake{W}' +
                         ' for {G}%s{W}' % bssid)
            elif essid:
                Color.pl('{+} %s.cap file' % tool_str +
                         ' {G}contains a valid handshake{W}' +
                         ' for ({G}%s{W})' % essid)
Example #40
0
    def __str__(self):
        ''' Colored string representation of interface '''
        s = Color.s("{W}%s" % self.phy)
        s += ' ' * max(Interface.PHY_LEN - len(self.phy), 0)

        s += Color.s("{G}%s" % self.name)
        s += ' ' * max(Interface.NAME_LEN - len(self.name), 0)

        s += Color.s("{C}%s" % self.driver)
        s += ' ' * max(Interface.DRIVER_LEN - len(self.driver), 0)

        s += Color.s("{W}%s" % self.chipset)
        s += ' ' * max(Interface.CHIPSET_LEN - len(self.chipset), 0)
        return s
Example #41
0
    def save_handshake(self, handshake):
        '''
            Saves a copy of the handshake file to hs/
            Args:
                handshake - Instance of Handshake containing bssid, essid, capfile
        '''
        # Create handshake dir
        if not os.path.exists(Configuration.wpa_handshake_dir):
            os.mkdir(Configuration.wpa_handshake_dir)

        # Generate filesystem-safe filename from bssid, essid and date
        essid_safe = re.sub('[^a-zA-Z0-9]', '', handshake.essid)
        bssid_safe = handshake.bssid.replace(':', '-')
        date = time.strftime('%Y-%m-%dT%H-%M-%S')
        cap_filename = 'handshake_%s_%s_%s.cap' % (essid_safe, bssid_safe, date)
        cap_filename = os.path.join(Configuration.wpa_handshake_dir, cap_filename)

        if Configuration.wpa_strip_handshake:
            Color.p("{+} {C}stripping{W} non-handshake packets, saving to {G}%s{W}..." % cap_filename)
            handshake.strip(outfile=cap_filename)
            Color.pl('{G}saved{W}')
        else:
            Color.p('{+} saving copy of {C}handshake{W} to {C}%s{W} ' % cap_filename)
            copy(handshake.capfile, cap_filename)
            Color.pl('{G}saved{W}')

        # Update handshake to use the stored handshake file for future operations
        handshake.capfile = cap_filename
Example #42
0
    def call(command, cwd=None,shell=False):
        '''
            Calls a command (either string or list of args).
            Returns tuple:
                (stdout, stderr)
        '''
        if type(command) != str or ' ' in command or shell:
            shell = True
            if Configuration.verbose > 1:
                Color.pe("\n {C}[?] {W} Executing (Shell): {B}%s{W}" % command)
        else:
            shell = False
            if Configuration.verbose > 1:
                Color.pe("\n {C}[?]{W} Executing: {B}%s{W}" % command)

        pid = Popen(command, cwd=cwd, stdout=PIPE, stderr=PIPE, shell=shell)
        pid.wait()
        (stdout, stderr) = pid.communicate()

        if Configuration.verbose > 1 and stdout.strip() != '':
            Color.pe("{P} [stdout] %s{W}" % '\n [stdout] '.join(stdout.split('\n')))
        if Configuration.verbose > 1 and stderr.strip() != '':
            Color.pe("{P} [stderr] %s{W}" % '\n [stderr] '.join(stderr.split('\n')))

        return (stdout, stderr)
Example #43
0
    def print_targets(self):
        '''
            Prints targets to console
        '''
        if len(self.targets) == 0:
            Color.p('\r')
            return

        if self.previous_target_count > 0:
            # We need to "overwrite" the previous list of targets.
            if self.previous_target_count > len(self.targets) or \
               Scanner.get_terminal_height() < self.previous_target_count + 3:
                # Either:
                # 1) We have less targets than before, so we can't overwrite the previous list
                # 2) The terminal can't display the targets without scrolling.
                # Clear the screen.
                from Process import Process
                Process.call('clear')
            else:
                # We can fit the targets in the terminal without scrolling
                # "Move" cursor up so we will print over the previous list
                Color.pl(Scanner.UP_CHAR * (3 + self.previous_target_count))

        self.previous_target_count = len(self.targets)

        # Overwrite the current line
        Color.p('\r')

        Target.print_header()
        for (index, target) in enumerate(self.targets):
            index += 1
            Color.pl('   {G}%s %s' % (str(index).rjust(3), target))
Example #44
0
    def select_targets(self):
        ''' Asks user to select target(s) '''

        if len(self.targets) == 0:
            # TODO Print a more-helpful reason for failure.
            # 1. Link to wireless drivers wiki,
            # 2. How to check if your device supporst monitor mode,
            # 3. Provide airodump-ng command being executed.
            raise Exception("No targets found."
                + " You may need to wait longer,"
                + " or you may have issues with your wifi card")

        self.print_targets()
        input_str  = '{+} select target(s)'
        input_str += ' ({G}1-%d{W})' % len(self.targets)
        input_str += ' separated by commas, dashes'
        input_str += ' or {G}all{W}: '

        chosen_targets = []
        for choice in raw_input(Color.s(input_str)).split(','):
            if choice == 'all':
                chosen_targets = self.targets
                break
            if '-' in choice:
                # User selected a range
                (lower,upper) = [int(x) - 1 for x in choice.split('-')]
                for i in xrange(lower, upper):
                    chosen_targets.append(self.targets[i])
            else:
                choice = int(choice) - 1
                chosen_targets.append(self.targets[choice])
        return chosen_targets
Example #45
0
    def user_wants_to_continue(self, attack_index):
        ''' Asks user if attacks should continue using remaining methods '''
        Color.pl('\n{!} {O}interrupted{W}\n')

        if attack_index + 1 >= len(Configuration.wep_attacks):
            # No more WEP attacks to perform.
            return False

        attacks_remaining = Configuration.wep_attacks[attack_index + 1:]
        Color.pl("{+} {G}%d{W} attacks remain ({C}%s{W})" % (len(attacks_remaining), ', '.join(attacks_remaining)))
        prompt = Color.s('{+} type {G}c{W} to {G}continue{W}' +
                         ' or {R}s{W} to {R}stop{W}: ')
        if raw_input(prompt).lower().startswith('s'):
            return False
        else:
            return True
Example #46
0
    def dump():
        ''' (Colorful) string representation of the configuration '''
        from Color import Color

        max_len = 20
        for key in Configuration.__dict__.keys():
            max_len = max(max_len, len(key))

        result  = Color.s('{W}%s  Value{W}\n' % 'Configuration Key'.ljust(max_len))
        result += Color.s('{W}%s------------------{W}\n' % ('-' * max_len))

        for (key,val) in sorted(Configuration.__dict__.iteritems()):
            if key.startswith('__'): continue
            if type(val) == staticmethod: continue
            if val == None: continue
            result += Color.s("{G}%s {W} {C}%s{W}\n" % (key.ljust(max_len),val))
        return result
Example #47
0
 def deauth(self, target_bssid, station_bssid=None):
     """
         Sends deauthentication request.
         Args:
             target_bssid  - AP BSSID to deauth
             station_bssid - Client BSSID to deauth
                             Deauths 'broadcast' if no client is specified.
     """
     # TODO: Print that we are deauthing and who we are deauthing!
     target_name = station_bssid
     if target_name == None:
         target_name = "broadcast"
     command = ["aireplay-ng", "--ignore-negative-one", "-0", "-a", self.target.bssid]  # Deauthentication
     if station_bssid:
         # Deauthing a specific client
         command.extend(["-h", station_bssid])
     command.append(Configuration.interface)
     Color.p(" {C}sending deauth{W} to {C}%s{W}" % target_name)
     return Process(command)
Example #48
0
    def deauth(self, target):
        '''
            Sends deauthentication request to broadcast and every client of target.
            Args:
                target - The Target to deauth, including clients.
        '''
        if Configuration.no_deauth: return

        for index, client in enumerate([None] + self.clients):
            if client is None:
                target_name = "*broadcast*"
            else:
                target_name = client
            Color.clear_entire_line()
            Color.pattack("WPA",
                    target,
                    "Handshake capture",
                    "Deauthing {O}%s{W}" % target_name)
            Aireplay.deauth(target.bssid, client_mac=client, timeout=2)
Example #49
0
    def fake_auth(self):
        '''
            Attempts to fake-authenticate with target.
            Returns: True if successful,
                     False is unsuccesful.
        '''
        Color.p('\r{+} attempting {G}fake-authentication{W} with {C}%s{W}...'
            % self.target.bssid)
        start_time = time.time()
        aireplay = Aireplay(self.target, 'fakeauth')
        process_failed = False
        while aireplay.is_running():
            if int(time.time() - start_time) > AttackWEP.fakeauth_wait:
                aireplay.stop()
                process_failed = True
                break
            time.sleep(0.1)

        # Check if fake-auth was successful
        if process_failed:
            fakeauth = False
        else:
            output = aireplay.get_output()
            fakeauth = 'association successful' in output.lower()

        if fakeauth:
            Color.pl(' {G}success{W}')
        else:
            Color.pl(' {R}failed{W}')
            if Configuration.require_fakeauth:
                # Fakeauth is requried, fail
                raise Exception(
                    'Fake-authenticate did not complete within' +
                    ' %d seconds' % AttackWEP.fakeauth_wait)
            else:
                # Warn that fakeauth failed
                Color.pl('{!} {O}' +
                    'unable to fake-authenticate with target' +
                    ' (%s){W}' % self.target.bssid)
                Color.pl('{!} continuing attacks because' +
                    ' {G}--require-fakeauth{W} was not set')
        return fakeauth
Example #50
0
    def __init__(self):
        '''
            Starts scan, prints as it goes.
            Upon interrupt, sets 'targets'.
        '''
        self.previous_target_count = 0
        self.targets = []
        self.target = None # Specific target (based on ESSID/BSSID)

        # Loads airodump with interface/channel/etc from Configuration
        with Airodump() as airodump:
            try:
                # Loop until interrupted (Ctrl+C)
                while True:

                    if airodump.pid.poll() != None:
                        # Airodump process died!
                        raise Exception(
                            "Airodump exited unexpectedly! " +
                            "Command ran: %s"
                                % ' '.join(airodump.pid.command))

                    self.targets = airodump.get_targets()

                    if self.found_target():
                        # We found the target we want
                        return

                    self.print_targets()

                    target_count = len(self.targets)
                    client_count = sum(
                                       [len(t.clients)
                                           for t in self.targets])
                    Color.p(
                        '\r{+} scanning, found' +
                        ' {G}%d{W} target(s),' % target_count +
                        ' {G}%d{W} clients.' % client_count +
                        ' {O}Ctrl+C{W} when ready')
                    sleep(1)
            except KeyboardInterrupt:
                pass
Example #51
0
    def run(self):
        ''' Run all WPS-related attacks '''

        # Drop out if user specified to not use Reaver
        if Configuration.no_reaver:
            self.success = False
            return self.success

        # Run Pixie-Dust attack
        bully = Bully(self.target, pixie=True)
        if bully.crack_result is not None:
            # Pixie-Dust attack succeeded. We're done.
            self.crack_result = bully.crack_result
        elif Configuration.pixie_only:
            Color.pl('\r{!} {O}--pixie{R} set, ignoring WPS-PIN attack{W}')
        else:
            # Run WPS-PIN attack
            bully = Bully(self.target, pixie=False)
            self.crack_result = bully.crack_result
        return self.crack_result is not None
Example #52
0
    def deauth_hidden_targets(self):
        '''
            Sends deauths (to broadcast and to each client) for all
            targets (APs) that have unknown ESSIDs (hidden router names).
        '''
        self.decloaking = False

        # Do not deauth if requested
        if Configuration.no_deauth: return

        # Do not deauth if channel is not fixed.
        if self.channel is None: return

        # Reusable deauth command
        deauth_cmd = [
            'aireplay-ng',
            '-0', # Deauthentication
            str(Configuration.num_deauths), # Number of deauth packets to send
            '--ignore-negative-one'
        ]
        for target in self.targets:
            if target.essid_known: continue
            now = int(time.time())
            secs_since_decloak = now - self.decloaked_times.get(target.bssid, 0)
            # Decloak every AP once every 30 seconds
            if secs_since_decloak < 30: continue
            self.decloaking = True
            self.decloaked_times[target.bssid] = now
            if Configuration.verbose > 1:
                from Color import Color
                verbout = " [?] Deauthing %s" % target.bssid
                verbout += " (broadcast & %d clients)" % len(target.clients)
                Color.pe("\n{C}" + verbout + "{W}")
            # Deauth broadcast
            iface = Configuration.interface
            Process(deauth_cmd + ['-a', target.bssid, iface])
            # Deauth clients
            for client in target.clients:
                Process(deauth_cmd + ['-a', target.bssid, '-c', client.bssid, iface])
Example #53
0
    def save_handshake(self, handshake):
        """
            Saves a copy of the handshake file to hs/
            Args:
                handshake - Instance of Handshake containing bssid, essid, capfile
        """
        # Create handshake dir
        if not os.path.exists(Configuration.wpa_handshake_dir):
            os.mkdir(Configuration.wpa_handshake_dir)

        # Generate filesystem-safe filename from bssid, essid and date
        essid_safe = re.sub("[^a-zA-Z0-9]", "", handshake.essid)
        bssid_safe = handshake.bssid.replace(":", "-")
        date = time.strftime("%Y-%m-%dT%H-%M-%S")
        cap_filename = "handshake_%s_%s_%s.cap" % (essid_safe, bssid_safe, date)
        cap_filename = os.path.join(Configuration.wpa_handshake_dir, cap_filename)

        Color.p("{+} saving copy of {C}handshake{W} to {C}%s{W} " % cap_filename)
        copy(handshake.capfile, cap_filename)
        Color.pl("{G}saved{W}")

        # Update handshake to use the stored handshake file for future operations
        handshake.capfile = cap_filename
Example #54
0
    def forge_packet(xor_file, bssid, station_mac):
        ''' Forges packet from .xor file '''
        forged_file = 'forged.cap'
        cmd = [
            'packetforge-ng',
            '-0',
            '-a', bssid,           # Target MAC
            '-h', station_mac,     # Client MAC
            '-k', '192.168.1.2',   # Dest IP
            '-l', '192.168.1.100', # Source IP
            '-y', xor_file,        # Read PRNG from .xor file
            '-w', forged_file,     # Write to
            Configuration.interface
        ]

        cmd = '"%s"' % '" "'.join(cmd)
        (out, err) = Process.call(cmd, cwd=Configuration.temp(), shell=True)
        if out.strip() == 'Wrote packet to: %s' % forged_file:
            return forged_file
        else:
            from Color import Color
            Color.pl('{!} {R}failed to forge packet from .xor file{W}')
            Color.pl('output:\n"%s"' % out)
            return None
Example #55
0
 def deauth(self, target_bssid, station_bssid=None):
     '''
         Sends deauthentication request.
         Args:
             target_bssid  - AP BSSID to deauth
             station_bssid - Client BSSID to deauth
                             Deauths 'broadcast' if no client is specified.
     '''
     # TODO: Print that we are deauthing and who we are deauthing!
     target_name = station_bssid
     if target_name == None:
         target_name = 'broadcast'
     command = [
         'aireplay-ng',
         '--ignore-negative-one',
         '-0', # Deauthentication
         '-a', self.target.bssid
     ]
     if station_bssid:
         # Deauthing a specific client
         command.extend(['-h', station_bssid])
     command.append(Configuration.interface)
     Color.p(' {C}sending deauth{W} to {C}%s{W}' % target_name)
     return Process(command)
Example #56
0
    def terminate_conflicting_processes():
        ''' Deletes conflicting processes reported by airmon-ng '''

        '''
        % airmon-ng check

        Found 3 processes that could cause trouble.
        If airodump-ng, aireplay-ng or airtun-ng stops working after
        a short period of time, you may want to kill (some of) them!
        -e 
        PID Name
        2272    dhclient
        2293    NetworkManager
        3302    wpa_supplicant
        '''

        out = Process(['airmon-ng', 'check']).stdout()
        if 'processes that could cause trouble' not in out:
            # No proceses to kill
            return

        hit_pids = False
        for line in out.split('\n'):
            if re.search('^ *PID', line):
                hit_pids = True
                continue
            if not hit_pids: continue
            if line.strip() == '': continue
            match = re.search('^[ \t]*(\d+)[ \t]*([a-zA-Z0-9_\-]+)[ \t]*$', line)
            if match:
                # Found process to kill
                pid = match.groups()[0]
                pname = match.groups()[1]
                Color.pl('{!} {R}terminating {O}conflicting process' +
                         ' {R}%s{O} ({R}%s{O})' % (pname, pid))
                os.kill(int(pid), signal.SIGTERM)
Example #57
0
    def __init__(self, command, devnull=False, stdout=PIPE, stderr=PIPE, cwd=None):
        ''' Starts executing command '''

        if type(command) == str:
            # Commands have to be a list
            command = command.split(' ')

        self.command = command

        if Configuration.verbose > 1:
            Color.pe("\n {C}[?] {W} Executing: {B}%s{W}" % ' '.join(command))

        self.out = None
        self.err = None
        if devnull:
            sout = Process.devnull()
            serr = Process.devnull()
        else:
            sout = stdout
            serr = stderr

        self.start_time = time.time()

        self.pid = Popen(command, stdout=sout, stderr=serr, cwd=cwd)
Example #58
0
    def divine_bssid_and_essid(self):
        '''
            Tries to find BSSID and ESSID from cap file.
            Sets this instances 'bssid' and 'essid' instance fields.
         '''
        # Get list of bssid/essid pairs from cap file
        pairs = self.tshark_bssid_essid_pairs()
        if len(pairs) == 0:
            # Find bssid/essid pairs that have handshakes in Pyrit
            pairs = self.pyrit_handshakes()

        if len(pairs) == 0 and not self.bssid and not self.essid:
            # Tshark and Pyrit failed us, nothing else we can do.
            raise Exception("Cannot find BSSID or ESSID in cap file")

        if not self.essid and not self.bssid:
            # We do not know the bssid nor the essid
            Color.pl('{!} {O}Warning{W}:' +
                ' {R}bssid{O} and {R}essid{O} were not specified{W}')
            # TODO: Display menu for user to select from list
            # HACK: Just use the first one we see
            self.bssid = pairs[0][0]
            self.essid = pairs[0][1]
            Color.pl('{!} {O}Warning{W}:' +
                ' {O}Arbitrarily selected' +
                ' {R}bssid{O} {C}%s{O} and {R}essid{O} "{C}%s{O}"{W}'
                    % (self.bssid, self.essid))

        elif not self.bssid:
            # We already know essid
            for (bssid, essid) in pairs:
                if self.essid == essid:
                    Color.pl('{+} Discovered bssid {C}%s{W}' % bssid)
                    self.bssid = bssid
                    break

        elif not self.essid:
            # We already know bssid
            for (bssid, essid) in pairs:
                if self.bssid.lower() == bssid.lower():
                    Color.pl('{+} Discovered essid "{C}%s{W}"' % essid)
                    self.essid = essid
                    break
Example #59
0
def main():

    print('\033c', end='')

    ref = Color.from_rgb(args.color) if args.color else RandomColor()
    algo = Algo(args.population_size)

    n = 0
    ok = None
    start = datetime.now()
    while True:
        n += 1

        deltas = []
        for color in algo.population:
            delta = ref.delta_e(color)
            deltas.append(delta)
            if delta <= args.fitness:
                if ok is None or ok[1] > delta:
                    ok = (color, delta)

        dump(ref, algo, deltas)
        if ok:
            break
        if n == args.iterations:
            print('\033[1;31mFailed after {} iterations\033[0;0m'.format(n))
            exit(1)

        algo.tick(deltas)
        if args.delay:
            sleep(args.delay)

    stop = datetime.now()
    duration = (stop - start).total_seconds()
    color, delta = ok
    print('Color to find   : {} {}'.format(ref, ref.rgb))
    print('Color found     : {} {} (\u0394E = {:.3f})'.format(color,
                                                              color.rgb,
                                                              delta))
    print('Algorithm       : {}'.format(algo.__class__.__name__))
    print('Iterations      : {}'.format(n))
    print('Population size : {}'.format(args.population_size))
    print('Colors tested   : {}'.format(n * args.population_size))
    print('All that in     : {:.3f} seconds'.format(duration))