文章目录

  • 前言
  • Python语法
    • 自定义迭代器
    • Python多线程
  • Python脚本
    • 单线程数字爆破
    • 单线程字符爆破
    • 多线程字典爆破
  • 总结

前言

本文继续记录学习下 Python 的有趣应用:借助 Python 脚本暴力破解 ZIP 加密文件的密码。虽然有相关的工具 ARCHPR 可实现 RAR、ZIP 等压缩加密文件的可视化暴力破解,但是主要是为了学习 Python 编程应用。

Python语法

既然本意是学习 Python 编程,那自然是要对本实战应用场景的编码过程遇到的相关语法知识进行学习。

在此先推荐一个 Python 语法的官方站点:Python官方中文文档,支持下载到本地。

自定义迭代器

迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象,迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,迭代器有两个基本的方法:iter()next()

1、迭代器对象可以使用常规 for 语句进行遍历:

#!/usr/bin/python3
list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
for x in it:print (x, end=" ")执行以上程序,输出结果如下:
1 2 3 4

2、也可以使用 next() 函数:

#!/usr/bin/python3
import sys         # 引入 sys 模块list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
while True:try:print (next(it))except StopIteration:sys.exit()执行以上程序,输出结果如下:
1
2
3
4

3、Python 支持编写 class 来自定义迭代器,如何自定义一个迭代器:

  • 在自定义的类中添加了__iter__魔法方法可取得迭代器;
  • 在自定义的类中通过__next__魔法方法指出所有的数据。

来看看一个简单的自定义可迭代的类示例:

class TopTen(object):def __init__(self):self.num = 1def __iter__(self):return selfdef __next__(self):if self.num <= 10:val = self.numself.num += 1return valelse:raise StopIterationif __name__ == "__main__":values = TopTen()for v in values:print(v, end=' ')

代码运行效果:

Python多线程

线程是 CPU 分配资源的基本单位,但一个程序开始运行后这个程序就变成了一个进程,而一个进程相当于一个或者多个线程。当没有多线程编程时,一个进程也是一个主线程,但有多线程编程时,一个进程包含多个线程,包括主线程。使用线程可以实现程序的并发,Python 多线程快速入门可参见:python3 多线程编程。

Python3 线程中常用的两个模块为:

  • (1)_thread;
  • (2)threading (推荐使用)

其中 thread 模块已被废弃,用户可以使用 threading 模块代替。所以在 Python3 中不能再使用 “thread” 模块,为了兼容性,Python3 将 thread 重命名为 “_thread”。

1、函数创建多线程

Python3 中提供了一个内置模块threading.Thread,可以很方便的创建多线程,threading.Thread()一般接收2个参数:

  • 1)线程函数名:要放置线程让其后台执行的函数,有用户自己定义,主要不要加();
  • 2)线程函数的参数:线程函数名所需的参数,以 tuple 元组的形式传入,如果不需要参数,可以不指定。

下面来看看一个简单的多线程示例:

import time
import threading# 自定义线程函数
def my_threadfunc(name='python3'):for i in range(2):print("hello", name)time.sleep(1)if __name__=="__main__":# 创建线程01,不指定参数thread_01 = threading.Thread(target=my_threadfunc)# 启动线程01thread_01.start()# 创建线程02,指定参数,注意逗号不要少,否则不是一个tuplethread_02 = threading.Thread(target=my_threadfunc, args=('Tr0e',))# 启动线程02thread_02.start()

代码运行效果:
2、类创建多线程

首先,自定义一个类,对这个自定义的类有两个要求:

  • 1)必须继承 threading.Thread 这个父类;
  • 2)必须重写 run() 这个方法:run() 方法相当于第一种方法中的线程函数,可以写自己需要的业务逻辑代码,在start()后将会调用。

来看看示例代码:

import time
from threading import Threadclass MyThread(Thread):def __init__(self, name='Python3'):super().__init__()self.name = namedef run(self):for i in range(2):print("Hello", self.name)time.sleep(1)

3、 join() 方法

多线程中 join() 作用是调用 join() 的线程阻塞直到某一线程结束才继续执行。来看看示例代码:

import threading
import timeclass mythread(threading.Thread):def run(self):self.i = 1print("子线程运行秒数:",'%d' % (self.i))self.i = self.i + 1time.sleep(1)  # 睡眠一秒print("子线程运行秒数:",'%d' % (self.i))time.sleep(1)print("子线程运行结束!")if __name__ == '__main__':ta = mythread()  # 实例化线程ta.start()  # 开启ta线程ta.join()  # 主线程等待 ta线程结束才继续执行print("主线程结束!")

代码运行效果:
4、线程的同步——锁

当一个进程拥有多个线程之后,如果他们各做各的任务互没有关系还行,但既然属于同一个进程,他们之间总是具有一定关系的。比如多个线程都要对某个数据进行修改,则可能会出现不可预料的结果。为保证操作正确,就需要引入锁来进行线程间的同步。

Python3 中的 threading 模块提供了 RLock 锁(可重入锁):

  • 对于某一时间只能让一个线程操作的语句放到 RLock 的 acquire 方法 和 release 方法之间;
  • 即 acquire() 函数相当于给 RLock 锁 上锁,而 release() 函数相当于解锁。

来看看一个简单的演示案例:

import threadingclass mythread(threading.Thread):def run(self):global x        # 声明一个全局变量lock.acquire()  # 上锁,acquire()和release()之间的语句一次只能有一个线程进入,其余线程在acquire()处等待x += 10print('%s:%d' % (self.name, x))lock.release()  # 解锁x = 0
lock = threading.RLock()  # 创建 可重入锁def main():l = []for i in range(5):l.append(mythread())  # 创建5个线程,并把他们放到一个列表中for i in l:i.start()  # 开启列表中的所有线程if __name__ == '__main__':main()

代码运行效果:
5、多线程函数小结:

t = Thread(target=func)
# 启动子线程
t.start()
# 阻塞子线程,待子线程结束后,再往下执行
t.join()
# 判断线程是否在执行状态,在执行返回True,否则返回False
t.is_alive()
t.isAlive()
# 设置线程是否随主线程退出而退出,默认为False
t.daemon = True
t.daemon = False
# 设置线程名
t.name = "My-Thread"

Python脚本

下面将从单线程、多线程两种角度实现 ZIP 加密文件的密码爆破。

单线程数字爆破

先来生成一个用数字密码(“101”)加密的 ZIP 压缩文件 password.zip,压缩文件为图片 pasword.png(注意勾选 “ZIP 传统加密” 的选项,后面的代码不支持 WinRAR 新式的默认加密方式),如下图所示:

爆破密码的脚本也相对简单,直接上代码:

import zipfile
import os
import time
import sys"""
获取zip文件
"""
def get_zipfile():os.chdir(r'D:\Code\Python\MyTest\Basic')files = os.listdir()for file in files:if file.endswith('.zip'):return file"""
爆破zip文件
"""
def extract():file = get_zipfile()zfile = zipfile.ZipFile(file)  # 读取压缩文件start_time = time.time()for num in range(1, 99999):      # 设置爆破的数字密码区间try:zfile.extractall(path='.', pwd=str(num).encode('utf-8'))print('解压密码是:', str(num))end_time = time.time()print('单线程破解压缩包花了%s秒' % (end_time - start_time))sys.exit(0)  # 让程序在得到结果后,就停止运行,正常退出except Exception as e:print(e)#passif __name__ == "__main__":extract()

以上代码没什么需要特别解释的,简单补充两点:

  1. 需要注意的是在爆破过程需要使用异常处理机制避免密码错误时程序直接终止;
  2. 对于 zipfile 库的用法有疑问请参见官方文档:ZipFile数据压缩与存档。

下面直接来看看 Pycharm 中运行脚本的效果:

单线程字符爆破

先来看看脚本:

import zipfile
import random
import time
import sysclass MyIterator():# 用于暴力破解的字符集合letters = 'abcdefghijklmnopqrstuvwxyz012345678'min_digits = 0max_digits = 0def __init__(self, min_digits, max_digits):# 下面的if-else是为了解决extract函数中,for循环中传递的密码长度可能前者的值大于后者,这一bugif min_digits < max_digits:self.min_digits = min_digitsself.max_digits = max_digitselse:self.min_digits = max_digitsself.max_digits = min_digits# 迭代器访问定义,直接返回self实列对象def __iter__(self):return self# 通过不断地轮循,生成密码def __next__(self):rst = str()for item in range(0, random.randrange(self.min_digits, self.max_digits + 1)):# 从letters中随机取选取一个值,并把选取几次的结果拼接成一个字符,即一个密码rst += random.choice(MyIterator.letters)return rstdef extract():start_time = time.time()zfile = zipfile.ZipFile("password.zip")# 随机迭代出5~6位数的密码for password in MyIterator(5, 6):try:zfile.extractall(path=".", pwd=str(password).encode('utf-8'))print("the password is {}".format(password))now_time = time.time()print("spend time is {}".format(now_time - start_time))sys.exit(0)except Exception as e:print(e)passif __name__ == '__main__':extract()

将 password.png 重新压缩并将解压密码设置为 “ab12” 数字与字母组合的字符串,上述利用自定义迭代器生成的字符组合范围太广了,爆破起来可能跑到天荒地老……故演示此代码时我依据已知的密码对代码做了如下更改:

  1. 设置缩小字符范围:letters = 'abcd0123456789'
  2. 设置缩小遍历的字符串长度:for password in MyIterator(3, 4)

来看看脚本运行效果,还足足跑了 78 秒之久:

多线程字典爆破

直接上脚本:

import zipfile
import threading
import sys
import os'''
多线程爆破完成
'''
def extractfile(zip_file, password):try:zip_file.extractall(path='.', pwd=str(password).encode("utf-8"))print('[+] 解压密码是:', password)sys.exit(0)except Exception as e:print("当前爆破的密码:%s 不正确!" % (password))passdef main():os.chdir(r'D:\Code\Python\MyTest\Basic')password_file = 'pwd.txt'files = os.listdir()for file in files:  # 遍历当前路径下的所有文件if file.endswith('.zip'):  # 爆破zip文件zip_file = zipfile.ZipFile(file)pass_file = open(password_file)for line in pass_file.readlines():password = line.strip('\n')t = threading.Thread(target=extractfile, args=(zip_file, password))t.start()if __name__ == '__main__':main()

代码运行效果:

总结

个人感觉最后的多线程脚本实际上意义不大,仅供简单学习多线程使用……因为此程序中对每个密码的尝试都单开了一个线程、而尝试密码是否正常的逻辑函数 extractfile() 又十分简单,没有必要单开一个线程来浪费资源,除非说处理的逻辑函数 extractfile() 执行了十分耗时的操作(比如需要下载文件、或者说每次执行 extractfile() 函数都对一个单独的大型字典进行爆破等)。

Python攻防-暴力破解ZIP加密文件的密码相关推荐

  1. 前女友闺蜜给我发了一个压缩包,居然还带密码?暴力破解ZIP加密文件的密码!

    前言 今晚下班后微信收到一跳消息!是前女友的闺蜜发过来的,然后让我自己去猜密码,本来我是不打算理她的!但是她后面说里面有你想不到的福利!这句话对于一枚(lsp)不对一枚宅男程序员没有抵抗力,毕竟我对她 ...

  2. python暴力破解zip加密文件

    目录 前言: 一.破解zip加密文件的思路: 1.准备一个加密的zip文件. 2.zipfile模块可以解压zip文件. 3.itertools.permutations实现全字符的全排列. 二.实操 ...

  3. python 暴力破解 excel加密文件

    python 暴力破解 excel加密文件 'wordlist.txt' 为待测试的密码列表 fdd ddd eeee 5e5e5 58d85d5e d2d4d5d 4d4d4d3 dfdf,d; l ...

  4. Python实战-暴力破解zip文件解压密码

    简介 使用的核心模块是python标准库中的zipfile模块.这个模块可以实现zip文件的各种功能,具体可以查看官方参考文档.这里的暴力破解的意思是对密码可能序列中的值一个一个进行密码尝试,这对人来 ...

  5. 破解Zip加密文件常用的几种方法

    前言 在互联网的浪潮中,大家也许碰到过这种情况: 从网络上下载了一个zip文件,最后却发现它是用密码保护的,或者自己用密码加密了一个很重要zip文件,但是一段时间后忘记了密码,无法打开.这个时候,我们 ...

  6. Python:暴力破解zip!

    照顾没有接触过Python编程的同学,行文可能会有些啰嗦. 废话少说,我们进入正题. 2.1准备基本材料 在/home/ziptest/目录下,我创建了两个文件,一个test.zip,是一个设置了密码 ...

  7. 暴力破解zip加密压缩包

    最近恰好有个压缩包要解密,所以稍微研究了一下该怎么去破解加密的压缩包(zip,rar在道理上是一样的).由于现有的方法中没想到高级的破解方式,所以只有暴力破解压缩包了. 暴力破解压缩包的原理很简单,就 ...

  8. ZIP加密文件破解:john简介

    John是一款Kali linux自带的密码破解工具,支持密码本破解.John基于密码本破解root用户开机口令如下图所示,当然重点还是你有靠谱的密码本,否则也是白费力气. unshadow /etc ...

  9. Python暴力破解教程: Zip加密文件, pdf加密书籍在线爆破!

    点击上方"程序员大咖",选择"置顶公众号" 关键时刻,第一时间送达! 先不说楚枫的这般年纪,能够踏入元武一重说明了什么,最主要的是,楚枫在刚刚踏入核心地带时,明 ...

最新文章

  1. 【c语言】蓝桥杯算法提高 3-2求存款
  2. 比特币现金在稳定币领域的地位怎样
  3. 如何玩转PDF?5款简单好用的PDF工具推荐
  4. VC调用matlab中定义的.m文件中的函数的实例
  5. 利用生物视觉机制提高神经网络的对抗鲁棒性 | NeurIPS 2020
  6. 竟然被awk生成的随机数给整蒙了,也谈随机数生成种子
  7. Geatpy自定义初始种群
  8. 字体系列之文字样式(CSS、HTML)
  9. 使用html仿支付宝首页,仿支付宝首页头部伸缩效果
  10. HDU——2154——跳舞毯
  11. 华为办公协作与远程视频会议软件Link Now停止运营 请及时备份数据
  12. 低端电流检测电路实测
  13. Java写的第一个小游戏
  14. 20天完成智能推送系统。
  15. 计算机二级Word第四套
  16. 燃气热水器的主要部件及维修常识
  17. 劈尖干涉公式_劈尖干涉条纹数的计算
  18. 大盘平稳运行 新股申购性价比较低
  19. html实现3D立体动态像册源代码
  20. Proxmox VE 超融合集群不停服务更换硬盘操作实录

热门文章

  1. 网络通信协议基础(ISIS)——概述
  2. 用Rasa NLU构建自己的中文NLU系统
  3. Arduino RP2040 读取ADC采样数据
  4. Arduino使用点灯科技+小爱同学+WIFI,实现一个设备区分控制多个舵机/电灯
  5. qt plugin metadata file does not exist解决方案
  6. ESP8266通信详细教程
  7. php有什么版本,php哪个版本稳定?
  8. RouterOS搭建一台SSTP Server用于远程办公
  9. linux如何解除密码锁屏图案大全,手机锁屏图案(锁屏密码)忘记了怎么办?四种方法帮你轻松搞定...
  10. 基于MATLAB 2021b的机器学习、深度学习