Try Attack/python[basic]

python으로 zip파일 크랙하기

D4tai1 2019. 1. 28.

※ 이 글은 파이썬3을 기준으로 작성되었으니 참고하시기 바랍니다.

이전에는 단계별로 6자리 숫자에 대해서만 찾아보았다.
참고 : https://ccurity.tistory.com/228

그렇다면 이제는 zip파일이 어떠한 비밀번호로 잠겨있어도 비밀번호를 알아내보자!!

 

1. zip파일 크랙

(1) 실행파일 소스(zip_crack7.py)

from zip_crack import * 
import sys   

def usage():     
    print('Usage: {} [OPTION] <zipfile.zip>'.format(sys.argv[0]))
    sys.exit(1)  
    
def main():     
    if len(sys.argv) != 2:         
    usage()      
    
    try:         
        zFile = Crack(sys.argv[1])         
        zFile.crack()      
        
    except KeyboardInterrupt:         
        print('\b\b[Ctrl + C]를 입력하여 종료합니다.')     
    
    except FileNotFoundError :         
        usage()  

if __name__ == '__main__':    
    main()  

 

(2) 모듈파일 소스(zip_crack.py)

import zipfile from colorama import init, Fore, Back from threading import Thread  init(autoreset = True)  class Crack():     def __init__(self, zipName):         self.zipName = zipName         self.zFile = zipfile.ZipFile(zipName)         self.data = ''         self.key = ''      def make_dic(self):         for i in range(2):             for c in range(ord('a'), ord('z') + 1):                 self.data += chr(c)             if not i :                 self.data = self.data.upper()          for n in range(10):             self.data += str(n)      def make_key(self):         def repeat(key, maxLength, now):             for a in self.data:                 key += a                 if len(key) < maxLength:                     repeat(key, maxLength, now - 1)                     key = key[0 : maxLength - now]                 else:                     print(key)                     guess = extract(key)                     if guess:                         print(Fore.GREEN + "[+] Found password = " + key)                         exit(0)                     key = key[0 : maxLength - 1]          def extract(passwd):             try:                 self.zFile.extractall(pwd = passwd.encode('utf-8'))                 return passwd             except Exception as e:                 if passwd == '9999':                     print(Fore.YELLOW + Back.RED + '[-] Password not found...')                     exit(0)          for x in range(1, 5):             repeat('', x, x)      def crack(self):         self.make_dic()         self.make_key()  

 

 

2. 쓰레드를 이용한 방법

(1) 실행파일 소스(zip_crack8.py)

from zip_crackT import * 
import sys   

def usage():     
    print('Usage: {} [OPTION] <zipfile.zip>'.format(sys.argv[0]))     
    sys.exit(1)  
    
def main():     
    if len(sys.argv) != 2:         
        usage()      
        
    try:         
        zFile = Crack(sys.argv[1])         
        zFile.crack()     
    
    except KeyboardInterrupt:         
        print('\b\b[Ctrl + C]를 입력하여 종료합니다.')    
    
    except FileNotFoundError :         
        usage()  
        
if __name__ == '__main__':     
    main()  

 

(2) 모듈파일 소스(zip_crackT.py)

import zipfile from colorama import init, Fore, Back from threading import Thread  init(autoreset = True)  class Crack():     def __init__(self, zipName):         self.zipName = zipName         self.zFile = zipfile.ZipFile(zipName)         self.data = ''         self.key = ''          def make_dic(self):         for i in range(2):             for c in range(ord('a'), ord('z') + 1):                  self.data += chr(c)             if not i :                  self.data = self.data.upper()              for n in range(10):             self.data += str(n)      def make_key(self):          def repeat(key, maxLength, now):             for a in self.data:                 key += a                 if len(key) < maxLength:                     repeat(key, maxLength, now - 1)                     key = key[0 : maxLength - now]                 else:                     print(key)                     guess = extract(key)                     if guess:                         print(Fore.GREEN + "[+] Found password = " + key)                         exit(0)                     key = key[0 : maxLength - 1]              def extract(passwd):             try:                 #self.zFile.extractall(pwd = passwd.encode('utf-8')                 m = Thread(target=extractall, args=(self.zFile, passwd))                 m.start()                 return passwd              except Exception as e:                 if passwd == '9999':                     print(Fore.YELLOW + Back.RED + '[-] Password not found...')                     exit(0)          for x in range(1, 5):              repeat('', x, x)          def crack(self):         self.make_dic()         self.make_key()          #t = Thread(target=self.make_dic)         #u = Thread(target=self.make_key)         #t.start()         #u.start()  

 

 

3. 시연

(1) zip파일 크랙하기

 

 

 

(2) 쓰레드 사용

 

 

(3) 상황에 따른 결과

 

 [1] 현재는 영어 대소문자, 숫자만 넣었지만 특수문자가 비밀번호에 있다면 self.data에 특수문자를 넣으면 찾을 수 있다.

 [2] 현재는 1자리~4자리 비밀번호로 진행했지만 반복문을 range(1, ?)와 같이 두 번째 인자에 원하는 숫자를 입력하면 길이 제한없이 찾을 수 있다.

 [3] 단.. 양자컴퓨터가 개발되지 않는 이상 몇 천년 몇 만년이 걸릴지 모른다는 거...

 [4] 현재는 속도를 확인하기위해 프린트문으로 계속찍었다.(매번 확인하고 찍는 함수까지 호출하니 더욱 느리겠지만,,)

 [5] 찾을경우, 못 찾을경우, 파일이름을 넣지 않을경우, 없는 파일이름을 넣은경우 등의 상황에 맞게 출력이 된다.

 

4. 결론(테스트는 동일한 가상머신의 환경에서 진행)

(1) 쓰레드를 이용하면 key를 입력할 때마다 새로운 쓰레드로 실행시키므로 한 번에 여러 개의 key를 넣어볼 수 있다는 장점이 있다.

(2) 1과 2는 같은 결과를 가지고 오지만 2의 경우 쓰레드를 이용하였기 때문에 속도를 비교해본 결과 1의 경우보다 7배가량 빠르다.

(3) 그러나... 쓰레드를 이용할 경우 예외처리가 되지 않아 크랙에 실패하게 된다.

(4) 쓰레드를 많이 사용해보지 않아서 그런 것이지만.. 추후에 쓰레드를 더 공부하고 이 문제는 수정해보려고 한다.

 

 

댓글