黑科技新篇章:利用神经网络破解密码
0×01 背景
去年一次偶然的机会,我看到了一篇介绍神经网络的有趣文章(https://karpathy.github.io/2015/05/21/rnn-effectiveness/)。我曾经接触过神经网络,受此文章启发,我就开始思考神经网络在信息安全领域的使用。据我了解,目前人们已经在入侵检测系统或类似的安全防御策略里使用神经网络了。但是如果从攻击者角度出发,神经网络是否可以用来帮助开展攻击或者入侵行为。
读完Karpathy's的文章后,尤其是看完给新生婴儿取名这块,我一直在想,神经网络是否可以学习人类设置密码的方式。想象这样一个场景,假设你有一个大型网站(facebook、推特、新浪等)后台用户帐户密码库,这个库非常庞大,几百G甚至P级别的,都是经过hash形式将用户密码进行加密。根据这个网站用户特点,也许存在一种你不知道的密码设定方式。因此,让我们看看如果一个循环神经网络系统能找出这种新模式,同时生成新的无法破解的hash散列密码。
0×02安装
声明:我不是机器学习领域的专家,如果我下面存在错误的地方,请大家指正。在实际研究过程中,我没有完成机器训练模块,仅仅停留在理论证明上面。
我不想浪费我的时间和机器资源在hash加密或密码破解上面。于是我跳过了安装,直接下载了rockyou.txt (https://downloads.skullsecurity.org/passwords/rockyou.txt.bz2)。我一直以为这个字典是去重了的,但是我发现不是这样,我最后自己把这个字典去重了一次。
$> sort rockyou.txt | uniq -u > rockyou.unique.txt $> du -sb rockyou.* 139921497 rockyou.txt 139842217 rockyou.unique.txt
同时我不喜欢被破解的字典被排序了,所以我又把字典的顺序进行了打乱:
$> sort -R rockyou.unique.txt > rockyou.random.txt
我随后又把这个字典包分割成了两块,一块包含250,000的密码数据,是用来做机器学习训练的。另一块用来做测试。
$> head -n 250000 rockyou.random.txt > train.txt
为了保证训练数据和测试数据没有重叠的,我又进行了一次去重操作。
$> sort train.txt test.txt | uniq -d | wc -l 0
目前我没有CUDA集群,因此我租用了一个AWS GPU g2.2xlarge spot instance 几小时。spot instances相对来说十分便宜,也十分适合做这个实验。已经有人集成了所有的工具和CUDA的驱动安装程序和配置,链接如下:https://github.com/brotchie/torch-ubuntu-gpu-ec2-install。你要做的仅仅是运行如下步骤:
$> cd /tmp/ $> sudo luarocks install nngraph $> sudo luarocks install optim $> git clone https://github.com/karpathy/char-rnn $> cd char-rnn
最后一步就是要上传train.txt文件到/tmp/char-rnn/data/pws/input.txt
在神经网络10时代之内,我训练三个数据集。
$> th train.lua -rnn_size 128 -num_layers 3 -eval_val_every 500 -seq_length 50 -data_dir data/pws/ -savefile pws $> th train.lua -rnn_size 512 -num_layers 3 -eval_val_every 500 -seq_length 100 -data_dir data/pws/ -savefile pws2 $> th train.lua -rnn_size 64 -num_layers 3 -eval_val_every 500 -seq_length 20 -data_dir data/pws/ -savefile pws3
在每一代中,我让输出控制在25kb的大小
$> th sample.lua -length 25000 cv/lm_pws_epochXY > output/pws-epochXY
所有的文件按照如下格式进行生成pwsX-EPOCH[-t].txt ,其中:
X 代表网络 id EPOCH 代表保存的文件在第几代中 -t 代表采样的顺序标记
0×03结果展现
再一次申明,我们的目的是为了证明神经网络在已学习相关训练数据后可以预测密码设定模式。现在我们获得了一部分结果,让我们来瞧瞧:
神经网络单元1:
Neurons per layer: 128 Layers: 3 Sequence length: 50
这个计算网元生成31,000的独立的密码,其中只有92个在训练样本里面。
$> cat pws-* | sort | uniq -u > output-1.txt $> wc -l output-1.txt 31441 output-1.txt $> sort output-1.txt train.txt | uniq -d | wc -l 92
其中3180个在测试样本里面
$> sort output-1.txt test.txt | uniq -d | wc -l 3180
我们看看其中的数据:
$> sort output-1.txt test.txt | uniq -d | sort -R | head -n 25 freddy12 ava2005 joseph2006 sexylexy marcolo jackson7 jackson1 ariela11 andrew12345 mercedes23 brittshit 19081984 jklover boodoo eliana19 725972 daliani pacy99 121093a celin1 Hottie. andrew1010 tatty9 karina79 amanda213 080223
神经网络单元2:
Neurons per layer: 512 Layers: 3 Sequence length: 100
这个单元我没有进行太长时间的训练,生成的5000个密码中,3个在训练样本里面,178个在测试样本里面。
$> wc -l output-2.txt 5046 output-2.txt $> sort output-2.txt train.txt | uniq -d | wc -l 3 $> sort output-2.txt test.txt | uniq -d | wc -l 178 $> sort output-2.txt test.txt | uniq -d | sort -R | head -n 25 zhan23 hooda1 dobes 081087 69777 jestin 492007 25372 griss34 14711 172085 ka2006 ellva 10113 franz27 nissa09 33 012187 a 1113sd ilove2 ford19 40309 kina13 kiku13
神经网络单元3:
Neurons per layer: 64 Layers: 3 Sequence length: 20
在最小的一个神经网元里面生成了1500个密码,其中15个在训练样本里面,726个在测试样本里面。
$> wc -l output-3.txt 14976 output-3.txt $> sort output-3.txt train.txt | uniq -d | wc -l 15 $> sort output-3.txt test.txt | uniq -d |wc -l 726 $> sort output-3.txt test.txt | uniq -d | sort -R | head -n 25 dannica hissss lobe21 carlo14 ho killer1 candice12 laiska kaley2 pusher1 778658 7344501 leanng bron55 GOLLITA jaimi 490767 552655 71 12 cocker07 660244 nanina hirann love19
综合统计:
综合前面三个神经网元的统计数据,我们获得超过50,000的密码,其中3,8000在测试样本里面,105个在训练样本里面。
$> wc -l output-all.txt 50691 output-all.txt $> sort output-all.txt train.txt | uniq -d | wc -l 105 $> sort output-all.txt test.txt | uniq -d | wc -l 3881 $> sort output-all.txt test.txt | uniq -d | sort -R | head -n 25 newmon chesar pawita opalla buster6 reneeia singers123 patito123 6312355 biggie1 297572 jairo01 bday1992 coolboy1 meeka1 blackie laura25 neil10 mone10 12345sexy dog143 193208 mash28 alexa87 793806
我能确定的是,如果能训练的时间再长一点、添加其他的学习参数或者在学习过程中使用-primetext选项,神经网络能预测更多的密码。所有数据可以通过https://github.com/gehaxelt/RNN-Passwords进行下载。
0×04总结
综上所述,使用神经网络来学习样本密码,根据样本密码特性来生成一些目前未知的密码,这种方法是可行的。但是根据训练和测试数据量的大小,及生成的非常少的预测密码,我不认为这种方式有何实际的意义。