Solução

Nome Valor
Vulnerabilidade Use of Cryptographically Weak PRNG
CWE CWE-338
OWASP Top Ten A02_2021-Cryptographic_Failures

Gerar senhas aleatórias pode não ser tão simples quanto aparenta ser. Mesmo que a senha gerada seja enorme e com vários caracteres especiais, mesmo assim isso não garante que ela é segura.

Se o algoritmo utilizado para gerar a senha for fraco, é possível que o atacante tente quebrar a seed que foi usada para gerar a senha ao invés da senha em si.

E não, não adianta usar um “algoritmo secreto” que isso não garante que seja impossível quebrarem a senha. Informações vazam. Um atacante pode obter acesso a esse código fonte.

Quando se pensa em segurança, é importante cogitar a possibilidade de uma ameaça interna, isto é, alguém da empresa (como um funcionário ou ex-funcionário). Além disso um atacante poderia obter o código de outras maneiras também, como por engenharia social.

Abaixo um exemplo de script que poderia ser usado para quebrar a senha:

#!/usr/bin/python3
import bcrypt
import random
import sys

def main() -> int:
    if len(sys.argv) < 3:
        print("Usage: ./crack.py <registered_at> <bcrypt-hash>")
        return 0

    registered_at = int(sys.argv[1])
    hash = sys.argv[2].encode()

    if b"\x00" in hash:
        print("Hash cannot contain nul byte!", file=sys.stderr)
        return 1

    password = crack_hash(registered_at, hash)

    if password:
        print(f"Password cracked: {password}")
        return 0

    print("Unable to crack the password!", file=sys.stderr)
    return 2

def crack_hash(registered_at: int, hash: bytes) -> str | None:
    seed = registered_at - 10
    max_timestamp = registered_at + 10

    while seed <= max_timestamp:
        password = passgen(seed, 64)
        seed += 1

        if bcrypt.checkpw(password, hash):
            return password.decode()

    return None

pass_dict = (
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST"
    "UVWXYZ0123456789-_!.,~`^+{}[]();:@#%&*'\" "
)

def passgen(seed: int, size: int) -> bytes:
    passwd = bytes()
    random.seed(seed)

    for i in range(size):
        rindex = random.randint(0, len(pass_dict) - 1)
        passwd += pass_dict[rindex].encode()

    return passwd

if __name__ == "__main__":
    try:
        exit(main())
    except KeyboardInterrupt:
        print("Bye!")

Exemplo de uso:

$ ./crack.py 1724990168 '$2b$12$Hqd8dWFgE8lYY/G44xyj2eD1BMLVvla
7QLzfsqVIYtxiJBMTsc2zm'