파이썬 브루트포스 공격(BruteForce Attack) 사전파일 만들기

무차별대입공격(BruteForceAttack)

 

이번 포스팅에서는 파이썬 언어를 활용하여 브루트 포스 공격(BruteForce Attack)을 진행해보려고 합니다

 

먼저 설명에 앞서서 브루트 포스 공격(BruteForce Attack)에 대해서 알고 갈 필요가 있는데 위키피디아의 설명을 빌려 암호학에서 무차별 대입 공격인 BruteForceAttack은 사이트의 사용자 패스워드를 알아내기 위해서 혹은 특정한 암호를 풀기 위해 가능한 모든 값을 대입하여 값을 찾는 것을 의미합니다

 

예를 들어서 웹페이지 로그인 시에 비밀번호가 '123'일 경우 패스워드가 3자리니깐 0에서부터 999까지 패스워드 목록이 담겨있는 사전 파일을 생성하여 브루트 포스 공격으로 하나하나 패스워드를 대입하여 값을 찾아낼 수 있습니다

단순하면서도 엄청난 공격 같지만 패스워드의 길이가 길어지거나 특수문자 등 값이 많을수록 그만큼 많은 값을 소요하므로 실전에서는 사용자가 사용할만한 패스워드 단어 등을 이용한다거나 탐색범위를 좁히는 게 유리합니다

 

 

출처:위키피디아

 

실제 패스워드 암호별 대입할 수 있는 경우의 수를 나타내는 표입니다

16자리의 경우 영문+숫자 조합만으로도 13자리의 숫자까지 엄청나게 경우의 수가 많아지는 걸 확인할 수 있습니다

 

 

for문으로 반복하여 패스워드 리스트 생성

1
2
3
4
5
6
numlist = '0123456789'
 
for i in numlist:
    for j in numlist:
            print(i,j)
 
cs

 

이제 본격적으로 파이썬에서 브루트 포스 공격(BruteForceAttack)에서 사용할 패스워드 사전 파일을 생성하려고 합니다

 

#1

numlist라는 변수를 생성하여 패스워드의 조합이 0에서부터 9까지 숫자로만 이루어졌다고 가정하여 간단하게 생성하겠습니다

 

#3~#5

for문을 사용하여 i in numlist 즉 0부터 9까지 10번 반복하는데 i가 0인 상태에서 for j in numlist 똑같이 j도 0에서부터 9까지 반복하게 됩니다

그래서 i가 0 일 때 j는 0에서부터 9까지 반복하여 i가 1일 때 또 j가 0에서부터 9까지 반복하고 출력 결과는 00부터 99까지 패스워드 리스트가 생성되게 됩니다

 

 

 

그렇다면 패스워드의 자릿수가 많아지면 어떨까요??

예를 들어서 4자리 숫자의 패스워드 리스트를 만들려고 해 봅시다

1
2
3
4
5
6
7
numlist = '0123456789'
 
for i in numlist:
    for j in numlist:
        for k in numlist:
            for h in numlist:
                print(i,j,k,h)
cs

위와 같이 반복문을 추가하여 4자리의 패스워드 생성코드를 작성할 수 있지만 코드가 길어지고 번거롭습니다

5자리 10자리의 패스워드를 생성하려면 for문을 추가적으로 계속 써가야 하는데 이러한 사전 파일을 간편하게 만들 수 있는 모듈이 존재합니다

 

 

itertools를 사용하여 패스워드 리스트 생성하기

 

itertools는 파이썬에 내장된 내장 모듈이므로 별도의 설치 없이 사용 가능합니다

 

itertools — 효율적인 루핑을 위한 이터레이터를 만드는 함수 — Python 3.8.13 문서

 

docs.python.org

위에는 itertools에 대한 문서 페이지입니다 해당 모듈에대해 자세한 내용을 확인하고 싶으신분은 위에 링크를 클릭해주세요

itertools에는 다양한 도구가 있는데 오늘 사용할 건 product입니다

product 함수는 product(p, q, … [repeat=1])와 같은 형태로 사용할 수 있는데 글로 설명하는 것보다 코드로 보는 게 훨씬 이해가 빠르다고 생각될 테니 코드로한 번 보시죠

 

 

 

1
2
import itertools
numlist = '0123456789'
cs

#1

itertools모듈을 가져와줍니다

#2

numlist 라는 변수로 경우의 수 이번 예제에서는 0에서부터 9까지의 숫자로만 이루어졌다고 가정하여 생성하였습니다

 

3
4
for password in itertools.product(numlist, repeat=1):
    print(password)
 
cs

for문을 사용하는 건 동일하지만 itertools.product(문자열 목록, repeat=횟수) 형식으로 사용됩니다

위에서 괄호 안에 첫 번째 인자 값 numlist는 앞서 선언한 0에서부터 9까지 숫자가 담긴 문자열 변수이며

repeat=뒤에 1 같은 경우 1자리의 패스워드를 뜻합니다

위와 같이 작성하고 출력해보겠습니다

 

('0',)
('1',)
('2',)
('3',)
('4',)
('5',)
('6',)
('7',)
('8',)
('9',)

그랬더니 위와 같이 튜플 형식으로 출력됩니다 근데 ()와 ' 때문에 보기가 안좋습니다 이 부분을 없애고 숫자만 깔끔하게 출력되게 변경해보겠습니다

 

 

 

튜플을 문자열로 정리하여 나타내기 위해서는 join함수를 사용하면 됩니다

출력 부분을 print(''.join(password)) 형태로 ' ' 는 큰따옴표가 아니라 작은따옴표로 변경한 후에 출력해보면

1

3

~

9

형태로 출력이 됩니다 

 

1
2
3
for password in itertools.product(numlist, repeat=1):
    print(''.join(password)+',',end="")
 
 
cs

출력 부분을 이렇게 각 숫자 뒤에 , 구분자를 넣고 end=""로 다음 줄로 넘어가지 않게 한 줄로 출력해줄 수도 있습니다

위와 같이 코드 작성 후 실행할 경우에는 0,1,2,3,4,5,6,7,8,9, 형태로 출력됩니다

 

 

 

조금 더 깔끔하게 출력하기

1
2
3
4
5
6
aa=''
for password in itertools.product(numlist, repeat=1):
    aa += ''.join(password)+','
 
print(aa[:-1],end="")
 
 
cs

이걸 출력 시 조금 더 깔끔하게 처리하기 위해서는 

aa변수를 for문 밖에 전역변수(global variable)로 선언해주고(for문 안에 선언할 경우 for문이 돌때마다 aa에는 ''빈내용이 채워지겠죠??)

*전역변수는 함수외부를 포함하여 모든함수에서 접근가능, 지역변수는 선언한 해당 함수 내에서만 접근가능*

aa에다가 튜플 형태의 패스워드를 문자열로 바꾸고 +','으로 뒤에 구분자 , 을 넣어 0,1,2,3,4,5,6,7,8,9, 가 최종적으로 aa에 누적되어 문자열로 들어갑니다

 

그리고 출력 시에 문자열 인덱싱을 통해 [:-1] 맨뒤에 ,를 하나만 제거한 후에 출력해주면 깔끔하게 출력됩니다

 

 

해당 패스워드 파일의 경우 나중에 공격 시에 다시 사용하기 위해서 txt 파일 형태로 저장하겠습니다

 

1
2
3
file = open('passwordlist.txt','w')
file.write(aa[:-1])
file.close()
cs

open함수에 첫 번째 인자 값은 저장될 파일 이름과 두 번째 인자 값에 w는 쓰기 모드로 해당 파일을 연다는 의미이며

write함수로 aa에 들어있는 내용을 작성하게 됩니다 aa [:-1] 문자열 인덱싱을 통하여 맨뒤에 , 는 안 나오도록 깔끔하게 작성해줍니다

 

모두 작성 후에 실행한 뒤에 현재 파이썬파일이 담겨있는 폴더 내에 passwordlist.txt 파일이 새로 생성됩니다 해당 파일을 열어주면 print문으로 출력했던 내용과 동일한 내용이 담겨있게 됩니다

 

 

GITHUB

 

GitHub - Blue-B/PythonBrutueForce-1

Contribute to Blue-B/PythonBrutueForce-1 development by creating an account on GitHub.

github.com

 

Top