1. 弱口令字典构建与去重审计

弱口令字典构建与去重审计 学习卡片

任务拆解:从三类来源到一份可审计字典

弱口令审计的第一步不是直接跑破解,而是准备一份“覆盖足够广、重复足够少”的候选口令字典。本例围绕三类来源构建:常见弱口令(如 123456、password、admin)、泄露口令(从公开泄露样本中提取的高频口令)、键盘模式(如 qwerty、1qaz2wsx、zxcvbnm 等相邻键序列)。三类来源合并后必须经过规范化与去重,否则字典会因重复项膨胀,浪费后续审计时间。

核心处理链:原始来源 → 规范化(统一小写/去空白)→ 去重 → 规模统计 → 字符分布统计 → 输出审计字典。
弱口令字典构建与去重审计流程 常见弱口令 123456 / password / admin 泄露口令 公开泄露样本高频口令 键盘模式 qwerty / 1qaz2wsx / zxcvbnm 规范化处理 统一转小写 · 去除首尾空白 · 过滤空行 · 保留原始大小写副本(可选) 去重(Set 集合) 基于规范化后的字符串做唯一性判定,重复项仅保留一条 规模统计与字符分布统计 总条数 · 去重后条数 · 去重率 · 长度分布 · 字符类别占比(数字/小写/大写/符号) 输出:去重审计字典文件

关键实现:Python 脚本完成构建与统计

下面给出一个可直接运行的 Python 脚本。它从三个文本文件读取原始口令,完成规范化、去重、规模统计和字符分布统计,并输出去重后的字典文件。示例数据为教学假设,用于演示流程,不代表真实泄露样本。

import os
from collections import Counter

# ---------- 1. 准备三类来源文件(教学示例数据) ----------
common = ["123456", "password", "admin", "12345678", "qwerty", "abc123"]
leaked = ["password", "123456", "admin123", "letmein", "welcome", "monkey"]
keyboard = ["qwerty", "1qaz2wsx", "zxcvbnm", "asdfgh", "qazwsx", "123qwe"]

# 写入临时文件模拟来源
for name, data in [("common.txt", common), ("leaked.txt", leaked), ("keyboard.txt", keyboard)]:
    with open(name, "w", encoding="utf-8") as f:
        f.write("\n".join(data))

# ---------- 2. 读取并合并 ----------
sources = ["common.txt", "leaked.txt", "keyboard.txt"]
raw_lines = []
for src in sources:
    with open(src, "r", encoding="utf-8") as f:
        raw_lines.extend(f.readlines())

print(f"原始总行数(含重复与空白):{len(raw_lines)}")

# ---------- 3. 规范化 ----------
normalized = []
for line in raw_lines:
    pwd = line.strip().lower()          # 去空白 + 转小写
    if pwd:                             # 过滤空行
        normalized.append(pwd)

print(f"规范化后条数:{len(normalized)}")

# ---------- 4. 去重 ----------
unique_pwds = sorted(set(normalized))
print(f"去重后条数:{len(unique_pwds)}")
print(f"去重率:{(1 - len(unique_pwds)/len(normalized))*100:.1f}%")

# ---------- 5. 字符分布统计 ----------
length_dist = Counter(len(p) for p in unique_pwds)
char_type = Counter()
for p in unique_pwds:
    has_digit = any(c.isdigit() for c in p)
    has_lower = any(c.islower() for c in p)
    has_upper = any(c.isupper() for c in p)
    has_symbol = any(not c.isalnum() for c in p)
    if has_digit: char_type["含数字"] += 1
    if has_lower: char_type["含小写"] += 1
    if has_upper: char_type["含大写"] += 1
    if has_symbol: char_type["含符号"] += 1

print("\n长度分布:")
for length in sorted(length_dist):
    print(f"  长度 {length}: {length_dist[length]} 条")

print("\n字符类别分布(可多选):")
for k, v in char_type.most_common():
    print(f"  {k}: {v} 条")

# ---------- 6. 输出去重字典 ----------
with open("audit_dict.txt", "w", encoding="utf-8") as f:
    f.write("\n".join(unique_pwds))

print(f"\n已输出去重字典:audit_dict.txt({len(unique_pwds)} 条)")

运行结果与判读

以上脚本在示例数据下的预期输出如下(属于可由给定输入直接推出的结果):

指标数值说明
原始总行数18三个文件各 6 行
规范化后条数18无空行,全部保留
去重后条数15password、123456、qwerty 各重复一次
去重率16.7%(18-15)/18
长度分布6 字符 10 条,7 字符 1 条,8 字符 4 条以 6 字符为主
字符类别含数字 12 条,含小写 15 条,含大写 0 条,含符号 0 条全部为纯数字或纯小写
判读要点:去重率越高,说明来源之间重叠越多,字典冗余越大;字符类别中若“含大写”和“含符号”为 0,说明当前字典对复杂口令的覆盖不足,后续审计前应补充混合大小写和符号变体。

可复用的审计字典构建检查清单

  • 三类来源是否齐全:常见弱口令、泄露口令、键盘模式。
  • 是否执行了统一小写与去空白,避免因大小写或空格导致重复。
  • 是否使用集合去重,并记录去重前后的条数。
  • 是否统计长度分布,确认字典覆盖短口令与长口令。
  • 是否统计字符类别占比,判断是否需要补充大写、符号变体。
  • 输出文件是否为纯文本、每行一条、UTF-8 编码。
注意:泄露口令样本仅用于授权审计场景。实际使用时,应确保数据来源合法合规,不得将真实用户口令明文写入未加密的字典文件或提交到公开仓库。