비밀번호 form 위에 해시값이 있는 것으로 판단된다.
아마 해시값을 이용하여 비밀번호를 알아내는 문제인 듯하다.

 

<?php
  sleep(1); // anti brute force
  if((isset($_SESSION['chall4'])) && ($_POST['key'] == $_SESSION['chall4'])) solve(4);
  $hash = rand(10000000,99999999)."salt_for_you";
  $_SESSION['chall4'] = $hash;
  for($i=0;$i<500;$i++) $hash = sha1($hash);
?>

코드를 살펴보니, 해시를 생성하는 코드가 있었다.

그러나 문제는 10000000 ~ 99999999이라는 엄청난 범위에서 랜덤으로 나온 값과 ‘sal_for_you’라는 문자열을 합한 값을 해시화했다는 것이다.

거기서 끝나지 않고 해시화한 값을 500번 반복하여 해시화하였다.

이러면, 코드를 짜서 해시값과 같은 값이 나올 때까지 돌릴 수 밖에 없다.

나는 여러가지 방법을 생각을 하였다.

  • 방법 1 - 일반적인 파이썬으로 값을 구하는 방법
    이 방법은 10000000 ~ 30000000까지 돌리고, 안나오면 페이지를 리로딩하여 해시값을 초기화하는 방법으로 접근해야한다.
    이렇게 하지 않으면 범위가 크기 때문에 엄청난 시간이 소요될 것으로 판단된다.
  • 방법 2 - 멀티 프로세싱을 이용하는 방법
    10개의 프로세스로 돌리는 방법이다. 이 방법으로 구하는데, 더 빠르게 구하고 싶으면, 각 프로세스에 멀티 스레딩를 적용하여 사용하면 된다.

방법 1

import hashlib

current = ''
for i in range(10000000, 99999999+1):
    current = str(i) + 'salt_for_you'

    for _ in range(0, 500):
        h = hashlib.sha1()
        h.update(current.encode('utf-8'))
        current = h.hexdigest()

    if '89b3dc6eacc20ce197d29c728a330fdee4b4a808' == current:
        print(f'Success!!! - {i}salt_for_you')
        break

10000000 ~ 99999999까지 돌리는 코드이다.

10000000 ~ 40000000까지만 돌리는 것은 Range 함수의 범위를 수정하면 된다.

다른 방법으로 시도 후 안되면 수정해서 사용하겠다.


방법 2

from multiprocessing import Pool, cpu_count, Process
import hashlib, time

def pwCreate(num:int):
    return str(num) + 'salt_for_you'

def hashing(pw:str):
    current = pw

    for _ in range(500):
        h = hashlib.sha1()
        h.update(current.encode('utf-8'))
        current = h.hexdigest()

    if current == '89b3dc6eacc20ce197d29c728a330fdee4b4a808':
        print('Password is', pw)

if __name__ == '__main__':
    start = time.time()

    cores = cpu_count()
    with Pool(cores) as p:
        pwList = p.map(pwCreate, list(range(10000000, 99999999+1)))
    print('PW List 완료 -', int(time.time() - start), '초')

    with Pool(cores) as p:
        p.map(hashing, pwList)
    print('End -', int(time.time() - start), '초')

해당 코드를 돌리면, 컴퓨터의 자원이 많이 사용 되기 때문에 사용에 유의하기 바란다.
때문에 나는 맥북에서 돌리는 대신 데스크탑의 환경에서 코드를 돌렸다.

 

거의 1시간을 소비하니, 결과가 나왔다.

 

Flag를 획득할 수 있었다.


문제를 풀이하는 분들은 코드를 수정하여 해시값을 파일에 저장하여, 검색하는 방법으로 접근하면 좋을 것 같다.

from multiprocessing import Pool, cpu_count, Process
import hashlib, time

def pwCreate(num:int):
    return str(num) + 'salt_for_you'

def hashing(pw:str):
    current = pw

    for _ in range(500):
        h = hashlib.sha1()
        h.update(current.encode('utf-8'))
        current = h.hexdigest()

    print(pw, '-', current)

if __name__ == '__main__':
    start = time.time()

    cores = cpu_count()
    with Pool(cores) as p:
        pwList = p.map(pwCreate, list(range(10000000, 99999999+1)))
    print('PW List 완료 -', int(time.time() - start), '초')

    with Pool(cores) as p:
        p.map(hashing, pwList)
    print('End -', int(time.time() - start), '초')

python3 4-1.py > result.txt로 하면, 출력값이 텍스트 파일로 저장이 된다.
다만, 거의 10기가에 가까운 텍스트 파일이라 에디터나 메모장은 열지 못할 것이다.
나는 GVIM 에디터로 열어서 확인하였다. 참고하면 될 듯 하다.

'워게임 > webhacking.kr' 카테고리의 다른 글

[Webhacking.kr] Old - 7 Write Up  (0) 2021.05.26
[Webhacking.kr] Old - 5 Write Up  (0) 2021.05.25
Old - 56 Write Up  (0) 2021.05.23
Old - 51 Write Up  (0) 2021.05.22
Old - 43 Write Up  (0) 2021.05.21
복사했습니다!