SHA256 Passwort-Cracker - Brute Force

Nov 16 2020

Ich habe einen SHA256 Passwort Cracker geschrieben. Ich zunächst Listen verwendet in die Informationen zu speichern list1.txtund list2.txtaber ich würde Speicher Überlastungen am Ende immer. Also benutze ich jetzt Dateien. Ich bemerkte, dass sich die Programmgeschwindigkeit bei diesem Übergang erheblich verringerte. Gibt es eine Möglichkeit, die Geschwindigkeit dieser Programmierung zu optimieren, ohne auf Probleme mit der Speicherüberlastung zu stoßen?

Vielen Dank

import hashlib
import time
import os

def extract_password(fname):
    if fname == 0:
        filename = "list2.txt"
    else:
        filename = "list1.txt"
    for line in open(filename, "r"):
        yield line.strip()


def save_password(fname, password):
    if fname == 0:
        filename = "list1.txt"
    else:
        filename = "list2.txt"

    file = open(filename, "a")
    file.write(password)
    file.write("\n")
    file.close()



def next_password(lsta, item,next_char, secure_password):
    found = 0
    guess = item + chr(next_char)
    if hash_password(guess) == secure_password:
        print(guess)
        found = 1
    save_password(lsta, guess)
    return found

def hash_password(pwrd):
    #Generates hash of original password
    pwrd = pwrd.encode("UTF-8")
    password = hashlib.sha256()
    password.update(pwrd)
    return password.hexdigest()

def delete_file(ltsa):
    try:
        if ltsa == 1:
            os.remove("list2.txt")
        else:
            os.remove("list1.txt")
    except:
        pass

def reset_file_status():
    try:
        os.remove("list2.txt")
        os.remove("list1.txt")
    except:
        pass

def find_password(secure_password):
    #Brute force to find original password
    found = 0
    lsta = 1
    for length in range(1, 15):
        if found == 1: break
        lsta = lsta^1
        delete_file(lsta)
        for next_char in range(65, 123):
            if found == 1: break
            if length == 1:
                found = next_password(lsta, "", next_char, secure_password)
                if found == 1: break
            else:
                for item in extract_password(lsta):
                    found = next_password(lsta, item, next_char, secure_password)
                    if found == 1: break

if __name__ == "__main__":
    reset_file_status()
    start = time.time()
    secure_password = hash_password("AAAA")
    find_password(secure_password)
    print(f"{(time.time() - start)} seconds")

Antworten

4 LevM. Nov 16 2020 at 06:40

Die Optimierung, nach der Sie suchen, ist sehr einfach:
Fragen Sie sich selbst - was muss ich wirklich behalten?

Die Antwort: Nur das Passwort schätze ich gerade.

Es ist nicht erforderlich, alle alten Vermutungen zu speichern, sodass keine Dateien oder großen Listen erforderlich sind.

Alles, was Sie wirklich brauchen, ist eine Zeichenfolge, die Sie ständig aktualisieren.

Um dies zu veranschaulichen, stellen Sie sich Ihre Zeichenfolge als wachsende Zahl vor, wobei jeder Buchstabe eine Basis-58-Ziffer ist.

Jetzt. Alles, was Sie wirklich brauchen, ist, eine +1 auf der ersten Ziffer zu machen, auf Übertrag zu prüfen und die folgenden Ziffern bei Bedarf zu aktualisieren, genau wie üblich.

Leider erlauben Python-Strings keine Zuweisung nach Index, aber sie unterstützen das Slicing .

Hier ist eine Funktion, die sequentielle Passwörter generiert, die alle Buchstaben durchlaufen und die Länge nach Bedarf erhöhen (ein Passwort pro Anruf!):

def make_next_guess(guess):
    carry = 1
    next_guess = guess

    for i in range(len(guess)):
        cur_char = ord(guess[i]) + carry
        if cur_char > ord('z'):
            cur_char = ord('A')
            carry = 1
        else:
            carry = 0

        next_guess = next_guess[:i] + chr(cur_char) + guess[i + 1:]
        if carry == 0:
             break

    if carry = 1:
        next_guess += 'A'

    return next_guess

Damit können Sie eine Schleife für alle Möglichkeiten bis zur maximalen Länge verwenden:

guess = 'A'

for _ in range(58 ** 14): #password maximum length 14 and there are 58 characters that can be used
    
    if hash_password(guess) == secure_password:
        print(guess)
        break

    guess = make_next_guess(guess)