You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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()

关键修复点说明

  1. 改用crypt模块:crypt.crypt(word, f'${full_salt}')会自动识别盐里的算法标识($6$),按照系统标准生成SHA512哈希,完全匹配/etc/shadow的格式。
  2. 修复循环逻辑:只有找到匹配密码时才return,否则遍历完整个字典后再提示未找到。
  3. 正确解析盐格式:crypt函数需要完整的盐标识(包括$6$前缀),而不是只取盐的字符串部分。
  4. 优化文件操作:用with语句自动关闭文件,避免资源泄漏。

内容的提问来源于stack exchange,提问作者dexray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:07:44