破解Django密码哈希值的方法

635 阅读4分钟

我工作的大多数Django项目都利用了django.contrib.auth 。它管理
用户和组,并与django.contrib.admin 。在这篇文章中,我们

探讨它如何抵御潜在的攻击者。

下面的研究假设攻击者从数据库中获得了加密的密码列。

mysql> select password from auth_user limit 1;
+-------------------------------------------------------------------------------+
| password                                                                      |
+-------------------------------------------------------------------------------+
| pbkdf2_sha256$20000$H0dPx8NeajVu$GiC4k5kqbbR9qWBlsRgDywNqC2vd9kqfk7zdorEnNas= |
+-------------------------------------------------------------------------------+

Django以如下格式存储密码

<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做什么的表面。可以投入大量时间使它在你的硬件上运行得更快,并对你使用的攻击类型或字典进行微调。

我了解到,暴力破解密码比听起来更容易、更便宜。如果你担心你的密码的安全性,我建议研究以下选项,以减少你的潜在风险。

  1. 对开发人员和非生产系统的数据库转储进行窜改/匿名化,以减少数据泄漏的风险。
  2. 限制登录页面的速度。
  3. 将你的管理界面保持在开放的互联网之外。使用SSH、VPN等。
  4. 强制执行密码复杂性和长度要求。
  5. 将Django更新到至少最新的LTS版本。
  6. 增加迭代次数和/或选择一个更昂贵的算法来计算。