【Python】Python绝技第一章 入门 python3实现密码破解

Python绝技第一章 入门 python3实现密码破解

春告鳥发布于 2 月 6 日

前言

对我而言,武术的非凡之处在于它的简单。简单的方法也是正确的方法,同时武术也没有什么特别之处。越接近武术的真谛,招式表现上浪费越少

简介

python 绝技 第一章是python入门语法,两个需要编写的程序分别是用字典攻击法破解UNIX口令暴力破解ZIP文件,两者都是使用暴力法直接进行破解,另外第一个程序在当前的网络环境中已经不太适用了,我们将其升级为破解SHA-512 hash的版本

背景故事

虽然在书中已经有背景故事的翻译了,但是这里我还是采用乌云之前翻译的版本

SHA-512 hash 破解

环境 : python3

在破解之前我们先了解一下shadow格式

root:$1$v2wT9rQF$XSpGgoB93STC4EFSlgpjg1:14181:0:99999:7:::

可以发现shadow中每一行对应这一个用户的用户名和密码等信息,格式为0:1:2:3:4:5:6:7:8

冒号是分割符,分别代表着,每个字段分别代表着:

0:用户名

1:密码hash值

2:密码修改距离1970年1月1日的时间

3:密码将被允许修改之前的天数(0 表示“可在任何时间修改”)

4:系统将强制用户修改为新密码之前的天数(1 表示“永远都不能修改”)

5:密码过期之前,用户将被警告过期的天数(-1 表示“没有警告”)

6:密码过期之后,系统自动禁用帐户的天数(-1 表示“永远不会禁用”)

7:该帐户被禁用的天数(-1 表示“该帐户被启用”)

8:保留供将来使用

hash值一览格式如:$id$salt$密文

id代表的是使用不同的加密算法,不同的系统使用的算法也不尽相同。salt是加密的时候需要用到盐。最后就是密文。

数字和所使用的加密算法对应关系:

格式算法
$1md5
$2ablowfish
$2yblowfish
$5sha-256
$6sha-512

注意:如果密码字符串为*,表示系统用户不能被登入,为!表示用户名被禁用,如果密码字符串为空,表示没有密码。

这里我们使用python3中的hashlib库计算sha-512

hash=hashlib.sha512(salt.encode('utf-8'))

hash.update(word.encode('utf-8'))

print(hash.hexdigest())

这样实现了sha-512加密,但是,这里的结果并不像是我们Linux操作系统中的密码,譬如我们上面举例的密码中:

XSpGgoB93STC4EFSlgpjg1

其中就包含了不在十六进制中的字符

事实上以$6为例并不是单纯的sha512(pass+salt)或者sha512(salt+passwd),而是经历了一系列复杂的运算而获得的。

我们先实现sha-512的解密

import hashlib

'''

testPass(cryptPass)函数

功能:

传入 cryptPass 待解密密码

print 破解结果

算法:穷举法

'''

def testPass(cryptPass):

salt,shadowPass=cryptPass.split('$')[2],cryptPass.split('$')[3]

dictFile=open('dictionary.txt','r')

for word in dictFile.readlines():

word=word.strip()

# print(word)

hash=hashlib.sha512(salt.encode('utf-8'))

hash.update(word.encode('utf-8'))

# print(hash.hexdigest())

if shadowPass==hash.hexdigest():

print("[+] Found Password {}".format(word))

return

print("[-] Password Not Found ")

return

def main():

passFile=open('passwords.txt')

for line in passFile.readlines():

if ":" in line:

user=line.split(':')[0]

cryptPass=line.split(':')[1].strip(' ')

print("[*] Now cracking Password For :{}".format(user))

testPass(cryptPass)

if __name__ == '__main__':

main()

这里的密码文件是我们构造的

root:$6$123$263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62:15503:0:99999:7:::

实际上是密文123同时盐值123

【Python】Python绝技第一章 入门 python3实现密码破解

运行破解

【Python】Python绝技第一章 入门 python3实现密码破解

破解成功

shadow密码破解

上面举例的密码是我们在cmd5网站上自行构造的,但*nix操作系统上密码并不是简单的sha512(pass+salt)或者sha512(salt+passwd),但在简书上找到了一位师傅之前使用hashlib来还原该加密算法python生成shadow中密码(SHA512)

import hashlib,math

def rstr_sha512(text: bytes) -> bytes:

sha512 = hashlib.sha512()

sha512.update(text)

return sha512.digest()

def _extend(source: bytes, size_ref: int) -> bytes :

extended = b"";

for i in range(math.floor(size_ref/64)):

extended += source;

extended += source[:size_ref % 64]

return extended;

def _sha512crypt_intermediate(password: bytes,salt: bytes) -> bytes:

#digest_a = rstr_sha512(password + salt)

digest_b = rstr_sha512(password + salt + password)

digest_b_extended = _extend(digest_b,len(password))

intermediate_input = password + salt + digest_b_extended

passwd_len = len(password)

while passwd_len!=0:

if passwd_len&1 == 1:

intermediate_input += digest_b

else:

intermediate_input += password

passwd_len >>= 1

return rstr_sha512(intermediate_input)

def _sha512crypt(password :bytes,salt :bytes,rounds :int) -> bytes:

digest_a = _sha512crypt_intermediate(password, salt)

p = _extend(rstr_sha512(password*len(password)),len(password))

s = _extend(rstr_sha512(salt*(16+digest_a[0])),len(salt))

digest = digest_a

for i in range(rounds):

c_input = b""

if i&1 :

c_input += p

else:

c_input += digest

if i % 3:

c_input += s

if i % 7:

c_input += p

if i & 1:

c_input += digest

else:

c_input += p

digest = rstr_sha512(c_input)

return digest

def sha512crypt(password :bytes,salt :bytes, rounds=5000) -> str:

salt = salt[:16] # max 16 bytes for salt

input = _sha512crypt(password, salt, rounds)

tab = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

order = [ 42, 21, 0, 1, 43, 22, 23, 2, 44, 45, 24, 3,

4, 46, 25, 26, 5, 47, 48, 27, 6, 7, 49, 28,

29, 8, 50, 51, 30, 9, 10, 52, 31, 32, 11, 53,

54, 33, 12, 13, 55, 34, 35, 14, 56, 57, 36, 15,

16, 58, 37, 38, 17, 59, 60, 39, 18, 19, 61, 40,

41, 20, 62, 63]

output = ""

for i in range(0,len(input),3):

# special case for the end of the input

if i+1 >= len(order): # i == 63

char_1 = input[order[i+0]] & 0b00111111

char_2 = (input[order[i+0]] & 0b11000000) >> 6

output += tab[char_1] + tab[char_2]

else:

char_1 = input[order[i+0]] & 0b00111111

char_2 = (((input[order[i+0]] & 0b11000000) >> 6) |

(input[order[i+1]] & 0b00001111) << 2)

char_3 = (

((input[order[i+1]] & 0b11110000) >> 4) |

(input[order[i+2]] & 0b00000011) << 4)

char_4 = (input[order[i+2]] & 0b11111100) >> 2

output += tab[char_1] + tab[char_2] + tab[char_3] + tab[char_4]

if rounds!=5000:

return "$6$rounds={}${}${}".format(rounds,salt.decode("utf-8"),output)

else:

return "$6${}${}".format(salt.decode("utf-8"),output)

if __name__ == "__main__":

# 与crypt.crypt("123456","$6$123456") 运算结果一致

print(sha512crypt(b"123456",b"123456",5000))

ubuntu 16.04虚拟机里面添加一个账号为test123,密码为123的用户

【Python】Python绝技第一章 入门 python3实现密码破解

接着查看shadow文件中其对应的密码

【Python】Python绝技第一章 入门 python3实现密码破解

test123:$6$DhlRUwqV$Jln02cwolkp3adJjELMn9q2MxKRalcdzyyJnMg3EayVMgNQ0v9plYEnFns58sBkfUROfhT4Fsdksoxjfr5nVA/:18664:0:99999:7:::

将简书的师傅代码修改为字典破解的版本

import hashlib,math

def rstr_sha512(text: bytes) -> bytes:

sha512 = hashlib.sha512()

sha512.update(text)

return sha512.digest()

def _extend(source: bytes, size_ref: int) -> bytes :

extended = b""

for i in range(math.floor(size_ref/64)):

extended += source

extended += source[:size_ref % 64]

return extended

def _sha512crypt_intermediate(password: bytes,salt: bytes) -> bytes:

#digest_a = rstr_sha512(password + salt)

digest_b = rstr_sha512(password + salt + password)

digest_b_extended = _extend(digest_b,len(password))

intermediate_input = password + salt + digest_b_extended

passwd_len = len(password)

while passwd_len!=0:

if passwd_len&1 == 1:

intermediate_input += digest_b

else:

intermediate_input += password

passwd_len >>= 1

return rstr_sha512(intermediate_input)

def _sha512crypt(password :bytes,salt :bytes,rounds :int) -> bytes:

digest_a = _sha512crypt_intermediate(password, salt)

p = _extend(rstr_sha512(password*len(password)),len(password))

s = _extend(rstr_sha512(salt*(16+digest_a[0])),len(salt))

digest = digest_a

for i in range(rounds):

c_input = b""

if i&1 :

c_input += p

else:

c_input += digest

if i % 3:

c_input += s

if i % 7:

c_input += p

if i & 1:

c_input += digest

else:

c_input += p

digest = rstr_sha512(c_input)

return digest

def sha512crypt(password :bytes,salt :bytes, rounds=5000) -> str:

salt = salt[:16] # max 16 bytes for salt

input = _sha512crypt(password, salt, rounds)

tab = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

order = [ 42, 21, 0, 1, 43, 22, 23, 2, 44, 45, 24, 3,

4, 46, 25, 26, 5, 47, 48, 27, 6, 7, 49, 28,

29, 8, 50, 51, 30, 9, 10, 52, 31, 32, 11, 53,

54, 33, 12, 13, 55, 34, 35, 14, 56, 57, 36, 15,

16, 58, 37, 38, 17, 59, 60, 39, 18, 19, 61, 40,

41, 20, 62, 63]

output = ""

for i in range(0,len(input),3):

# special case for the end of the input

if i+1 >= len(order): # i == 63

char_1 = input[order[i+0]] & 0b00111111

char_2 = (input[order[i+0]] & 0b11000000) >> 6

output += tab[char_1] + tab[char_2]

else:

char_1 = input[order[i+0]] & 0b00111111

char_2 = (((input[order[i+0]] & 0b11000000) >> 6) |

(input[order[i+1]] & 0b00001111) << 2)

char_3 = (

((input[order[i+1]] & 0b11110000) >> 4) |

(input[order[i+2]] & 0b00000011) << 4)

char_4 = (input[order[i+2]] & 0b11111100) >> 2

output += tab[char_1] + tab[char_2] + tab[char_3] + tab[char_4]

if rounds!=5000:

return "$6$rounds={}${}${}".format(rounds,salt.decode("utf-8"),output)

else:

return "$6${}${}".format(salt.decode("utf-8"),output)

def testPass(cryptPass):

salt,shadowPass=cryptPass.split('$')[2],cryptPass.split('$')[3]

dictFile=open('dictionary.txt','r')

for word in dictFile.readlines():

word=word.strip()

# print(word)

tempPassWord=sha512crypt(bytes(word, encoding = "utf8"), bytes(salt, encoding = "utf8"), 5000)

# print("temppassword is {}".format(tempPassWord))

# print("shadowpassword is {}".format(shadowPass))

if cryptPass==tempPassWord:

print("[+] Found Password {}".format(word))

return

print("[-] Password Not Found ")

return

def main():

passFile=open('passwords.txt')

for line in passFile.readlines():

if ":" in line:

user=line.split(':')[0]

cryptPass=line.split(':')[1].strip(' ')

print("[*] Now cracking Password For :{}".format(user))

testPass(cryptPass)

if __name__ == "__main__":

# 与crypt.crypt("123456","$6$123456") 运算结果一致

# print(sha512crypt(b"123",b"DhlRUwqV",5000))

main()

运行结果如图:

【Python】Python绝技第一章 入门 python3实现密码破解

破解成功,该脚本可用于Linux弱口令批量爆破

zip口令破解

zip口令破解比较简单,破解的成功与否还是在于密码文件的构造,同时可能会出现在CTF题目中,阴间题目比如说设置压缩包密码为不可见字符,需要自己编写脚本来进行破解

另外如果python3代码完全按照书上这么写会有一个报错

def extractFile(zFile,password):

try:

# print(password)

zFile.extractall(pwd=password)

print("[+] Found password {}".format(password))

except Exception as e:

pass

需要将password转为二进制传入

zFile.extractall(pwd=password.encode(encoding='utf-8', errors = 'strict'))

完整代码如下

import zipfile

import optparse

from threading import Thread

def extractFile(zFile,password):

try:

# print(password)

zFile.extractall(pwd=password.encode(encoding='utf-8', errors = 'strict'))

print("[+] Found password {}".format(password))

except Exception as e:

pass

def main():

parser=optparse.OptionParser("参数说明 -f <压缩包文件名> -d <密码txt文件名>")

parser.add_option('-f',dest='zname',type='string',help='压缩包文件名')

parser.add_option('-d',dest='dname',type='string',help='密码文件名')

(options,args)=parser.parse_args()

if (options.zname==None) or (options.dname==None):

print(parser.usage)

exit(0)

zname,dname=options.zname,options.dname

zFile=zipfile.ZipFile(zname)

passFile=open(dname)

for line in passFile.readlines():

password=line.strip()

t=Thread(target=extractFile,args=(zFile,password))

t.start()

return

if __name__ == '__main__':

main()

创建一个密码为admin的压缩包 key.zip

使用程序破解之

【Python】Python绝技第一章 入门 python3实现密码破解

破解成功

完整代码和字典文件放在github上了,欢迎师傅们Star:https://github.com/Cl0udG0d/pythonStunt

参考链接

  • http://www.vuln.cn/8178
  • https://gv7.me/articles/2017/batch-crack-shadows/
  • https://blog.csdn.net/deargua/article/details/6666121
  • https://www.jianshu.com/p/9da78abd6a96

欢迎关注公众号 芸潘

【Python】Python绝技第一章 入门 python3实现密码破解~~~~

segmentfaultpython程序员ubuntu安全

阅读 7发布于 2 月 6 日

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议

avatar

春告鳥

公众号 芸潘

1 声望

0 粉丝

0 条评论

得票时间

avatar

春告鳥

公众号 芸潘

1 声望

0 粉丝

宣传栏

前言

对我而言,武术的非凡之处在于它的简单。简单的方法也是正确的方法,同时武术也没有什么特别之处。越接近武术的真谛,招式表现上浪费越少

简介

python 绝技 第一章是python入门语法,两个需要编写的程序分别是用字典攻击法破解UNIX口令暴力破解ZIP文件,两者都是使用暴力法直接进行破解,另外第一个程序在当前的网络环境中已经不太适用了,我们将其升级为破解SHA-512 hash的版本

背景故事

虽然在书中已经有背景故事的翻译了,但是这里我还是采用乌云之前翻译的版本

SHA-512 hash 破解

环境 : python3

在破解之前我们先了解一下shadow格式

root:$1$v2wT9rQF$XSpGgoB93STC4EFSlgpjg1:14181:0:99999:7:::

可以发现shadow中每一行对应这一个用户的用户名和密码等信息,格式为0:1:2:3:4:5:6:7:8

冒号是分割符,分别代表着,每个字段分别代表着:

0:用户名

1:密码hash值

2:密码修改距离1970年1月1日的时间

3:密码将被允许修改之前的天数(0 表示“可在任何时间修改”)

4:系统将强制用户修改为新密码之前的天数(1 表示“永远都不能修改”)

5:密码过期之前,用户将被警告过期的天数(-1 表示“没有警告”)

6:密码过期之后,系统自动禁用帐户的天数(-1 表示“永远不会禁用”)

7:该帐户被禁用的天数(-1 表示“该帐户被启用”)

8:保留供将来使用

hash值一览格式如:$id$salt$密文

id代表的是使用不同的加密算法,不同的系统使用的算法也不尽相同。salt是加密的时候需要用到盐。最后就是密文。

数字和所使用的加密算法对应关系:

格式算法
$1md5
$2ablowfish
$2yblowfish
$5sha-256
$6sha-512

注意:如果密码字符串为*,表示系统用户不能被登入,为!表示用户名被禁用,如果密码字符串为空,表示没有密码。

这里我们使用python3中的hashlib库计算sha-512

hash=hashlib.sha512(salt.encode('utf-8'))

hash.update(word.encode('utf-8'))

print(hash.hexdigest())

这样实现了sha-512加密,但是,这里的结果并不像是我们Linux操作系统中的密码,譬如我们上面举例的密码中:

XSpGgoB93STC4EFSlgpjg1

其中就包含了不在十六进制中的字符

事实上以$6为例并不是单纯的sha512(pass+salt)或者sha512(salt+passwd),而是经历了一系列复杂的运算而获得的。

我们先实现sha-512的解密

import hashlib

'''

testPass(cryptPass)函数

功能:

传入 cryptPass 待解密密码

print 破解结果

算法:穷举法

'''

def testPass(cryptPass):

salt,shadowPass=cryptPass.split('$')[2],cryptPass.split('$')[3]

dictFile=open('dictionary.txt','r')

for word in dictFile.readlines():

word=word.strip()

# print(word)

hash=hashlib.sha512(salt.encode('utf-8'))

hash.update(word.encode('utf-8'))

# print(hash.hexdigest())

if shadowPass==hash.hexdigest():

print("[+] Found Password {}".format(word))

return

print("[-] Password Not Found ")

return

def main():

passFile=open('passwords.txt')

for line in passFile.readlines():

if ":" in line:

user=line.split(':')[0]

cryptPass=line.split(':')[1].strip(' ')

print("[*] Now cracking Password For :{}".format(user))

testPass(cryptPass)

if __name__ == '__main__':

main()

这里的密码文件是我们构造的

root:$6$123$263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62:15503:0:99999:7:::

实际上是密文123同时盐值123

【Python】Python绝技第一章 入门 python3实现密码破解

运行破解

【Python】Python绝技第一章 入门 python3实现密码破解

破解成功

shadow密码破解

上面举例的密码是我们在cmd5网站上自行构造的,但*nix操作系统上密码并不是简单的sha512(pass+salt)或者sha512(salt+passwd),但在简书上找到了一位师傅之前使用hashlib来还原该加密算法python生成shadow中密码(SHA512)

import hashlib,math

def rstr_sha512(text: bytes) -> bytes:

sha512 = hashlib.sha512()

sha512.update(text)

return sha512.digest()

def _extend(source: bytes, size_ref: int) -> bytes :

extended = b"";

for i in range(math.floor(size_ref/64)):

extended += source;

extended += source[:size_ref % 64]

return extended;

def _sha512crypt_intermediate(password: bytes,salt: bytes) -> bytes:

#digest_a = rstr_sha512(password + salt)

digest_b = rstr_sha512(password + salt + password)

digest_b_extended = _extend(digest_b,len(password))

intermediate_input = password + salt + digest_b_extended

passwd_len = len(password)

while passwd_len!=0:

if passwd_len&1 == 1:

intermediate_input += digest_b

else:

intermediate_input += password

passwd_len >>= 1

return rstr_sha512(intermediate_input)

def _sha512crypt(password :bytes,salt :bytes,rounds :int) -> bytes:

digest_a = _sha512crypt_intermediate(password, salt)

p = _extend(rstr_sha512(password*len(password)),len(password))

s = _extend(rstr_sha512(salt*(16+digest_a[0])),len(salt))

digest = digest_a

for i in range(rounds):

c_input = b""

if i&1 :

c_input += p

else:

c_input += digest

if i % 3:

c_input += s

if i % 7:

c_input += p

if i & 1:

c_input += digest

else:

c_input += p

digest = rstr_sha512(c_input)

return digest

def sha512crypt(password :bytes,salt :bytes, rounds=5000) -> str:

salt = salt[:16] # max 16 bytes for salt

input = _sha512crypt(password, salt, rounds)

tab = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

order = [ 42, 21, 0, 1, 43, 22, 23, 2, 44, 45, 24, 3,

4, 46, 25, 26, 5, 47, 48, 27, 6, 7, 49, 28,

29, 8, 50, 51, 30, 9, 10, 52, 31, 32, 11, 53,

54, 33, 12, 13, 55, 34, 35, 14, 56, 57, 36, 15,

16, 58, 37, 38, 17, 59, 60, 39, 18, 19, 61, 40,

41, 20, 62, 63]

output = ""

for i in range(0,len(input),3):

# special case for the end of the input

if i+1 >= len(order): # i == 63

char_1 = input[order[i+0]] & 0b00111111

char_2 = (input[order[i+0]] & 0b11000000) >> 6

output += tab[char_1] + tab[char_2]

else:

char_1 = input[order[i+0]] & 0b00111111

char_2 = (((input[order[i+0]] & 0b11000000) >> 6) |

(input[order[i+1]] & 0b00001111) << 2)

char_3 = (

((input[order[i+1]] & 0b11110000) >> 4) |

(input[order[i+2]] & 0b00000011) << 4)

char_4 = (input[order[i+2]] & 0b11111100) >> 2

output += tab[char_1] + tab[char_2] + tab[char_3] + tab[char_4]

if rounds!=5000:

return "$6$rounds={}${}${}".format(rounds,salt.decode("utf-8"),output)

else:

return "$6${}${}".format(salt.decode("utf-8"),output)

if __name__ == "__main__":

# 与crypt.crypt("123456","$6$123456") 运算结果一致

print(sha512crypt(b"123456",b"123456",5000))

ubuntu 16.04虚拟机里面添加一个账号为test123,密码为123的用户

【Python】Python绝技第一章 入门 python3实现密码破解

接着查看shadow文件中其对应的密码

【Python】Python绝技第一章 入门 python3实现密码破解

test123:$6$DhlRUwqV$Jln02cwolkp3adJjELMn9q2MxKRalcdzyyJnMg3EayVMgNQ0v9plYEnFns58sBkfUROfhT4Fsdksoxjfr5nVA/:18664:0:99999:7:::

将简书的师傅代码修改为字典破解的版本

import hashlib,math

def rstr_sha512(text: bytes) -> bytes:

sha512 = hashlib.sha512()

sha512.update(text)

return sha512.digest()

def _extend(source: bytes, size_ref: int) -> bytes :

extended = b""

for i in range(math.floor(size_ref/64)):

extended += source

extended += source[:size_ref % 64]

return extended

def _sha512crypt_intermediate(password: bytes,salt: bytes) -> bytes:

#digest_a = rstr_sha512(password + salt)

digest_b = rstr_sha512(password + salt + password)

digest_b_extended = _extend(digest_b,len(password))

intermediate_input = password + salt + digest_b_extended

passwd_len = len(password)

while passwd_len!=0:

if passwd_len&1 == 1:

intermediate_input += digest_b

else:

intermediate_input += password

passwd_len >>= 1

return rstr_sha512(intermediate_input)

def _sha512crypt(password :bytes,salt :bytes,rounds :int) -> bytes:

digest_a = _sha512crypt_intermediate(password, salt)

p = _extend(rstr_sha512(password*len(password)),len(password))

s = _extend(rstr_sha512(salt*(16+digest_a[0])),len(salt))

digest = digest_a

for i in range(rounds):

c_input = b""

if i&1 :

c_input += p

else:

c_input += digest

if i % 3:

c_input += s

if i % 7:

c_input += p

if i & 1:

c_input += digest

else:

c_input += p

digest = rstr_sha512(c_input)

return digest

def sha512crypt(password :bytes,salt :bytes, rounds=5000) -> str:

salt = salt[:16] # max 16 bytes for salt

input = _sha512crypt(password, salt, rounds)

tab = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

order = [ 42, 21, 0, 1, 43, 22, 23, 2, 44, 45, 24, 3,

4, 46, 25, 26, 5, 47, 48, 27, 6, 7, 49, 28,

29, 8, 50, 51, 30, 9, 10, 52, 31, 32, 11, 53,

54, 33, 12, 13, 55, 34, 35, 14, 56, 57, 36, 15,

16, 58, 37, 38, 17, 59, 60, 39, 18, 19, 61, 40,

41, 20, 62, 63]

output = ""

for i in range(0,len(input),3):

# special case for the end of the input

if i+1 >= len(order): # i == 63

char_1 = input[order[i+0]] & 0b00111111

char_2 = (input[order[i+0]] & 0b11000000) >> 6

output += tab[char_1] + tab[char_2]

else:

char_1 = input[order[i+0]] & 0b00111111

char_2 = (((input[order[i+0]] & 0b11000000) >> 6) |

(input[order[i+1]] & 0b00001111) << 2)

char_3 = (

((input[order[i+1]] & 0b11110000) >> 4) |

(input[order[i+2]] & 0b00000011) << 4)

char_4 = (input[order[i+2]] & 0b11111100) >> 2

output += tab[char_1] + tab[char_2] + tab[char_3] + tab[char_4]

if rounds!=5000:

return "$6$rounds={}${}${}".format(rounds,salt.decode("utf-8"),output)

else:

return "$6${}${}".format(salt.decode("utf-8"),output)

def testPass(cryptPass):

salt,shadowPass=cryptPass.split('$')[2],cryptPass.split('$')[3]

dictFile=open('dictionary.txt','r')

for word in dictFile.readlines():

word=word.strip()

# print(word)

tempPassWord=sha512crypt(bytes(word, encoding = "utf8"), bytes(salt, encoding = "utf8"), 5000)

# print("temppassword is {}".format(tempPassWord))

# print("shadowpassword is {}".format(shadowPass))

if cryptPass==tempPassWord:

print("[+] Found Password {}".format(word))

return

print("[-] Password Not Found ")

return

def main():

passFile=open('passwords.txt')

for line in passFile.readlines():

if ":" in line:

user=line.split(':')[0]

cryptPass=line.split(':')[1].strip(' ')

print("[*] Now cracking Password For :{}".format(user))

testPass(cryptPass)

if __name__ == "__main__":

# 与crypt.crypt("123456","$6$123456") 运算结果一致

# print(sha512crypt(b"123",b"DhlRUwqV",5000))

main()

运行结果如图:

【Python】Python绝技第一章 入门 python3实现密码破解

破解成功,该脚本可用于Linux弱口令批量爆破

zip口令破解

zip口令破解比较简单,破解的成功与否还是在于密码文件的构造,同时可能会出现在CTF题目中,阴间题目比如说设置压缩包密码为不可见字符,需要自己编写脚本来进行破解

另外如果python3代码完全按照书上这么写会有一个报错

def extractFile(zFile,password):

try:

# print(password)

zFile.extractall(pwd=password)

print("[+] Found password {}".format(password))

except Exception as e:

pass

需要将password转为二进制传入

zFile.extractall(pwd=password.encode(encoding='utf-8', errors = 'strict'))

完整代码如下

import zipfile

import optparse

from threading import Thread

def extractFile(zFile,password):

try:

# print(password)

zFile.extractall(pwd=password.encode(encoding='utf-8', errors = 'strict'))

print("[+] Found password {}".format(password))

except Exception as e:

pass

def main():

parser=optparse.OptionParser("参数说明 -f <压缩包文件名> -d <密码txt文件名>")

parser.add_option('-f',dest='zname',type='string',help='压缩包文件名')

parser.add_option('-d',dest='dname',type='string',help='密码文件名')

(options,args)=parser.parse_args()

if (options.zname==None) or (options.dname==None):

print(parser.usage)

exit(0)

zname,dname=options.zname,options.dname

zFile=zipfile.ZipFile(zname)

passFile=open(dname)

for line in passFile.readlines():

password=line.strip()

t=Thread(target=extractFile,args=(zFile,password))

t.start()

return

if __name__ == '__main__':

main()

创建一个密码为admin的压缩包 key.zip

使用程序破解之

【Python】Python绝技第一章 入门 python3实现密码破解

破解成功

完整代码和字典文件放在github上了,欢迎师傅们Star:https://github.com/Cl0udG0d/pythonStunt

参考链接

  • http://www.vuln.cn/8178
  • https://gv7.me/articles/2017/batch-crack-shadows/
  • https://blog.csdn.net/deargua/article/details/6666121
  • https://www.jianshu.com/p/9da78abd6a96

欢迎关注公众号 芸潘

【Python】Python绝技第一章 入门 python3实现密码破解~~~~

以上是 【Python】Python绝技第一章 入门 python3实现密码破解 的全部内容, 来源链接: utcz.com/a/113711.html

回到顶部