使用hashcat爆破各种hash

零、背景知识

1.hash函数

hash函数是一类函数的统称,这类函数的输入是任意的二进制数据,输出是固定长度的二进制数据,这类函数具有如下特点:

  • 单向性:由输入计算得到输出是简单迅速的,而由输出反推出输入在数学上讲是不可行的
  • 碰撞约束:寻找到两个不同的输入,具有相同的输出是极为困难的

满足这些特点的函数均可称为hash函数。将某数据作为hash函数的输入,计算得到输出,习惯上将这一输出称为该数据的hash值。

hash函数的一大作用便是安全地存储密码,不直接保存密码(也就是不存储明文的密码),而是保存密码的hash值,验证时只需再次计算输入的密码的hash值,与保存的密码的hash值相比较便可得知密码是否正确。由于hash函数的单向性与碰撞约束的特点,攻击者即使拿到了密码的hash值,也难以知道密码本身。

2.hashcat

攻击者拿到了密码的hash值,真的没有办法知道密码本身吗?当然不是,虽然由密码的hash值直接计算密码本身从数学上讲就是不可行的,但我们知道hash函数由输入计算得到输出是简单迅速的,大不了可以试嘛,人类可能设置的密码也就那些,一个一个地试,运气好还是可以试出来的。通过不断尝试获得hash值对应的输入的操作就被称做爆破

基于这样的思路,hashcat应运而生,据说hashcat的诞生就是为了证明爆破hash是很简单的事。hashcat自称是世界上最快的hash爆破工具,它甚至支持GPU和FGPA,如果你有的话。这里有两篇文章讲解如何用GPU快速爆破hash:

是两篇英文文章,这么好的文章自然已经有人翻译成中文了,分别在这里这里。hashcat不仅速度快,而且专业支持两百多种hash函数,使用命令:

    hashcat --help

可以看到hashcat支持的所有hash函数的列表,太多了我这里就不贴出来了。

Kali中默认安装了hashcat,可直接使用。但我的Kali安装在VirtualBox中,总觉得虚拟机会慢一些,所以想要在物理主机中使用hashcat。先到hashchat的官网下载hashcat,截止目前,最新版是v3.5.0,发布于2017.04.05,从更新日期可见hashchat是充满活力的。免去编译的麻烦,直接下载二进制包,只有2.7M,与动辄几十G的游戏相比是很小的。

下载完成后解压hashcat-3.5.0.7z,看到有:

  • hashcat32.bin
  • hashcat32.exe
  • hashcat64.bin
  • hashcat64.exe

这样的文件,分别是32位和64位下的linux中和windows中的可执行文件,按自己电脑的情况选择其中之一即可。我选择的是hashcat64.bin,为漂亮起见,在~/.bashrc文件中添加一行:

  alias hashcat='hashcat64.bin的路径'

保存后重新打开虚拟终端,使~/.bashrc文件生效,这样,无论在哪,直接输入hashcat命令就可以了,不用切换目录,也不用输入输入难看的“64.bin”,如下图所示。

好了,现在可以开始使用hashcat爆破各种hash了。

一、爆破md5

md5应该是最著名、使用最为广泛的hash函数之一了。先用Python生成几个md5值用于爆破,代码如下:

  import hashlib
  passwords = ['123123', 'bond007', 'xxxxxx', '*H@&(NT*@BR#^']
  for password in passwords:
    md5 = hashlib.md5()
    md5.update(password)
    print md5.hexdigest()

以上代码分别计算了四个字符串的hash值,输出的结果是:

  4297f44b13955235245b2497399d7a93
  cbdb7e2b1ed566ceb796af2df07205a3
  dad3a37aa9d50688b5157698acfd7aee
  d77db958c179bbffae04b2b908b75c26

将输出结果保存在文件md5.hash中,一行一个hahs值。然后用hashcat爆破这几个hash值,命令如下:

  hashcat -w 3 -a 0 -m 0 --remove -o md5.out md5.hash wordlist.dic

参数-w用于指定工作模式,共有四种,如下表所示:

N Performance Runtime Power Consumption Desktop Impact
1 Low 2 ms Low Minimal
2 Default 12 ms Economic Noticeable
3 High 96 ms High Unresponsive
4 Nightmare 480 ms Insane Headless

参数-a用于指定攻击模式,0的含义是直接地、连续的,也就是用密码字典爆破,-a的取值共有五种,如下表所示:

N Mode
0 Straight
1 Combination
3 Brute-force
6 Hybrid Wordlist + Mask
7 Hybrid Mask + Wordlist

-m用于指定要爆破的hash值的hash函数,0表示hash函数是md5,其他取值如下表所示:

N Name Category
0 MD5 Raw Hash
300 MySQL4.1/MySQL5 Database Server
1000 NTLM Operating Systems
1800 sha512crypt $6$, SHA512 (Unix) Operating Systems
2611 vBulletin < v3.8.5 Forums, CMS, E-Commerce, Frameworks

这张表太长了,我这里只展示本文中涉及到的几种hash函数,用参数–help可以看到全部。

参数–remove的含义是若成功爆破某hash值,就将该值从md5.hash中移除。

参数-o后接一个文件名,指出保存爆破结果的地方。

最后的两个参数md5.hash和wordlist.dic分别是待爆破的hash值和密码字典,hash值与密码字典都是一行一个。md5.hash中的内容已经由Python算,若你手头没有合适的密码字典,可以用命令:

  wget -O wordlist.dic https://samsclass.info/123/proj10/500_passwords.txt

下载一个。现在完事具备,按下回车,结果华丽地报错:(

  clGetPlatformIDs(): CL_PLATFORM_NOT_FOUND_KHR

大概是缺少什么运行环境,那就安装呗。我总共安装了这些东西:

  sudo apt-get install gcc make p7zip-full git lsb-core
  wget http://registrationcenter-download.intel.com/akdlm/irc_nas/9019/opencl_runtime_16.1.1_x64_ubuntu_6.4.0.25.tgz
  tar -xvf opencl_runtime_16.1.1_x64_ubuntu_6.4.0.25.tgz
  cd opencl_runtime_16.1.1_x64_ubuntu_6.4.0.25
  sudo ./install.sh

网速好的话一小会就安好了,第一条命令报错:

  /sbin/ldconfig.real: /usr/lib/nvidia-375/libEGL.so.1 is not a symbolic link
  /sbin/ldconfig.real: /usr/lib32/nvidia-375/libEGL.so.1 is not a symbolic link

但是好像不影响什么,忽略掉好了。安装完这些后,再次按下回车,运行原本报错的命令,发现果然没有再次报错,且转瞬之间,便执行完毕。命令执行完毕后查看文件md5.hash和md5.out的内容,发现md5.hash中只剩一个hash,爆破成功的三个hash已经被转移到文件md5.out中,md5.out中是三个hash值及其原值,如下图所示:

其实吧,对于md5来说,通过某些网站破解可能更简单有效,这些网站中的部分是(排名分先后):

二、爆破Windows7登录密码hash

Windows的登录密码的hash值保存在SAM文件中,SAM是“security account manager”的首字母缩写。通常,它位于

  C:\windows\system32\config\SAM

SAM文件被Windows保护,不能直接读取,需借助工具,如SAMInside。找一台Windows7虚拟机,新建一个名为hashcat的管理员用户,并设置密码,在Windows7中下载并解压SAMInside后以管理员权限运行,然后点击File->Import Local Users vis Scheduler,如下图所示:

之后SAMInside可能会“未响应”,但不要紧,耐心地等待几秒,SAMInside不负所望地读出了我们想要的hash,如下图所示:

选中我们想要爆破密码的用户“hashcat”,按Ctrl+5复制NT-hash,然后回到安装了hashcat的Ubuntu中,用如下命令将复制出的hash值保存到文件win7.hash中:

  echo 356CEAE0C89FB65ED6D6AA7A445C4CE5 > win7.hash

NT-hash便是Windows7保存登录密码使用的hash函数,接着用如下命令爆破NT-hash:

  hashcat -w 3 -a 0 -m 1000 --remove -o win7.out win7.hash wordlist.dic

片刻后执行完毕,查看win7.out文件,发现爆破成功,用户hashcat的登录密码是rush2112:

  werner@Yasser:~/hashcat$ cat win7.out
  356ceae0c89fb65ed6d6aa7a445c4ce5:rush2112

怎样拿到SAM文件可参考《如何导出Windows哈希系列一 》。下面记录我读取虚拟机Windows7中SAM文件的过程。

若是物理机,用Win PE启动机器,读取磁盘上的SAM文件即可。我的是虚拟机,将虚拟磁盘文件挂载到文件系统中就可以读虚拟磁盘中的文件了。我用的虚拟机是VirtualBox,使用命令vdfuse可以完成此事。若没有vdfuse则需先安装virtualbox-fuse:

  sudo apt-get install virtualbox-fuse

也可下载virtualbox-fuse的安装包自己安装。

安装完成后便有了vdfuse命令,可以开始虚拟磁盘映射、挂载了:

  mkdir -p ~/vmdisk
  sudo vdfuse -t VMDK -f Win7Pro32.vmdk ~/vmdisk/

执行完这步后查看~/vmdisk目录,其中有三个文件:EntireDisk、Partition1和Partition2,新建目录:

  mkdir -p ~/vmdisk_en
  mkdir -p ~/vmdisk_1
  mkdir -p ~/vmdisk_2

用mount命令分别挂载EntireDisk、Partition1和Partition2这三个文件:

  sudo mount ~/vmdisk/EntireDisk   ~/vmdisk_en
  sudo mount ~/vmdisk/Partition1   ~/vmdisk_1
  sudo mount ~/vmdisk/Partition2   ~/vmdisk_2

发现,EntireDisk挂载失败,Partition1中内容不是我想要的,Partition2中是Windows7虚拟机中的文件,正是我想要的。从vmdisk_fs中复制出我们的目标SAM文件:

  cp ~/vmdisk_2/Windows/System32/config/SAM ./

顺便把SYSTEM文件也复制出来:

  cp ~/vmdisk_2/Windows/System32/config/SYSTEM ./

查看SAM文件的内容,如下图所示,竟然不是纯文本文件,果然是Windows的风格,

好吧,虽然成功打开了SAM文件,但我们还是没有得到hash,接下来改怎么办?只能借助工具解析SAM文件内容了。把SAM文件和SYSTEM文件都搞到Kali中,运行命令:

  samdump2 -o sam.hash SYSTEM SAM

然后查看sam.hash,也可以看到各个用户登录密码的hash值。sam.hash文件中每行是一个用户,每一行的格式均为:

  用户名称:RID:LM-hash值:NTLM-hash值

注意此格式是samdump2命令输出格式,并不是“Windows下的Hash密码格式”。

三、爆破linux登录密码hash

首先,得有一台运行linux系统的电脑,这个好说,虚拟机就可以了。然后,运行如下命令添加新用户并设置密码,以供我们爆破之用:

  sudo adduser justforfun

linux中用户登录密码的hash值存放在文件/etc/shadow中(注意:不是/etc/passwd),使用如下命令查看新建用户的登录密码的hash值:

test@test-VirtualBox:~$ sudo tail -n 1 /etc/shadow
justforfun:$6$0fokwg59$6hpMS5dM9wDT/42DDoSD0i0g/wHab50Xs9iEvVLC3V20yf1kRmXZHGXCM0Efv6XU69hdgMZ4FwaMzso4hQaGQ0:17373:0:99999:7:::

tail命令用于读一个文件的最后几行,默认是10行,用参数-n指定行数。我们刚刚新建的用户自然在最后一行,故用tail -n 1读取。读到的结果是以“:”分割的数据,第一部分是用户名“justforfun”,第二部分便是密码的hash值了,其他的部分在本文中不必关心。我们重点研究第二部分。

开头的“$6$”指所用hash函数的类型为SHA-512,除“$6$”外,在linux中,“$1$”指MD5, “$2a$”指Blowfish, “$2y$”指Blowfish(correct handling of 8-bit chars), “$5$”指SHA-256,详情参见维基百科:passwd。此外,文件/etc/login.defs也对hash算法有所说明。

“$6$”开始到下一个“$”之前的部分“0fokwg59”是盐(SALT)。什么是盐呢?百度知道CNB2009对问题“什么是md5盐值”的回答简单易懂:

简单说就是为了使相同的密码拥有不同的hash值的一种手段,就是盐化。MD5自身是不可逆的,但是目前网路上有很多数据库支持反查询,如果用户密码数据库不小心被泄露,黑客就可以通过反查询方式获得用户密码,或者对于数据库中出现频率较高的hash码(即很多人使用的)进行暴力破解(因为它通常都是弱口令)。盐值就是在密码hash过程中添加的额外的随机值,比如我的id是癫ω倒④ゞ,密码是123456,存在数据库中的时候就可以对字符串“123456/癫ω倒④ゞ ”进行hash,而验证密码的时候也以字符串“(要验证的密码)/癫ω倒④ゞ ”进行验证。这样有另外一个笨蛋密码是123456的时候,依然能构造出不同的hash值,并且能成功的验证。这时候我的id就作为盐值 为密码进行复杂hash了。所以么。。盐值的作用是减少数据库泄露带来的损失。如果你RP非常好,猜中了我的密码是123456,我也阻止不了你啊

该回答针对md5,其他hash函数同理。盐之后的部分就是hash值了。现在复制整个第二部分到文件linux.hash中,linux.hash中的内容应为:

 $6$0fokwg59$6hpMS5dM9wDT/42DDoSD0i0g/wHab50Xs9iEvVLC3V20yf1kRmXZHGXCM0Efv6XU69hdgMZ4FwaMzso4hQaGQ0

然后用如下命令爆破linux登录密码hash:

  hashcat -w 3 -a 0 -m 1800 --remove -o linux.out linux.hash wordlist.dic

片刻后,爆破完成,查看结果:

werner@Yasser:~/hashcat$ cat linux.out
$6$0fokwg59$6hpMS5dM9wDT/42DDoSD0i0g/wHab50Xs9iEvVLC3V20yf1kRmXZHGXCM0Efv6XU69hdgMZ4FwaMzso4hQaGQ0:4321

可见爆破成功。

四、爆破Mysql登录密码hash

首先,得有Mysql。刚好我虚拟机中就有。百度可知Mysql的登录密码的hash值保存在文件user.MYD中。文件user.MYD又在哪里?我也不知道啊,就找呗:

  test@test-VirtualBox:~$ sudo find / -name user.MYD
  /var/lib/mysql/mysql/user.MYD

找到了,是在/var/lib/mysql/mysql/user.MYD,查看该文件内容:

  sudo cat /var/lib/mysql/mysql/user.MYD

不是纯文本文件,关系不大,还是看得出用户root的登录密码的hash值是:

  6B825255FB466413D6B1B724644E23428C94BBCB

将此值保存到文件mysql.hash中,用如下命令爆破Mysql登录密码hash:

  hashcat -w 3 -a 0 -m 300 --remove -o mysql.out mysql.hash wordlist.dic

片刻后,爆破完成,查看结果:

  werner@Yasser:~/hashcat$ cat mysql.out
  6b825255fb466413d6b1b724644e23428c94bbcb:viper

可见爆破成功。

五、爆破Discuz!论坛密码

Discuz!是我国知名的php论坛程序,使用极为广泛。现在我们来爆破下Discuz!用户密码的hash值。首先得找到hash值,从哪里找呢?当然是从Discuz!的数据库里。

可Discuz!的数据库又在哪里?我是这么解决的,从它的官网下载最新版Discuz!源码,运行安装,便得到了Discuz!的数据库:)

Discuz!的默认数据库名为ultrax,其中的pre_ucenter_members表中保存着登录密码的hash值,“pre_”是默认的前缀,在安装时可以改变,“ucenter_members”是不会变的。用如下sql语句查询出登录密码的hash值:

  select password,salt from pre_ucenter_members;

保存hash值和盐值到文件:

  echo 69bcba126b93c6f397983629a0f70553:c13fd9 > discuz.hash

hash值和盐值在同一行中,以“:”分割。最后,用如下命令爆破Discuz登录密码hash:

  hashcat -w 3 -a 0 -m 2611 --remove -o discuz.out discuz.hash wordlist.dic

片刻后,爆破完成,查看结果:

  werner@Yasser:~/hashcat$ cat discuz.out
  69bcba126b93c6f397983629a0f70553:c13fd9:winter

可见爆破成功。

六、大字典测试

截止目前,我们使用仅仅500个单词的小字典,每次都只需片刻,便顺利地爆破了各种hash,不觉得奇怪吗?这是因为我为练习使用hashcat而故意设置在字典内的弱密码,否则爆不出来岂不是让人心情很差。实际中就不可能有这么好的运气了。我们来随便计算一个不那么弱的密码的md5值,用大字典爆破,一方面试试运气,另一方面看看hashcat能有多快。

首先计算md5值:

  import hashlib
  md5 = hashlib.md5()
  md5.update("werner123456!!!")
  print md5.hexdigest()

输出为:

  b17133f9abff287ed0546c1af2b171f7

然后选择一个10.5G大小,内含9.4亿密码的字典,开始爆破:

  hashcat -w 3 -a 0 -m 0 --remove -o big.out b17133f9abff287ed0546c1af2b171f7 big.dic

注意到,只有一个hash值时,不用保存在文件中,直接写在命令行参数中也可以。睡觉前开始爆破,第二天起来看结果,发现:

  Started: Wed Jul 26 22:55:27 2017
  Stopped: Wed Jul 26 23:02:28 2017

原来只用了7分钟!我原以为要用7个小时,比我预想的快了60倍!有点遗憾的是,并没有成功的爆破出hash值,看来“werner123456!!!”并不在密码字典中。看来我需要准备一个100G的密码字典,但这么大的字典保存、转移都很不方便,没有其他办法吗?当然有,还记得攻击模式吗?我们一直在使用“Straight”模式,接下来,研究下其他几种模式吧。这篇文章已经够长了,在另一篇文章中研究其他攻击模式吧。

七、总结

使用hashcat爆破hash,第一是要找准hash,不同的系统、不同的软件,其hash存放的位置不同,需要准确地找出hash值来;第二是要正确判断hash类型,确定hashcat是否支持这种hash,选对-m的参数,否则几乎不可能成功;第三是密码字典要好,最终能否爆破成功,还是看字典。密码字典虽不是越大越好,但总归还是大点的好,hashcat也以速度著称,大字典对hashcat不是问题。这里记录一个比较好的字典:历次泄密门+常用弱口令字典集合.7z,解压密码是:anywlan。另外,若是收集了很多小字典,可以将小字典合并、排序、去重,得到一个大字典,以便于hashcat爆破之用。如果小字典在同一个目录下,使用一条命令就可以搞定:

    cat * | sort | uniq > Merge.dic

若是小字典被按类别整理,分布在多层目录中呢?只用cat命令显然不行,但其实也只需一条命令就可以了,假设小字典们均被存放在目录MyDictionary中,则命令可以这样写:

    find ./MyDictionary -type f -exec cat {} \; | sort | uniq > Merge.dic

2 Replies to “使用hashcat爆破各种hash”

发表评论

电子邮件地址不会被公开。 必填项已用*标注