Python爆破PDF
原创2024/9/3大约 2 分钟
爆破PDF
随手一写,记录一下:(花的时间基本上是去研究getDocumentInfo方法的库函数,调开代码库研究了一下才发现人家早就弃用了,后续发现弃用了之后找到了新的依赖,解决下班)
# 导入所需的模块
import threading
from PyPDF2 import PdfReader # 用于读取PDF文件
from queue import Queue # 线程安全的队列
from tqdm import tqdm # 用于显示进度条
# 尝试使用密码列表中的密码来解密PDF文件
def try_passwords(reader, passwords, result_queue, progress_bar) -> str:
# 遍历密码列表
for password in passwords:
try:
# 尝试使用当前密码解密PDF
reader.decrypt(password)
# 如果解密成功,将密码放入队列,关闭进度条,并返回密码
if reader.metadata:
result_queue.put(password)
progress_bar.close()
return password
# 更新进度条
progress_bar.update(1)
except Exception as e:
# 如果解密失败,更新进度条
progress_bar.update(1)
# 如果所有密码尝试完毕,关闭进度条,并返回空字符串
progress_bar.close()
return ""
# 从文件中读取密码列表
def read_passwords_from_file(file_path):
# 打开文件,并读取每一行,去除每行的前后空白字符,然后返回密码列表
with open(file_path, 'r') as file:
passwords = [line.strip() for line in file.readlines()]
return passwords
# 根据索引获取列表的一个子集
def get_sublist_by_index(list, i, num_parts):
# 检查索引是否在有效范围内
if i < 0 or i >= num_parts:
raise ValueError(f"索引i必须在0到{num_parts-1}之间")
# 计算子列表的大小和起始结束索引
total_size = len(list)
part_size = total_size // num_parts
extra = total_size % num_parts
start_index = part_size * i + min(i, extra)
end_index = start_index + part_size + (1 if i < extra else 0)
# 返回子列表
return list[start_index:end_index]
# 设置PDF文件路径和密码文件路径
pdf_path = 'q.pdf' # 你要破解的文档的路径
password_file_path = 'd.txt' # 这里是你的字典文件路径
passwords_list = read_passwords_from_file(password_file_path) # 读取密码列表
num_threads = 10 # 设置线程数量
result_queue = Queue() # 创建结果队列
threads = [] # 存储线程的列表
progress_bars = [] # 存储进度条的列表
# 打开PDF文件
with open(pdf_path, "rb") as file:
reader = PdfReader(file) # 创建PdfReader对象
# 对每个线程执行密码尝试函数
for i in range(num_threads):
pbar = tqdm(total=len(passwords_list)/num_threads) # 创建进度条
pbar.set_description(f"Thread {i+1}") # 设置进度条描述
progress_bars.append(pbar) # 将进度条添加到列表
# 创建线程,传递参数
thread = threading.Thread(target=try_passwords, args=(reader, get_sublist_by_index(passwords_list,i,num_threads),result_queue, pbar))
threads.append(thread) # 将线程添加到列表
thread.start() # 启动线程
# 等待所有线程完成
for thread in threads:
thread.join()
# 检查是否找到密码
if not result_queue.empty():
password_found = result_queue.get() # 从队列中获取密码
print(f"Password found: {password_found}") # 打印找到的密码
else:
print("No password found.") # 如果没有找到密码,打印提示信息