[webhacking.kr] old-4 Write-Up

두비니

·

2022. 8. 28. 16:27

 

webhacking.kr old-4

Write-Up

 

 

 

01. 문제 분석

 

뭔지모를 해시값을 주고, password를 제출하라고 하네요. 소스코드를 먼저 봅시다.

 

<?php
  include "../../config.php";
  if($_GET['view-source'] == 1) view_source();
?><html>
<head>
<title>Challenge 4</title>
<style type="text/css">
body { background:black; color:white; font-size:9pt; }
table { color:white; font-size:10pt; }
</style>
</head>
<body><br><br>
<center>
<?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);
?><br>
<form method=post>
<table border=0 align=center cellpadding=10>
<tr><td colspan=3 style=background:silver;color:green;><b><?=$hash?></b></td></tr>
<tr align=center><td>Password</td><td><input name=key type=text size=30></td><td><input type=submit></td></tr>
</table>
</form>
<a href=?view-source=1>[view-source]</a>
</center>
</body>
</html>

 

 

우선 목적은 우리가 입력하는 key값에다가 SESSION의 'chall4'값을 맞추는 것입니다.

다만 문제는 저희에게 주어지는 해시값은 기존의 $hash 값이 아닌, $hash값을 500번 sha1 암호화를 진행한 값을 줍니다.

그리고 $hash는 10000000~99999999사이의 랜덤값과 "salt_for_you"를 붙인 값이다. 예를 들면 "34597208salt_for_you"같은 값이 500번 sha1을 거쳐 우리에게 보여지는 것이다.

 

2. Solution

 

우선 $hash의 값이 많긴 하지만, 유한한 값 안에서 선택된다는 것을 보았다. 물론 worst case의 경우 89999999 * 500 = 44999999500.. 총 440억번 연산을 해주어야 한다.

뭔가 효율적으로 문제를 풀어야 겠다는 생각을 했다.

정확하게 세션 유지 기간이 얼마나 되는지는 모르겠지만, 그때그때 SHA1값을 생성하여 비교하는 것은 시간이 부족할 것이라고 예상하여 미리 rainbow table을 생성하기로 하였다. 

또한 작업속도를 늘리기 위해 멀티 프로세싱을 통해 레인보우 테이블을 생성하였다.

레인보우 테이블 생성 코드는 다음과 같다.

import hashlib
from multiprocessing import Process

def get_hash(start, end):
    with open("rainbow_"+str(start)[0]+".txt", "a") as f:
        for i in range(start, end):
            res = str(i)+"salt_for_you"
            for j in range(500):
                res = hashlib.sha1(res.encode('utf-8')).hexdigest()
            # print(res)
            
            f.write(str(i) +" : " + res+"\n")

if __name__ == "__main__":
    th1 = Process(target=get_hash, args=(10000000, 20000000))
    th2 = Process(target=get_hash, args=(20000000, 30000000))
    th3 = Process(target=get_hash, args=(30000000, 40000000))
    th4 = Process(target=get_hash, args=(40000000, 50000000))
    th5 = Process(target=get_hash, args=(50000000, 60000000))
    th6 = Process(target=get_hash, args=(60000000, 70000000))
    th7 = Process(target=get_hash, args=(70000000, 80000000))
    th8 = Process(target=get_hash, args=(80000000, 90000000))
    th9 = Process(target=get_hash, args=(90000000, 100000000))
        
    th1.start()
    th2.start()
    th3.start()
    th4.start()
    th5.start()
    th6.start()
    th7.start()
    th8.start()
    th9.start()
    
    th1.join()
    th2.join()
    th3.join()
    th4.join()
    th5.join()
    th6.join()
    th7.join()
    th8.join()
    th9.join()

 

이렇게 해도 만드는데 거의 5~6시간정도 걸린 것 같다.

그래도 다른 글들 찾아보니 하루 꼬박 걸리는 것보단 낫겠지ㅎ

 

그리고 해시를 직접 열어서 찾기 귀찮아 코드를 하나 더 짰다.

from multiprocessing import Process

hash = "YOUR_HASH"

def find_hash(i):
    filename = "rainbow_"+str(i)+".txt"
    with open(filename, "r") as f:
        print(f"[*] Finding in {filename}")
        lines = f.readlines()
        for line in lines:
            if hash in line:
                print(f"[!] Found Hash: {line}")
                break

if __name__ == "__main__":
    th1 = Process(target=find_hash, args=(1,))
    th2 = Process(target=find_hash, args=(2,))
    th3 = Process(target=find_hash, args=(3,))
    th4 = Process(target=find_hash, args=(4,))
    th5 = Process(target=find_hash, args=(5,))
    th6 = Process(target=find_hash, args=(6,))
    th7 = Process(target=find_hash, args=(7,))
    th8 = Process(target=find_hash, args=(8,))
    th9 = Process(target=find_hash, args=(9,))

    th1.start()
    th2.start()
    th3.start()
    th4.start()
    th5.start()
    th6.start()
    th7.start()
    th8.start()
    th9.start()
    
    th1.join()
    th2.join()
    th3.join()
    th4.join()
    th5.join()
    th6.join()
    th7.join()
    th8.join()
    th9.join()

 

multiprocess 최고ㅎ

이를 제출하면 답을 얻을 수 있다.

 

 

 

3. 결론

Rainbow Table Attack에 대한 문제였습니다.

문제풀이와는 논외일 수 있지만, 근본적으로 왜 여러번 SHA및 해시 함수를 사용하는 것이 도움이 되지 않는지에 대해 잘 적혀있어 공유합니다. 끝!

https://crypto.stackexchange.com/questions/98969/will-hashing-multiple-times-be-more-less-or-similarly-secure-as-hashing-once

 

Will Hashing Multiple Times Be More, Less, Or Similarly Secure As Hashing Once

Will Hashing Multiple Times Be More, Less, Or Similarly Secure As Hashing Once? Flushing out this question: I saw this claim: List item: Don't do this: hash = sha512(password + salt); for (i = ...

crypto.stackexchange.com

 

'War Games > webhacking.kr' 카테고리의 다른 글

[webhacking.kr] old-6 Write-Up  (0) 2022.08.30
[webhacking.kr] old-5 Write-Up  (0) 2022.08.29
[webhacking.kr] old-3 Write-Up  (4) 2022.08.26
[webhacking.kr] old-2 write-up  (0) 2022.08.24
[webhacking.kr] old-1 Write-Up  (0) 2022.08.21