Как создать взломщик паролей Bruteforce для буквенно-цифровых паролей?

Мне нужно сделать небольшие программы для школы, чтобы взламывать разные типы паролей; Я хочу создать код Python для грубой силы, который будет выполнять все возможные комбинации буквенных и буквенно-цифровых паролей и давать мне пароль и количество времени, которое потребовалось для взлома.

Я сделал то же самое с чисто числовыми паролями и получил это:

import datetime as dt

Password4 = 123456

def crack_password():
    start = dt.datetime.now()
    for n in range(1000000):
        password_guess = '{0:04d}'.format(n)
             if password_guess == str(Password4):
                end = dt.datetime.now()
                print("Password found: {} in {}".format(password_guess, end - start))
               break
    guesses = crack_password()

Затем я попытался сделать что-то похожее для алфавитно-цифровых паролей, но не сработало, что бы я ни пытался:

    import random

    letters = [str(i) for i in range('a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p')]
    s = [''.join([a,b,c,d,e,f,g,h]) for a in letters for b in letters for c   in letters for d in letters for e in letters for f in letters for g in letters  for h in letters]
    random.shuffle(s)
    real_password = 'aaaaaaaa'
    i = 0

    for code in s:
        if code == real_password:
            print()
            print('The password is: ', code)
             break
        else:
            i += 1
            print(i, ' failures', end='\r')

Крайне важно, чтобы программа включала либо количество сбоев, либо время, необходимое для подбора пароля, поэтому я не могу просто сделать генератор паролей.

Обратите внимание: я новичок в кодировании и очень благодарен за вашу помощь :)


person Alex H    schedule 26.10.2016    source источник
comment
Я предлагаю вам взглянуть на этот PHP-скрипт, я считаю, что он хорошо написан: gist.github. com/popc0rn/5859209   -  person Yann Chabot    schedule 26.10.2016
comment
спасибо @YannChabot, однако я хочу сделать эту программу на питоне и действительно не знаю, как переводить между разными языками   -  person Alex H    schedule 26.10.2016
comment
letters = [str(i) for i in range('a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p')] не работает, как вы думаете....   -  person MooingRawr    schedule 26.10.2016
comment
@AlexH Я знаю, что PHP - это не то же самое, что python, но я думаю, что вы все же можете понять логику, она довольно близка к php.   -  person Yann Chabot    schedule 26.10.2016
comment
letters = 'abcdefghijklmnopqstuvwxyz' это то, к чему вы стремитесь   -  person Patrick Haugh    schedule 26.10.2016


Ответы (2)


Вот наивный метод грубой силы, который угадывает числа (string.digits) и строчные буквы (string.ascii_lowercase). Вы можете использовать itertools.product с repeat, установленным на текущую угаданную длину пароля. Вы можете начать с паролей из 1 символов (или любой другой нижней границы), а затем ограничить их максимальной длиной. Затем просто return, когда вы найдете совпадение.

import itertools
import string

def guess_password(real):
    chars = string.ascii_lowercase + string.digits
    attempts = 0
    for password_length in range(1, 9):
        for guess in itertools.product(chars, repeat=password_length):
            attempts += 1
            guess = ''.join(guess)
            if guess == real:
                return 'password is {}. found in {} guesses.'.format(guess, attempts)
            print(guess, attempts)

print(guess_password('abc'))

Вывод

a 1
b 2
c 3
d 4
...
aba 1369
abb 1370
password is abc. found in 1371 guesses.
person Cory Kramer    schedule 26.10.2016
comment
Большое спасибо! Когда я превышаю 4 символа в пароле, моя IDE сообщает мне, что «слишком много вывода». Это все еще работает, но занимает значительно больше времени. Это то, с чем мне просто нужно иметь дело, поскольку это программа грубой силы? - person Alex H; 26.10.2016
comment
Просто удалите строку print(guess, attempts), чтобы подавить вывод. Затем он просто будет работать, пока не найдет совпадение, а затем вернет окончательное предположение и подсчет. - person Cory Kramer; 26.10.2016
comment
Печать действительно тормозит, особенно в IDLE. - person Anonymous; 23.02.2020

Один из возможных вариантов, который почти точно сохранит ваш текущий код, - это преобразовать в базу 36 со следующими «цифрами»: 0-9a-z. Это даст вам все возможные буквенно-цифровые комбинации для n символов, если вы будете искать в range(36**n).

Использование упрощенной функции из Как преобразовать целое число в любом основании в строку?:

def baseN(num, b=36, numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
    return ((num == 0) and numerals[0]) or (baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b])

Затем вы можете перебирать числа, как в вашем примере:

>>> for i in range(10000, 10005):
...     print(baseN(i).zfill(5))
...
007ps
007pt
007pu
007pv
007pw

Чтобы получить все 3-буквенные возможности, вы можете выполнить цикл следующим образом:

for i in range(36**3):
    possible = baseN(i).zfill(3)
person brianpck    schedule 26.10.2016
comment
Мне нравится это решение, так как оно более подробно показывает, как работает подсчет с другой базой. Одно замечание: ваше использование zfills предполагает, что первый символ в цифрах является нулевым символом. Чтобы сделать его более общим, лучше сделать baseN(i).rjust(3, numerals[0]) - person Eelco van Vliet; 18.03.2020