python으로 Linux에서 zip파일 압축 및 해제
※ 이 글은 파이썬3을 기준으로 작성되었으니 참고하시기 바랍니다.
1. Linux에서 zip파일 압축 및 해제
(1) 압축 및 해제
[1] unzip 패키지 설치
▶ [apt-get install unzip -y] 명령어로 unzip 패키지를 설치한다.
[2] 압축
▶ [zip "생성할 압축파일명" "압축할 파일1" "압축할파일2"...] 명령어로 zip압축할 수 있다.
▶ -P 옵션을 사용해서 패스워드를 지정할 수도 있다.
[3] 해제
▶ [unzip "압축파일명"]
[4] 일반적인 압축 및 해제 시연
2. python으로 압축파일 해제(zipfile 모듈 사용)
(1) zip_crack1.py
[1] 소스
import zipfile zFile = zipfile.ZipFile("secret.zip") #zipfile모듈의 ZipFile()메서드를 호출 #ZipFile()메서드는 zip파일의 이름을 넣어준다. zFile.extractall(pwd=b"456789") #zFile을 추출한다.
▶ 7라인에 pwd의 값에 b를 붙인 이유는 str로 들어가지 않고 byte로 들어가기 때문이다.
[2] 시연
▶ 만약 비밀번호가 틀리다면 여러 줄의 에러와 함께 돌아가지 않는 것을 확인할 수 있다.
▶ 오류가 발생할 가능성이 있기 때문에 (2)에서 예외처리를 해주려고 한다.
(2) zip_crack2.py
[1] 소스
import zipfile zFile = zipfile.ZipFile("secret.zip") try: zFile.extractall(pwd=b'999999') except Exception as e: e = str(e).split() it = iter(e) for result in range(4): print(next(it)+" ", end="") print()
▶ (1)의 소스와 동일하지만 try-except문을 추가하였다.
▶ except 부분은 그냥 print(e)로 처리해주어도 무방하다.
▶ 그러나 뒤에 보기 싫은 단어들이 우르르 달려있기 때문에 혹은 세부오류내용은 사용자에게 공개하는 것을 원치 않을 수도 있다.
▶ 그래서 e는 runtimeerror의 type이고 str로 변경 후 space를 기준으로 split(분할)하여 리스트로 변경하여 e에 재저장한다.
▶ 리스트로 for문을 돌려도 되지만 여기서는 iterator을 사용해보려고 한다.
▶ 이것을 그냥 찍으면 리스트형태로 찍히기 때문에 iterable객체를 iterator를 반환받아 사용한다.
▶ 객체.__next__() 메서드를 사용하거나 그냥 next(iterator객체)와 같이 사용하여도 무방하다.
▶ 쉽게 말하면 리스트에서 다음[next()메소드]을 4번 불러서 print(e[0], e[1], e[2], e[3]) 를 적은 것과 동일하다.
▶ print(e[:4]) 이렇게 적는다면 리스트형태로 찍히게 된다.
[2] 시연
▶ Exception을 그냥 출력할 경우 우르르 에러메세지가 출력된다.
▶ (2) - [1] 과 같이 정제 후 출력한 경우는 나름 정제되었다.
▶ 압축파일의 패스워드가 일치한다면 (1) - [2]와 같이 출력된다.
(3) zip_crack3.py
[1] 소스
import zipfile zFile = zipfile.ZipFile("secret.zip") for x in range (0, 1000000): if x % 100000 == 0: print("[*] Looking for password...", x) if x < 10: passwd = "00000" + str(x) elif x < 100: passwd = "0000" + str(x) elif x < 1000: passwd = "000" + str(x) elif x < 10000: passwd = "00" + str(x) elif x < 100000: passwd = "0" + str(x) else: passwd = str(x) try: zFile.extractall(pwd=bytes(passwd,'utf-8')) print("[+] Found password = "+passwd) exit(0) except Exception as e: pass
▶ 압축파일의 비밀번호를 모를 때 찾기 위해 비밀번호가 6자리 숫자라고 가정하고 진행하였다.
▶ 만약 숫자가 아니라면 0~9, a~z, 특수문자를 리스트에 넣고 하나씩 꺼내와서...
▶ 비밀번호가 한자리일 때부터... 어... 무차별공격은 언젠가는 성공하니...
▶ pwd는 byte type으로 변환 후 전달한다.
[2] 시연
▶ 찾았음을 알 수 있다.
▶ 이 내용을 보기좋게 (4)에서 함수로 모듈화하려고 한다.
(4) zip_crack4.py
[1] 소스
import zipfile def extract(zFile, passwd): try: zFile.extractall(pwd = bytes(passwd, 'utf-8')) return passwd except Exception as e: if passwd == '000000': print("[-] Password not found...") return def check(x): if x % 100000 == 0: print("[*] Looking for password..."+str(x)) if x < 10: passwd = "00000" + str(x) if x < 100: passwd = "0000" + str(x) elif x < 1000: passwd = "000" + str(x) elif x < 10000: passwd = "00" + str(x) elif x < 100000: passwd = "0" + str(x) else: passwd = str(x) return passwd def main(): zFile = zipfile.ZipFile("secret.zip") for x in range(999999, -1, -1): passwd = check(x) guess = extract(zFile, passwd) if guess: print("[+] Found password = " + passwd) exit(0) if __name__ == '__main__': #__name__은 현재 모듈이 메인이면? main()
▶ (3)의 내용을 함수화 하였다.
[2] 시연
▶ 함수로 작성해도 정상적으로 동작한다.
▶ (5)에서는 압축파일 이름을 인자로 입력받으려고 한다.
(5) zip_crack5.py
[1] 소스
import zipfile import sys #system모듈 def extract(zFile, passwd): try: zFile.extractall(pwd = bytes(passwd, 'utf-8')) return passwd except Exception as e: if passwd == '999999': print("[-] Password not found...") return def check(x): if x % 100000 == 0: print("[*] Looking for password..."+str(x//100000)+"0%") if x < 10: passwd = "00000" + str(x) if x < 100: passwd = "0000" + str(x) elif x < 1000: passwd = "000" + str(x) elif x < 10000: passwd = "00" + str(x) elif x < 100000: passwd = "0" + str(x) else: passwd = str(x) return passwd def main(): try: zFile = zipfile.ZipFile(sys.argv[1]) except Exception as e: print('\"'+sys.argv[1]+'\"'+ 'is not found!!') exit(0) for x in range(0, 1000000): passwd = check(x) guess = extract(zFile, passwd) if guess: print("[+] Found password = " + passwd) exit(0) if __name__ == '__main__': #__name__은 현재 모듈이 메인이면? main()
▶ sys를 import한다.
▶ 이유는 압축파일 이름을 파라미터로 입력받기 위해서이다.
▶ 소스는 (4)와 거의 동일하며 기존파일 이름부분이 sys.argv[1]로 작성되었다.
▶ def check(x): 부분에서 출력 시 %로 출력되도록 변경하였다.
▶ 또한 압축파일명을 파라미터로 입력받기 때문에 잘못 입력받으면 에러가 발생할 수 있다.
▶ 그래서 def main(): 부분에서 try-except문을 추가하였다.
[2] 시연
▶ 올바른 압축파일명을 입력하면 정상적으로 동작한다.
▶ 있지않은 압축파일명을 입력하면 에러를 출력한다.
(6) zip_crack6.py
[1] 소스
import zipfile import sys #system모듈 from colorama import init, Fore, Back init(autoreset = True) #한 줄이 끝나면 색깔 초기화!! def extract(zFile, passwd): try: zFile.extractall(pwd = bytes(passwd, 'utf-8')) return passwd except Exception as e: if passwd == '999999': print("[-] Password not found...") return def check(x): if x % 100000 == 0: print("[*] Looking for password..."+str(x//100000)+"0%") if x < 10: passwd = "00000" + str(x) if x < 100: passwd = "0000" + str(x) elif x < 1000: passwd = "000" + str(x) elif x < 10000: passwd = "00" + str(x) elif x < 100000: passwd = "0" + str(x) else: passwd = str(x) return passwd def main(): try: zFile = zipfile.ZipFile(sys.argv[1]) except Exception as e: print(Fore.YELLOW + Back.RED+'\"'+sys.argv[1]+'\"'+ 'is not found!!') exit(0) for x in range(0, 1000000): passwd = check(x) guess = extract(zFile, passwd) if guess: print(Fore.GREEN + "[+] Found password = " + passwd) exit(0) if __name__ == '__main__': #__name__은 현재 모듈이 메인이면? main()
▶ 3라인 [from colorama import init, Fore, Back] 이 추가되었다.
▶ 조금 이쁘게 색을 넣기 위해서 colorama 모듈을 추가하였다.
▶ 만약 오류가 발생한다면 [python3 pip install colorame] 명령어로 모듈을 추가한다.
▶ print문 작성 시 Fore."색상", Back."색상"과 같은 양식으로 포그라운드(글자색), 백그라운드(배경색)의 색상을 지정한다.
[2] 시연
▶ 에러 시에는 붉은 색, 패스워드를 찾은 경우는 녹색을 지정하였다.
▶ 필요에 따라 원하는대로 작성하면 좋을 것 같다.
'Try Attack > python[basic]' 카테고리의 다른 글
python으로 zip파일 크랙하기 (0) | 2019.01.28 |
---|---|
python으로 매크로 제작하기 (0) | 2019.01.26 |
python 코드 분석 방법 (4) | 2019.01.25 |
python으로 채팅구현하기 (0) | 2019.01.19 |
ping 서비스에 대한 공격코드 작성 (0) | 2019.01.19 |
댓글