今天我收到了网络服务商的月度账单,有件事让我觉得挺奇怪。

邮件里附带的账单是一个带密码的 ZIP 文件。

先不说在当下这个年代(垃圾邮件、恶意软件、钓鱼攻击满天飞)收到一个 ZIP 格式的附件本身就很诡异,他们选的密码也弱得让人吃惊。

密码是账户持有人的生日,格式为 YYMMDD。

我在健身房的时候,脑子里粗略算了一下,发现可能的组合数其实少得可怜。用了个在线工具算出从 1900-01-01 到现在经过了多少天(因为不是所有组合都能对应一个有效日期)之后,发现组合数一共只有 44,075 种(截止到 2020-09-14)。

我知道那些用 GPU 算力跑哈希破解的优化工具,每秒能猜几百万次。但我当时只能在健身房用一台 VPS,所以我想看看,不借助这些工具、只用 Linux/macOS 的命令行,能多快猜出密码。

我写出了下面这段代码,可以在 macOS 上运行:

echo {1..44000} | xargs -P 16 -n 1 -I{} date -v "-{}d" +"%y%m%d" | xargs -P 16 -I{} sh -c 'unzip -qqoP "{}" 0417160508.zip && echo "{}" && exit 255'

这条命令看起来挺复杂,但原理其实很简单。

echo {1..44000} 生成从 1 到 44,000 的数字,传给下一步。

xargs -P 16 -n 1 -I{} date -v "-{}d" +"%y%m%d" —— 接收第一步的输入,利用 date 的功能(给日期“加减”特定天数)生成 YYMMDD 格式的日期。这里是从当前日期往回减去 X 天,X 就是第一步生成的数字。这样就能一路生成从今天到 1900 年代的日期。

第三步是最有意思的部分,我把它拆成两块来说:

xargs -P 16 -I{} sh -c '...'

这一步拿第二步生成的日期,对每个日期执行一条命令。-P 16 表示用 16 个并行进程来跑,这样处理速度更快。第二步生成日期时也用了同样的技巧来提速。

第二部分才是真正猜密码的地方:

unzip -qqoP "{}" 0417160508.zip && echo "{}" && exit 255

这段代码先尝试用第二步生成的密码解压 ZIP 文件。如果成功了,就会打印(echo)这次猜中的密码,然后 exit 255 强制让 xargs 停止运行。毕竟密码已经找到了,没必要继续猜下去。

总而言之,拿这个当作文件密码实在是个相当糟糕的决定,因为运行上面这条命令,大概只花了 10 秒钟就猜出了我账单的正确密码。换成别人来猜,估计也快不了多少。