Always-Try(정보보안 및 일상)

webhacking.kr - Challenge(old) - 4번 레인보우 테이블 본문

Pen Test

webhacking.kr - Challenge(old) - 4번 레인보우 테이블

Always-Try 2021. 2. 10. 18:32

#1. 4번

1-1. 문제

1-2. 풀이

입력칸에 아무거나 입력하고 제출을 눌러봐도 별다른 반응이 없다.

일단 소스보기를 보자

php 부분에 뭔가 있다. 좀 자세히 보자.

1째 줄: sleep(1) 이라고 해서 1초 동안 지연을 주는 코드가 있다.

2째 줄: $_SESSION['chall4'] 라는 값이 존재하고 그 값과 $_POST['key']이 같으면 solve(4) 함수가 실행된다. (key를 맞추는 문제가 아닌가 싶다.)

3째 줄: 10000000 ~ 99999999까지 랜덤한 숫자를 생성하고 뒤에 salt_for_you 라는 문자를 붙인다. (ex. 10000000salt_for_you) 

4째 줄: $hash 값을 $_SESSION['chall4']에 넣는다.

5째 줄: $hash 값을 sha1으로 500번 돌린다.

 

즉, 문제에 나온 sha1 값은 $hash를 sha1으로 500번 돌린 값인데, 저 값을 보고 $hash를 알아내라는 것이다.

참고로 sha1은 160bits로 구성되어 있으며, 이는 20 bytes와 같다. 그리고 문제에 있는 값도 20글자다.

 

sha1은 암호화 알고리즘으로 복호화 할 수 없다. 사실 정확히는 요즘도 못하는지 까지는 모르겠지만 할 수 있다고 하더라도 내 컴퓨터에서는 못할 것이 분명하다.

 

그럼 어떻게 푸냐?

문제에 key의 범위를 알려줬다. 그 범위에 있는 값들을 모두 500번씩 sha1 알고리즘으로 돌리고 그 결과 값과 문제에 있는 값을 비교하면 될 것이다.(-> 레인보우 테이블) 물론 이것도 굉장히 큰 작업일 것이다. 흐음 그래도 해보자.

 

파이썬으로 코드를 짜본다. 단순 작업의 반복이므로 for문 만 몇번 쓰면 된다. 간단하니까 주석은 생략.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
import hashlib
 
= open("webhacking_04.csv""w")
 
for i in range(10000000100000000):
    origin_pw = str(i) + 'salt_for_you' 
    for j in range(0500):
        encrypt_pw = hashlib.sha1(origin_pw.encode('utf-8')).hexdigest()
        f.write(origin_pw +  '  ' + encrypt_pw)
        f.write('\n')
 
f.close()
 
cs

 

간단한 코드지만 워낙 반복 횟수가 많고 경우의 수가 많다보니 시간이 오래 걸린다. 거기다 용량도 GB 단위를 넘어간다. PC에 충분한 용량 확보 후 테스트하길 바란다.

 

 

 

추가....

코드를 실행시켜놓고 까먹고 한참뒤에 봤더니, 10GB짜리 csv 파일이 생성되어 있었다. 그런데!! 용량이 너무 커서 csv 파일이 열리다가 뻗는 현상이 발생한다. 후아..

그래서 그냥 레인보우 테이블을 파일로 만들지 않고, 본 문제의 답만 출력할 수 있도록 코드를 변경했다.

(참고. 4번 문제 웹페이지에 다시 들어갔더니 sha1 인코딩 된 값이 변경되었다.)

 

1
2
3
4
5
6
7
8
9
import hashlib
 
for i in range(10000000100000000):
    origin_pw = str(i) + 'salt_for_you' 
    for j in range(0500):
        encrypt_pw = hashlib.sha1(origin_pw.encode('utf-8')).hexdigest()
   if encrypt_pw == '14d807b3c3d3e597e03aebe470e30bd004daba33':
       print(origin_pw)
 
cs

다시 기다림의 시간..

과연...

....

2시간이 지났다.

....

....

....

여전히 코드가 실행중이다. 얼마나 걸릴지 모르겠다. 웹 서핑을 해보니 이틀이 걸렸다는 사람도 있다.

하, 생각보다 더 오래 걸린다. 이거 문제가 심각하다. 쓰레드를 사용해서 시간을 줄여보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from multiprocessing import Process, Queue
import hashlib
import time
 
start_time = time.time()
 
def rainbow_table():
    for i in range(10000000, 100000000):
        origin_pw = str(i) + 'salt_for_you'
        for j in range(0, 500):
            encrypt_pw = hashlib.sha1(origin_pw.encode('utf-8')).hexdigest()
        if encrypt_pw == '8528e8c63e137c766b5209353b5593156fd5776a':
            print(origin_pw)
            print("time :", time.time() - start)
            break
 
if __name__ == "__main__":
    proc1 = Process(target=rainbow_table)
    proc2 = Process(target=rainbow_table)
    proc3 = Process(target=rainbow_table)
    proc4 = Process(target=rainbow_table)
    proc5 = Process(target=rainbow_table)
    proc6 = Process(target=rainbow_table)
    
    proc1.start()
    proc2.start()
    proc3.start()
    proc4.start()
    proc5.start()
    proc6.start()
    proc1.join()
    proc2.join()
    proc3.join()
    proc4.join()
    proc5.join()
    proc6.join()
 
cs

자고 일어났는데 여전히 돌고 있다. 또한, 위와 같이 코드를 짤 경우, sha1 암호화 된 값이 변경될 경우 다시 코드를 실행시켜야하는 불편함이 있다. 이렇게 해서는 문제 못푼다.. 결국 1번째 코드와 3번째 코드를 합쳐서 아래와 같은 코드를 다시 실행했다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from multiprocessing import Process
import hashlib
import time
 
start_time = time.time()
= open("webhacking_04.csv""w")
 
def rainbow_table():
    for i in range(10000000100000000):
        origin_pw = str(i) + 'salt_for_you'
        for j in range(0500):
            encrypt_pw = hashlib.sha1(origin_pw.encode('utf-8')).hexdigest()
        f.write(origin_pw +  '  ' + encrypt_pw + '\n')
    print("time :", time.time() - start)
 
 
if __name__ == "__main__":
    proc1 = Process(target=rainbow_table)
    proc2 = Process(target=rainbow_table)
    proc3 = Process(target=rainbow_table)
    proc4 = Process(target=rainbow_table)
    proc5 = Process(target=rainbow_table)
    proc6 = Process(target=rainbow_table)
 
    
    proc1.start()
    proc2.start()
    proc3.start()
    proc4.start()
    proc5.start()
    proc6.start()
    proc1.join()
    proc2.join()
    proc3.join()
    proc4.join()
    proc5.join()
    proc6.join()
cs

 

결국 끝까지 기다리지 못하고 꺼버렸다.

저 코드가 정상 동작하는지 확인은 못한채로 4번은 넘어가려한다. bye..

 

 

Comments