拓冰建站拓冰建站
首页 / 资讯中心 / 正文

CUPP集成实战:从字段词根到自定义弱口令词库生成

1. CUPP工具的使用边界它是审计助手不是无脑扫描器最近接到一个内部安全审计需求要对公司一套核心业务系统的口令强度做全面评估。常规弱口令扫描器跑完第一轮报告里基本都是123456、admin、password这类“全民通用型”弱口令。可实际测试时我发现真正容易翻车的是另一类口令用户把自己的姓名拼音、生日、手机号、工号按常见习惯随意拼接。比如zhangsan1992、wangli123、LiMing0715。这类口令虽然不在常规弱口令字典里但命中率出奇地高。当时我选择引入 CUPPCommon User Passwords Profiler通用用户密码剖析器。这工具很老牌核心逻辑不复杂在不触碰未授权数据的前提下把参加评估的人员信息字段作为“词根”按照现实中人们起口令的习惯自动排列组合出一大批候选口令。它本质上不是那种拿着彩虹表到处撞的扫描器而是一个“按人物画像生成词库”的辅助工具。这里必须先把边界说清楚。CUPP 这类工具一旦用错场景很容易踩到合规红线。所以我在整个项目里的定位是安全审计辅助器只输入授权范围内可用的项目资料生成结果只服务于内部薄弱口令排查和安全意识宣讲绝不用于任何未授权的账号探测或外部系统验证。1.1 为什么我会把 CUPP 放到“集成”这个框架里单次运行 CUPP 其实很轻量一条命令就能生成一份词表。但真正落地到企业级审计时你会发现它有几个痛点默认输出格式比较原始生成结果往往是一堆按行排列的口令没有分类也没办法直接导入到后续检测工具里。每次运行都需要人工交互式录入信息审计项目一多重复操作极其烦人。默认词组偏向西文命名习惯对中文拼音场景覆盖不够需要额外定制词根和变换规则。所以我在这个项目里没有把 CUPP 当成一个独立工具直接调用而是把它嵌入到一条完整的“口令生成流水线”里先收集合规范围内的信息样本再通过脚本批量整理词根然后用 CUPP 的生成能力做组合扩展最后自动脱敏成审计报告要用到的检测词表。这么一搞整个流程就从“手动敲命令”变成了“一条命令跑完整条链路”后面接人的审计报告、接脚本检测、接整改通知单都方便很多。这也是项目名里“集成”二字的来由。1.2 密码语料向量从哪里来很多人第一次接触 CUPP 时会以为它真的是凭空白造词。其实它背后靠的是信息字段的组合。在做内部审计时我通常拿到并使用的字段分这么几类字段类别典型内容说明基础姓名zhangsan、wangwu、lisi拼音全拼、姓名缩写日期字段1992、0715、920715出生年份、生日月日、常见组合工号学号10086、T0001、20230045企业内部编号联系方式138xxxx、尾号4321只取授权范围内公开场景的片段习惯后缀123、、abc、520常见弱口令后缀与特殊字符需要特别强调这些字段的来源必须限定在项目组授权范围内比如企业自己提供的测试名单、员工签字确认过的安全演练信息。我在实际项目中会把真实姓名替换成脱敏后的拼音代号再进行测试避免把个人信息无限制地堆进工具里产生隐私风险。2. 搭建一个最小可用的 CUPP 集成环境这部分直接讲操作。我的运行环境是一台 CentOS 7 服务器装了 Python 3.8CUPP 源码放在/opt/audit/cupp目录下。整个集成环境的搭建分三个步骤。2.1 第一步准备好合法范围内的身份字段样本先用一个脚本把授权名单里的信息整理成 CUPP 能直接吃的文本格式。我习惯的格式是每行一个词根例如# words.txt zhangsan wangwu lisi 1992 0715 10086 T0001 1384321 520 123这里有个细节不要一股脑把所有字段全丢进去否则生成的词表会爆炸式增长里面会混入大量根本不会有人使用的组合。我在实践中通常控制在 8~12 个有效词根范围内。词根越贴近目标人群的真实使用习惯生成结果越有参考价值。2.2 第二步写一个可复用的批量生成脚本CUPP 原生交互模式跑一次会问一堆问题比如是否包含用户名、是否包含年份、键盘模式等。为了把整个生成过程固定下来我建议绕过交互直接用参数调用。我先用一条命令生成初步词表cd /opt/audit/cupp python3 cupp.py --import words.txt --output base_wordlist.txt参数说明--import导入外部词根文件。--output指定输出文件名。如果集群里有多个项目要测我会再包一层 Python 脚本实现“读取项目字段 → 动态生成 words.txt → 调用 CUPP → 汇总结果”的循环处理。核心脚本大概是这个逻辑import subprocess import os import time def generate_wordlist(project_name, fields): word_file f/opt/audit/projects/{project_name}/words.txt output_file f/opt/audit/projects/{project_name}/cupp_raw.txt with open(word_file, w, encodingutf-8) as f: for item in fields: f.write(item \n) cmd [ python3, /opt/audit/cupp/cupp.py, --import, word_file, --output, output_file ] result subprocess.run(cmd, capture_outputTrue, textTrue) return result.returncode 0这里我把每个项目独立目录化方便后面做追踪和复测。实际跑通后整个集成链路就成了字段收集脚本 → CUPP 生成引擎 → 后续清洗模块。这里需要提醒一句如果你的业务场景涉及特定的口令策略比如必须包含大写字母和特殊符号那么 CUPP 原生输出可能不完全满足要求。这种情况我们会在后面的自定义模块中做二次加工而不是强行改 CUPP 源码。3. 自定义词库与不同系统的对接细节CUPP 生成的原生词表虽然覆盖面不错但格式上往往还需要打磨才能对接不同的检测系统和报告组件。我在实际项目里主要做了三件事。3.1 把 CUPP 输出转化为明文口令检查点CUPP 默认输出的词表是每行一个口令但很多企业环境里的口令优化策略是组合式的。举个例子公司要求口令必须超过 8 位且包含字母和数字。CUPP 输出里会有一批类似zhangsan这种纯字母口令也有19920715这种纯数字口令。这些本来就不可能成为实际可用口令直接带进检测列表只会增加无效匹配。所以我在集成环境里加了一层规则过滤模块专门做三件事按目标系统密码复杂度策略做前置筛选。把 CUPP 输出的原始词根按常见习惯二次拼接例如姓名缩写 年份 特殊字符。对生成的候选词做去重和随机排序。核心逻辑可以这样理解import itertools def expand_candidates(names, years, suffixes): result [] for name in names: for year in years: for suffix in suffixes: result.append(f{name}{year}{suffix}) result.append(f{name.capitalize()}{year}{suffix}) result.append(f{year}{name}{suffix}) return list(set(result))这一层完成后得到的才是真正可用于比对入库审计系统账户口令的候选集合。3.2 留意与其他弱口令工具的配合很多团队在实际项目里不只用一个工具。我们这边常用的是hydra、john以及自建的口令强度检查脚本。CUPP 的集成价值就体现在这里生成的词表可以直接导出成其他工具支持的格式。比如john --wordlist要求纯文本词表我们把 CUPP 输出做一次sort -u就能直接用。比如某些自研检测脚本需要 JSON 数组格式那我再用一段脚本包装一下cat cupp_clean.txt | python3 -c import sys,json; print(json.dumps([line.strip() for line in sys.stdin])) audit_wordlist.json这一步非常琐碎但很关键。很多集成项目跑不通并不是工具本身有问题而是格式转换环节没做好。这里还有一个经验之谈词表生成后我会习惯性留一份“原始全量版”和“策略过滤版”。原始版用于复盘分析看用户到底有哪些起名习惯策略过滤版才用于最终的实际检测。两者分开存放能避免后续排查问题时把有效信息弄丢。4. 真实审计案例用自定义变体拼出用户习惯我拿一次实际项目来举例。某客户要求对内部一个办公系统的弱口令风险做摸底授权范围内提供了 200 个测试账号的脱敏字段信息。在正式检测前我们就意识到这批账号里大部分人用的是中文拼音起名习惯和 CUPP 默认词典的偏好有明显差异。4.1 案例一默认词典检测不到的口令常规弱口令扫描器扫完只报出了 3 个password和 2 个123456。但通过 CUPP 集成生成的自定义词表我们匹配到了 17 个高风险口令。其中比较典型的是zhangsan123、lisi2023、wangwu0715。这些口令为什么检测不到因为通用弱口令字典收录的是固定排序的常用口令它不会根据“这个用户的名字叫 zhangsan”来推导口令。CUPP 的价值恰恰在于它把独立的词根信息组合起来还原出用户最可能使用的口令。4.2 案例二团队部门拼凑词根如何在规则中收敛另一个有意思的发现是很多人的口令习惯把部门缩写和入司年份拼在一起。比如finance2021、hr2022、ops2020。这类口令如果只靠单个用户的姓名词根去生成很容易漏掉因为部门缩写不在 CUPP 默认的字段库中。处理方式很简单在词根文件里加一行部门缩写再配合年份后缀CUPP 就能自动生成一批同类变体。我把词根文件设计成可配置的支持按部门维度输入finance hr ops admin 2020 2021 2022这样一来原本需要单独猜测的hr2022就自然地进入候选词列表。整个检测能力不再只依赖单个工具自带的词典而是可以根据业务特点动态扩展。我在项目复盘时强调过这种基于业务字段的词根扩展才是 CUPP 集成项目真正有价值的地方。你不需要去市面上找一个所谓“更全”的弱口令字典只要把信息字段整理好让 CUPP 按规则去组合就能覆盖大量常规字典覆盖不到的盲区。5. 踩坑记录调试时最典型的四个失误集成环境从零搭到跑通前后花了差不多两个工作日。过程中踩了不少坑这里挑四个最典型的写出来供后来人参考。5.1 数据拼接格式不统一导致的漏检第一次整理词根文件时我直接复制了一份手填表格里的名单。结果发现同一批人里有的行是“张三”有的行是“zhangsan”还有一行是“Zhang San”。CUPP 遇到中文和空格格式输出的候选词会有大量无效内容导致后续匹配率骤降。解决方案是统一格式规范。我在脚本里加了字段清洗步骤把所有中转字符统一转成小写拼音同时剔除空白行和明显不合理的超长词条。建议在项目一开始就确认字段规范避免后期手工返工。5.2 字符集和编码问题CUPP 在 Linux 环境下默认以 UTF-8 处理文本但当我第一次在 Windows 上编辑 words.txt再传回 Linux 服务器运行时出现了奇怪的换行符和编码报错。具体表现是生成结果里夹杂\r字符导致口令匹配失败。这个坑很好修但很容易被忽略。我后来在脚本里统一加了编码处理和换行符清洗def clean_word_file(word_file): with open(word_file, r, encodingutf-8, errorsignore) as f: lines [line.strip() for line in f if line.strip()] with open(word_file, w, encodingutf-8) as f: f.write(\n.join(lines))别小看这几行它能省下大量排查时间。5.3 盲目扩大词根导致词表膨胀一开始我以为词根越多越好结果把几十个字段全部丢进 CUPP生成的候选词表达到了几十万条。后续检测脚本处理时间大幅拉长而且匹配到的真实命中率反而没有明显提升。后来我收缩了词根范围控制在不超过 15 个核心词根配合 2~3 种变换规则生成的词表大概在几千到一万条之间。这个规模既保证了检测速度又不会因为候选词太少而漏掉目标。5.4 违规边界把控不足这个坑属于经验层面的。CUPP 生成结果涉及不少个人信息拼凑如果不注意边界很容易把审计行为演变成个人信息滥用。我在项目启动前反复和客户确认授权范围并约定所有词根只允许来源于客户提供的脱敏测试字段不允许通过网络搜集、猜测、购买等方式获取额外信息。同时也提醒准备做类似项目的人务必把授权确认文档留档不然工具跑得再顺合规层面一旦出问题整个项目都可能被追责。这里放一个我在项目里使用的授权字段声明表格方便参考字段类型是否允许备注脱敏姓名允许必须由客户方主动提供出生日期部分允许只允许到年份不允许精确到日工号允许客户内部授权范围内使用手机号尾号不推荐隐私风险较高未经确认不使用社交账号信息禁止超出本审计项目授权范围写在最后的个人体会CUPP 本身是一个很有针对性的工具但它的价值释放程度完全取决于使用者的“前置加工”和“后置对接”能力。单跑一条命令很容易真正要花心思的是词根整理、规则过滤、输出格式统一这些看起来零碎的工作。我在这次内部审计项目里体会到任何工具一旦被嵌入到完整的业务链路中就不再是单一的命令行程序而是一套可以沉淀、可复用、能标准化交付的安全服务能力。后续如果再遇到类似的口令安全评估项目我会直接把这套集成环境复用起来只需要更新项目字段和授权确认文件就能快速投入工作。当然工具始终只是辅助口令安全评估最终还是要回归到“提升人的安全意识”这个根本目标上。毕竟再复杂的生成器也比不上让每个用户从一开始就不使用弱口令来得实在。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门