脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - python暴力解压rar加密文件过程详解

python暴力解压rar加密文件过程详解

2021-08-01 01:16_qiufeng Python

这篇文章主要介绍了python解压rar加密文件过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

第一次使用csdn写文章,写得不好还请见谅。(运行环境:python3.6)

下了一个带密码的压缩包文件,作为一个刚学python的新手,想着能不能用python暴力破解它,于是在网上搜了很多资料,看着似乎并不是很麻烦,也想试着自己写一个可以暴力破解的程序,在写的过程中却遇到了各种各样的问题,希望大手们能带带我。遇到的问题如下:

  • zipfile和zipfile2似乎都不支持AES解密(https://bugs.python.org/issue9170)
  • 在用rarfile暴力破解时即使密码错误也不抛出异常,因此无法用try,except捕获密码

本来是想写一个可以同时暴力破解zip和rar的程序,在试了半天解密zip却一直提示密码错误之后放弃了zip,想着能不能写一个暴力破解rar的程序。

首先是生成字典:要用到itertools模块

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import itertools as its
import string
 
def createDict(path,repeats,words):
    dict = its.product(words,repeat=repeats)
    '''这里的words是要迭代的字符串,repeats是生成的密码长度,生成的dict是一个返回元组的迭代器'''
    f = open(path,'a')
    for cipher in dict:
        f.write(''.join(cipher) + '\n')
    f.close()
 
def main():
    numbers = string.digits #包含0-9的字符串
    path = '输入你的字典路径'
    length = 你要迭代的密码长度
    for i in range(1,length):
        createDict(path,i,numbers)
 
if __name__=="__main__":
    main()

到这里我们的字典已经生成完毕了,接下来开始暴力破解rar

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from threading import Thread
from unrar import rarfile
import os
 
'''首先我们要读取字典,字典可能太大因此我们采用迭代器'''
 
def get_pwd(dict_path):
    with open(dict_path,'r') as f:
        for pwd in f:
            yield pwd.strip()
 
def decode_rar(fp,pwd,extract_path):
    try:
        fp.extractall(extract_path,pwd=pwd)
    except:
        pass
    else:
        print('the pwd is>',pwd)
'''
事实上我在尝试时似乎从来没有到达过else,这样可能是得不到解压密码的。我的
一种得到密码的想法如下,但是运行效率可能会降低
 
 
def decode_rar(fp,pwd,check_file,extract_path):
    fp.extractall(extract_path,pwd=pwd)
    if os.path.exists(check_file):
        print('The pwd is:',pwd)
        exit(0)
其中check_file可以设置为fp.namelist()[0]
并且该方法不能使用多线程,因此速度会降低很多
'''
 
def main():
    extract_path = '你要解压的路径'
    dict_path = '你的字典路径'
    filename = '你的rar路径'
    fp = rarfile.RarFile(filename)
    pwds = get_pwd(dict)
    '''使用多线程可提高速度'''
    for pwd in pwds:
        t = Thread(target=rar_file,args=(fp,pwd,extract_path))
        t.start()

以上是写程序的思路和遇到的各种坑,代码是手敲的,可能有一些错误,希望能得到谅解和帮助。

下面是一个图形界面的rar解密源代码:(图形只是想练习,运行较慢,建议直接运行上面的函数)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import tkinter as tk
import os
from tkinter import messagebox
from unrar import rarfile
from threading import Thread
 
def getPwd(dict):
  with open(dict,'r') as f:
    for pwd in f:
      yield pwd.strip()
def slowerDecode(fp,pwd,check_file,extract_path):
  fp.extractall(extract_path,pwd=pwd)
  if os.path.exists(check_file):
    messagebox.showinfo(message="密码:"+pwd)
    messagebox.showinfo(message="程序结束")
    messagebox.showinfo(message="密码:"+pwd)
    exit(0)
    
def quickDecode(fp,pwd,extract_path):
  fp.extractall(extract_path,pwd=pwd)
 
 
def check(obs):
  flag = 1
  for ob in obs:
    if not ob.checkExist():
      flag = 0
      ob.showError() 
 
  if(not flag):
    return 0
  else:
    for ob in obs:
      if not ob.check():
        flag = 0
        ob.showError()
        
  if (not flag):
    return 0
  else:
    for ob in obs:
      ob.right()
    return 1
        
def main(obs):
  extract_path = obs[0].path_input.get()
  rar_path = obs[1].path_input.get()
  txt_path = obs[2].path_input.get()
  pwds = getPwd(txt_path)
  global var1
  global var2
  if(check(obs)):
    if(var1.get() == 0 and var2.get() == 0):
      messagebox.showerror(message="选择一个选项!!!")
    elif(var1.get() == 0 and var2.get() == 1):
      fp = rarfile.RarFile(rar_path)
      check_file = fp.namelist()[0]
      for pwd in pwds:
        slowerDecode(fp,pwd,check_file,extract_path)
    elif(var1.get() == 1 and var2.get() == 0):
      fp = rarfile.RarFile(rar_path)
      for pwd in pwds:
        t = Thread(target=quickDecode,args=(fp,pwd,extract_path))
        t.start()
      exit(0)
    else:
      messagebox.showerror(message="只选择一个!!!")
    
 
class FolderPath:
  
  def __init__(self,y=0,error_message="Not exists!",path_input="",text=''):
    self.y = y
    self.error_message = error_message
    self.path_input = path_input
    self.text = text
    
  def createLabel(self):
    label = tk.Label(window,bg="white",font=("楷体",13),width=20,text=self.text)
    cv.create_window(100,self.y,window=label)
  
  def createEntry(self):
    entry = tk.Entry(window,fg="blue",width="40",bg="#ffe1ff",textvariable=self.path_input)
    cv.create_window(330,self.y,window=entry)
  
  def show(self):
    self.createLabel()
    self.createEntry()
    
  def showError(self,color="red"):
    label = tk.Label(window,bg="white",fg=color,font=("楷体",13),width="10",text=self.error_message)
    cv.create_window(530,self.y,window=label)
  
  def checkExist(self):
    self.error_message = 'Not exists!'
    if not os.path.exists(self.path_input.get()):
      return 0
    return 1
  
  def check(self):
    if not os.path.isdir(self.path_input.get()):
      self.error_message = 'Not a dir!'
      return 0
    else:
      return 1
  
  def right(self):
    self.error_message = "right path!"
    self.showError('#00FFFF')
    
  
class FilePath(FolderPath):
  def check(self):
    if (self.path_input.get().split('.')[-1] == self.suffix):
      return 1
    else:
      self.error_message = "Not "+self.suffix + '!'
      return 0
  
 
window = tk.Tk()
window.title('made by qiufeng')
window.geometry('600x300')
cv = tk.Canvas(window,width=600,height=300,bg='white')
cv.pack()
 
folderpath = FolderPath(y=140,path_input=tk.StringVar(),text="请输入解压路径")
folderpath.show()
 
 
rarpath = FilePath(y=60,path_input=tk.StringVar(),text="请输入rar路径")
rarpath.suffix = 'rar'
rarpath.show()
 
txtpath = FilePath(y=100,path_input=tk.StringVar(),text="请输入字典路径")
txtpath.suffix = 'txt'
txtpath.show()
obs = [folderpath,rarpath,txtpath]
 
#多选框
var1 = tk.IntVar()
var2 = tk.IntVar()
ck1 = tk.Checkbutton(window,text="直接破解(无法获得密码)",variable=var1)
cv.create_window(150,200,window=ck1)
ck2 = tk.Checkbutton(window,text="慢速(可获得密码)",variable=var2)
cv.create_window(132,230,window=ck2)
button = tk.Button(window,text="确认",command=lambda: main(obs))
cv.create_window(90,260,window=button)
 
window.mainloop()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/weixin_43873887/article/details/87862831

延伸 · 阅读

精彩推荐