asaotomo / ZipCracker

ZipCracker是一款由Hx0战队开发的高性能多并发破解工具,专为破解密码保护的Zip文件而设计。它采用CRC32碰撞和字典攻击方式猜测Zip文件的明文或密码,并能成功提取其中的内容。这款工具具备识别"伪加密"Zip文件的能力,并能自动进行修复。因此,它非常适合在CTF比赛中使用。(ZipCracker by Hx0 team is a tool for cracking passwords on Zip files, great for CTF competitions.)
295 stars 41 forks source link

RuntimeError: can't start new thread #1

Open xingstarx opened 8 months ago

xingstarx commented 8 months ago
NotImplementedError: That compression method is not supported

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/xingxing/pythonProjects/ZipCracker/ZipCracker.py", line 161, in <module>
    t.start()
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 957, in start
    _start_new_thread(self._bootstrap, ())
RuntimeError: can't start new thread

感谢大佬的开源项目,有个问题想要咨询下呢,我运行这个项目来破解一个zip文件,报错了。 崩溃日志如上,感觉是线程数开启太多了,爆炸了,大佬能给点指点么。

MangoYou commented 5 months ago

我也遇到相同的问题

guoyunhe commented 4 months ago

遇到相同问题

CiaranYoung commented 4 months ago

yeah, i have the same problem

yayaQAQ commented 4 months ago

you can try this code ZipCracker.py ,but this speed on screen is wrong.

import os
import shutil
import sys
from threading import Thread
from collections import OrderedDict
import time
import zipfile
import binascii
import string
import itertools as its
import concurrent.futures

def is_zip_encrypted(file_path):
    """
    检查zip文件是否存在伪加密
    """
    with zipfile.ZipFile(file_path) as zf:
        for info in zf.infolist():
            if info.flag_bits & 0x1:
                return True
    return False

def fix_zip_encrypted(file_path):
    """
    修复伪加密的zip文件
    """
    temp_path = file_path + ".tmp"
    with zipfile.ZipFile(file_path) as zf, zipfile.ZipFile(temp_path, "w") as temp_zf:
        for info in zf.infolist():
            if info.flag_bits & 0x1:
                info.flag_bits ^= 0x1  # 清除加密标记
            temp_zf.writestr(info, zf.read(info.filename))
    fix_zip_name = "fix_" + file_path
    try:
        shutil.move(temp_path, fix_zip_name)
    except:
        os.remove(fix_zip_name)
        shutil.move(temp_path, fix_zip_name)
    return fix_zip_name

def crack_password(password, stop):
    global success, cost_time
    start = time.time()
    try:
        zf = zipfile.ZipFile(zip_file)
        zf.setpassword(password.encode())
        zf.extractall()
        print(f'\n[*]恭喜您!密码破解成功,该压缩包的密码为:{password}')
        success = True
        filenames = zf.namelist()
        print(f"[*]系统已为您自动提取出{len(filenames)}个文件:{filenames}")
        stop[0] = True  # 破解成功,设置 stop 为 True
        os._exit(0)
        return True
    except:
        passwords_cracked = len(tried_passwords)
        avg_cracked = int(passwords_cracked / 1)
        remaining_time = time.strftime('%H:%M:%S',
                                       time.gmtime((total_passwords - passwords_cracked) / 1))
        print("\r[-]当前破解进度:{:.2f}%,剩余时间:{},当前时速:{}个/s,正在尝试密码:{:<20}".format(
            passwords_cracked / total_passwords * 100, remaining_time, avg_cracked, password),
            end="", flush=True)
    finally:
        cost_time += time.time() - start
    return False

def get_crc(zip_file, fz):
    key = 0
    for filename in fz.namelist():
        if filename.endswith('/'):  # skip directories
            continue
        getSize = fz.getinfo(filename).file_size
        if getSize <= 6:
            sw = input(
                f'[!]系统监测到压缩包 {zip_file} 中的 {filename} 文件大小为{getSize}字节,是否尝试通过CRC32碰撞的方式直接爆破该文件内容?(y/n)')
            if sw == 'y' or sw == "Y":
                getCrc = fz.getinfo(filename).CRC
                print(f'[+]{filename} 文件的CRC值为:{getCrc}')
                crack_crc(filename, getCrc, getSize)
                key += 1
    if key >= len([name for name in fz.namelist() if not name.endswith('/')]):  # only count files, not directories
        print(f'[*]系统检测到 {zip_file} 中的所有文件均已通过CRC32碰撞破解完成,将不再使用字典进行暴力破解!')
        exit()
    else:
        pass

def crack_crc(filename, crc, size):
    dic = its.product(string.printable, repeat=size)
    print(f"[+]系统开始进行CRC32碰撞破解······")
    for s in dic:
        s = ''.join(s).encode()
        if crc == (binascii.crc32(s)):
            print(f'[*]恭喜您,破解成功!\n[*]{filename} 文件的内容为:' + str(s.decode()))
            break

if __name__ == '__main__':
    print("""                          
 ______          ____                _   [*]Hx0战队      
|__  (_)_ __    / ___|_ __ __ _  ___| | _____ _ __ 
  / /| | '_ \  | |   | '__/ _` |/ __| |/ / _ \ '__|
 / /_| | |_) | | |___| | | (_| | (__|   <  __/ |   
/____|_| .__/___\____|_|  \__,_|\___|_|\_\___|_|   
       |_| |_____|                                 
#Coded By Asaotomo               Update:2024.03.12
        """)
    if len(sys.argv) == 1:
        print(
            "[*]用法1(内置字典):Python3 Hx0_Zip_Cracker.py YourZipFile.zip \n[*]用法2(自定义字典):Python3 Hx0_Zip_Cracker.py  YourZipFile.zip  YourDict.txt")
        os._exit(0)
    zip_file = sys.argv[1]
    if is_zip_encrypted(zip_file):
        print(f'[!]系统检测到 {zip_file} 是一个加密的ZIP文件')
        zf = zipfile.ZipFile(zip_file)
        try:
            fix_zip_name = fix_zip_encrypted(zip_file)
            zf = zipfile.ZipFile(fix_zip_name)
            zf.testzip()
            zf.extractall()
            filenames = zf.namelist()
            print(
                f"[*]压缩包 {zip_file} 为伪加密,系统已为您生成修复后的压缩包({fix_zip_name}),并自动提取出{len(filenames)}个文件:{filenames}")
            os._exit(0)
        except Exception as e:
            zf = zipfile.ZipFile(zip_file)
            print(f'[+]压缩包 {zip_file} 不是伪加密,准备尝试暴力破解')
            # crc32碰撞
            get_crc(zip_file, zf)
            # 破解加密的zip文件
            password_list = []
            if len(sys.argv) > 2:  # 检查是否指定了自定义字典文件
                dict_file = sys.argv[2]
                dict_type = "用户自定义字典"
            else:
                dict_file = 'password_list.txt'
                dict_type = "系统内置字典"
            try:
                with open(dict_file, 'r') as f:
                    password_list += [line.strip() for line in f.readlines()]
                print(f'[+]加载{dict_type}[{dict_file}]成功!')
            except Exception as e:
                print(f'[!]加载{dict_type}失败!,原因:{e}')
                exit(0)
            for length in range(1, 7):
                password_list += [f'{i:0{length}d}' for i in range(10 ** length)]
            print(f'[+]加载0-6位纯数字字典成功!')
            password_list = list(OrderedDict.fromkeys(password_list))
            tried_passwords = []
            total_passwords = len(password_list)
            print(f"[+]当前爆破字典总数:{total_passwords}个")
            print(f"[+]系统开始进行暴力破解······")
            success = False
            cost_time = 0.00001
            stop = [False]  # 用列表存储 stop 变量,使其可以在多个线程间共享
            threads = []
            # 设置最大线程数
            max_threads = 200  # 可以根据您的系统能力调整这个数值

            # 使用线程池执行密码破解任务
            with concurrent.futures.ThreadPoolExecutor(max_workers=max_threads) as executor:
                # 将任务提交到线程池
                future_to_password = {executor.submit(crack_password, password, stop): password for password in
                                      password_list}

                # 等待线程池中的任务完成,可以处理任务的结果(如果需要)
                for future in concurrent.futures.as_completed(future_to_password):
                    password = future_to_password[future]
                    tried_passwords.append(password)
                    try:
                        success = future.result()
                        if success:
                            print(f'\n[*]恭喜您!密码破解成功,该压缩包的密码为:{password}')
                            break  # 如果破解成功,则退出循环
                    except Exception as exc:
                        print(f'{password} 产生了异常: {exc}')
            if not success:
                print('\n[-]非常抱歉,字典中的所有密码均已尝试,请尝试其他字典或使用更高级的破解方法!')
popo4u commented 3 months ago

我也遇到相同的问题

可以看下这个 pr:https://github.com/asaotomo/ZipCracker/pull/3

popo4u commented 3 months ago

遇到相同问题

可以看下这个 pr:https://github.com/asaotomo/ZipCracker/pull/3

asaotomo commented 1 month ago

我们已经发布最新版,优化线程池逻辑,实现根据运行环境动态调整线程数,极大增加破解速度,大家可以下载体验一下,看看是否还有上述的问题,感谢大家的反馈和建议。