使用hashlib结合已知盐破解Unix SHA512密码哈希失败,求排查
问题排查与修复方案
你遇到的问题主要来自两个核心点:错误的哈希生成逻辑和代码循环提前终止,另外还有一些小的语法问题,咱们一步步拆解:
1. 为什么直接用hashlib生成的哈希不匹配?
Linux /etc/shadow 里的SHA512哈希($6$开头的)并不是简单的SHA512(盐+明文密码),而是使用系统的crypt(3)函数生成的迭代式哈希——它包含算法标识、盐、迭代次数(默认5000次)等参数,直接用hashlib拼接盐和密码计算的结果完全不符合系统的哈希格式。
正确的做法是使用Python的crypt模块,它会自动遵循系统的crypt格式生成哈希,和/etc/shadow里的格式完全兼容。
2. 代码逻辑的致命问题:循环提前终止
你的checkpass函数里,不管第一个单词是否匹配,都会执行return cryptWord,这导致字典文件只遍历第一行就直接退出了,后面的密码根本没机会被检查!这也是你找不到正确密码的重要原因。
3. 其他小问题
- 导入语句错误:
import hashlib import sys应该拆分成两行单独导入 - 文件操作未做资源释放:直接
open文件后没有关闭,最好用with语句自动管理 - 异常处理的信息不够清晰
修正后的代码
下面是修复后的完整代码,我保留了你的核心逻辑,同时解决了上述所有问题:
import crypt import sys def checkpass(passwd): try: semi_c = ':' d_sign = '$' # 解析shadow格式的密码串:拆分出算法、盐、目标哈希值 pwd_parts = passwd.split(d_sign) if len(pwd_parts) < 4: print("Invalid shadow password format") return algo = pwd_parts[1] # 这里是6,表示SHA512算法 full_salt = d_sign.join([pwd_parts[1], pwd_parts[2]]) # 完整盐格式:$6$xxxxxx target_hash = pwd_parts[3].split(semi_c)[0] print(f'Salt (full format): ${full_salt}') print(f'Target Hash: {target_hash}') # 遍历字典文件,用with自动管理文件句柄 with open('dictionary.txt', 'r') as dictFile: for word in dictFile.readlines(): word = word.strip('\n') print(f'Comparing: {word}') # 使用crypt模块生成符合系统格式的哈希 generated_hash = crypt.crypt(word, f'${full_salt}') # 提取生成的哈希核心部分(去掉前面的$6$盐$前缀) generated_hash_core = generated_hash.split(d_sign)[3] if generated_hash_core == target_hash: print(f'[+] Found Password : {word}\n') return word # 遍历完所有单词都没找到才提示 print('[-] Password not found in dictionary.\n') return None except Exception as e: print(f"Error occurred: {e}") return None def main(): try: with open('password.txt', 'r') as passfile: passwd = passfile.readline().strip() semi_c = ':' if semi_c in passwd: user = passwd.split(semi_c)[0] print(f'[*] Cracking Password for : {user}') checkpass(passwd) else: print("Invalid password file format - missing colon separator") except Exception as e: print(f"Error occurred: {e}") return if __name__ == '__main__': main()
关键修复点说明
- 改用crypt模块:
crypt.crypt(word, f'${full_salt}')会自动识别盐里的算法标识($6$),按照系统标准生成SHA512哈希,完全匹配/etc/shadow的格式。 - 修复循环逻辑:只有找到匹配密码时才return,否则遍历完整个字典后再提示未找到。
- 正确解析盐格式:crypt函数需要完整的盐标识(包括
$6$前缀),而不是只取盐的字符串部分。 - 优化文件操作:用
with语句自动关闭文件,避免资源泄漏。
内容的提问来源于stack exchange,提问作者dexray
相关产品推荐
相关产品推荐

