我工作的大多数Django项目都利用了django.contrib.auth 。它管理
用户和组,并与django.contrib.admin 。在这篇文章中,我们
将
探讨它如何抵御潜在的攻击者。
下面的研究假设攻击者从数据库中获得了加密的密码列。
mysql> select password from auth_user limit 1;
+-------------------------------------------------------------------------------+
| password |
+-------------------------------------------------------------------------------+
| pbkdf2_sha256$20000$H0dPx8NeajVu$GiC4k5kqbbR9qWBlsRgDywNqC2vd9kqfk7zdorEnNas= |
+-------------------------------------------------------------------------------+
<algorithm>$<iterations>$<salt>$<hash>
随着计算机的速度越来越快,密码的哈希运算也越来越快。这一点很重要,因为密码散列提供的唯一保护是使 "猜测 "加密密码更加耗时。
你可以转动2个旋钮来增加这个时间,即algorithm 和
iterations 。自Django 1.4(2012年发布)以来,它使用的默认算法是NIST推荐的PBKDF2。值得注意的是,从那时起,迭代参数至少增加了4次。1, 2,3,4
.
考虑到这一点,我很想知道用不到100美元的有限预算和几天时间能破解多少个密码。对你自己的数据库进行类似的实验,将有助于你评估自己的密码政策的有效性。你即将发现,这比你想象的要容易。事实上,大多数的密码 "恢复 "工具都可以处理Django的密码加密格式,而且是开箱即用。
恢复Django密码
下面的演示使用了一个谷歌云服务器和hashcat,并进行了一些基本的调整。它使用众所周知的rockyou 字典进行攻击,该字典在互联网上很容易找到。
配置服务器
首先用gcloud CLI初始化。
$ gcloud init
然后,在开发者控制台创建一个项目,
在计费信息下
给它分配一个预算
,并启用谷歌计算API
。
在这一点上,你应该能够列出可用的资源。
$ gcloud compute regions describe europe-west1 | grep -B1 GPU
- limit: 0.0
metric: NVIDIA_K80_GPUS
--
- limit: 0.0
metric: NVIDIA_P100_GPUS
--
- limit: 0.0
metric: PREEMPTIBLE_NVIDIA_K80_GPUS
--
- limit: 0.0
metric: PREEMPTIBLE_NVIDIA_P100_GPUS
--
- limit: 0.0
metric: NVIDIA_V100_GPUS
如果像我一样,你的限额在所有这些卡上都是0.0 ,你将需要提交一个配额增加。在这个实验中,我申请了8个NVIDIA K80 GPU的配额。根据谷歌的说法,这个步骤可能需要几天时间。我被要求向我的账户添加280美元,第二天就获得了配额增加。
根据谷歌的估算,一个拥有8个英伟达K80 GPUS的云服务器每天的成本约为63美元,或每小时2.7美元。在实践中,preemptible 模式使其更加便宜。
随着我的配额增加,我启动了这个实例。
$ gcloud compute instances create yml-gpu-4 \
--machine-type n1-standard-4 \
--zone europe-west1-b \
--accelerator type=nvidia-tesla-k80,count=8 \
--image-family ubuntu-1604-lts \
--image-project ubuntu-os-cloud \
--maintenance-policy TERMINATE \
--restart-on-failure \
--preemptible
设置服务器
接下来,我安装一些我认为在这种情况下有用的实用程序。
$ sudo apt install gnupg2 tmux htop p7zip-full git-core
然后,用这个脚本安装最新的NVIDIA驱动。
#!/bin/bash
echo "Checking for CUDA and installing."
# Check for CUDA and try to install.
if ! dpkg-query -W cuda-8-0; then
# The 16.04 installer works with 16.10.
curl -O https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
dpkg -i ./cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
apt-get update
apt-get install cuda-8-0 -y
fi
# Enable persistence mode
nvidia-smi -pm 1
安装hashcat。
$ wget https://hashcat.net/files/hashcat-4.1.0.7z
$ 7z x hashcat-4.1.0.7z
$ git clone https://github.com/praetorian-inc/Hob0Rules
提取密码哈希值
我将分析限制在已被授予
Django管理界面访问权
的用户
。
$ echo "select password from auth_user where is_staff;"| manage.py dbshell > django_hashes.txt
运行攻击
一切准备就绪后,我使用密码字典进行了攻击。
$ ./hashcat64.bin -m 10000 ~/django_hashes.txt ~/rockyou.txt
你可以用基于规则的攻击来调剂字典。
注意,这将大大增加执行攻击所需的时间。
$ ./hashcat64.bin -m 10000 -r ~/Hob0Rules/hob064.rule ~/django_hashes.txt ~/rockyou.txt
这是一个更快的
选择
,但缺点是你会失去估计的完成时间。
$ ./hashcat64.bin -w 3 --stdout -r ~/Hob0Rules/hob064.rule ~/rockyou.txt \
| ./hashcat64.bin -m 10000 ~/django_hashes.txt
结果
完成后,你可以从hashcat中获得你的密码。
$ ./hashcat64.bin -m 10000 --show ~/django_hashes.txt
我在几个不同的真实世界的数据集上测试了这种方法,并且能够在几个小时内恢复每个数据集中~10-25%的哈希值。总共,我破解了246个密码,在谷歌云上花费了73美元。我每个恢复的哈希值的成本是0.30美元。
总结
这篇文章几乎没有触及你可以用hashcat做什么的表面。可以投入大量时间使它在你的硬件上运行得更快,并对你使用的攻击类型或字典进行微调。
我了解到,暴力破解密码比听起来更容易、更便宜。如果你担心你的密码的安全性,我建议研究以下选项,以减少你的潜在风险。
- 对开发人员和非生产系统的数据库转储进行窜改/匿名化,以减少数据泄漏的风险。
- 限制登录页面的速度。
- 将你的管理界面保持在开放的互联网之外。使用SSH、VPN等。
- 强制执行密码复杂性和长度要求。
- 将Django更新到至少最新的LTS版本。
- 增加迭代次数和/或选择一个更昂贵的算法来计算。