Cracker password SHA256 - forza bruta

Nov 16 2020

Ho scritto un cracker di password SHA256. Inizialmente ho usato gli elenchi per memorizzare le informazioni list1.txte list2.txtalla fine avrei avuto sovraccarichi di memoria. Quindi ora uso i file. Ho notato che quando ho effettuato questa transizione, la velocità del programma si è ridotta enormemente. C'è un modo per ottimizzare la velocità di questa programmazione senza incorrere in problemi di sovraccarico di memoria?

Grazie

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")

Risposte

4 LevM. Nov 16 2020 at 06:40

L'ottimizzazione che stai cercando è molto semplice:
chiedi a te stesso: cosa devo mantenere?

La risposta: sto controllando solo l'ipotesi della password.

Non è necessario memorizzare tutte le vecchie ipotesi, quindi non sono necessari file o elenchi enormi.

Tutto ciò di cui hai veramente bisogno è una stringa che continuerai ad aggiornare.

Per visualizzarlo, pensa alla tua stringa come a un numero crescente, con ogni lettera che è una cifra di 58 in base.

Adesso. tutto ciò di cui hai veramente bisogno è fare un +1 sulla prima cifra, controllando il carry e aggiornando le cifre successive se necessario proprio come al solito aggiunta.

Sfortunatamente, le stringhe Python non consentono l'assegnazione per indice, ma supportano lo slicing .

Ecco una funzione che genererebbe password sequenziali che attraversano tutte le lettere e aumentano la lunghezza secondo necessità (una password per chiamata!):

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

Con questo puoi usare un loop per tutte le possibilità fino alla lunghezza massima:

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)