diff --git a/crack/crack.py b/crack/crack.py new file mode 100644 index 0000000..b27e77e --- /dev/null +++ b/crack/crack.py @@ -0,0 +1,65 @@ +import re +import sys + +from passlib.hash import sha512_crypt + +DEF_ROUNDS = 5000 + + +def parse_crypt_line(cr_line: str): + p_cr_pass = cr_line.split("$", 3) + if len(p_cr_pass) < 3: + return None, None, None + _, alg, salt, passwd = p_cr_pass + return alg, salt, passwd + + +def brute_passwd(dict_file, cr_line): + alg, salt, passwd = parse_crypt_line(cr_line) + if not passwd: + return None + r_match = re.match(r".*rounds=(\d*)", salt) + rounds = r_match.group(1) if r_match else DEF_ROUNDS + + with open(dict_file, 'r') as df: + for line in df.readlines(): + open_pass = line.strip() + exp_pass = sha512_crypt.hash(open_pass, salt=salt, rounds=rounds) + if exp_pass == cr_line: + return open_pass + return None + + +def parse_shadow(shadow_file): + result = dict() + + with open(shadow_file, 'r') as sf: + for line in sf.readlines(): + p_line = line.split(":") + if len(p_line) < 2: + continue + user, cr_pass = p_line[:2] + if not all(parse_crypt_line(cr_pass)): + continue + result[user] = cr_pass + + return result + + +def main(): + if len(sys.argv) != 3: + print(f"Usage: {sys.argv[0]} ") + exit(0) + shadow = sys.argv[1] + dictionary = sys.argv[2] + + shadow_data = parse_shadow(shadow) + for user, cr_pass in shadow_data.items(): + found_pass = brute_passwd(dictionary, cr_pass) + if found_pass: + print(f"[+] Found password for {user}: {found_pass}") + continue + + +if __name__ == "__main__": + main() diff --git a/requirements.txt b/requirements.txt index 49a7ffe..a1a9f7f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ ipython +passlib