[WARGAME][webhacking.kr] old-4

jckim22·2022년 11월 16일
0

[WEBHACKING] STUDY (WARGAME)

목록 보기
68/114

아래는 서버코드이다.

<?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>

이 문제에서 시간을 정말 많이 썼다.

코드 자체는 이해하기 매우 쉬운 난이도였다.
chall4 세션이 isset인지 확인하고 key값과 chall4이 일치하면 flag를 주는 문제였다.

그리고 웹페이지에 나와있는 암호는 10000000 ~ 99999999까지의 랜덤한 숫자 + "salt_for_you"라는 문자열을 sha1로 500번 해쉬한 암호이다.
이걸 이용해서 문제를 풀어야하는데 ,,
브루투포스로 숫자를 찾을 수도 없는게 한번 key값을 post요청으로 보내게 되면 매번 새로운 hash가 생기기 때문에 할 수가 없었다.
또한 sleep으로 브루트포스에 대한 공격도 방어하고 있었다.

sha1이라는 암호방식에 대해서 알아보았고 복호화 할 수 있는 방법이 있는 지도 계속 알아보았다.

sha1은 단방향이라 원문을 알 수 없다고 한다 ..

복호화 사이트에서는 1:1 매칭으로 원래 인코딩 하기 전 값을 다시 보여주기 때문에 2번이상 복호화 하거나 그 사이트에서 해쉬한게 아니면 값을 볼 수 가 없었다.

그러던 중 레인보우 테이블이라는 것을 알게되었다.

암호화 과정을 그대로 가져와 수만번 반복해서 기록하고 우리가 찾는 암호와 매칭하여 원문을 찾는 방법이다.

이 과정을 파이썬으로 하면 굉장히 오래걸릴 것이기 때문에 c로 코드를 가져와서 할까도 생각했다.

하지만 멀티쓰레드가 생각이 나서 파이썬으로 진행하기로 했다.

하지만 파이썬에서 GIL로 인하여 멀티쓰레드가 가능하지 않았다.
GIL이란 멀티 쓰레드를 실행하려고 할 때 파이썬에서는 하나의 쓰레드에 모든 자원을 투자하고 다른 쓰레드는 Lock을 걸어놓아서 동시에 실행되지 못하게 하는 방식이다.

GIL을 왜 쓰는지는 나중에 알아보기로 하고 파이썬에서 대신 멀티프로세싱을 지원한다는 것을 알게되었다.

프로세르를 하나 더 켜서 진행하는 것이다.
그렇게 되면 속도는 훨씬 빨라질 것이다.

먼저 아래처럼 멀티프로세싱 테스트를 해보았다.

이렇게 다른 프로세스에서 hi라는 문자열을 출력하는 함수를 실행한 것을 볼 수 있었다.

그럼 이제 익스플로잇 코드를 짜보자 php코드의 알고리즘 대로 짜면 됐다.

바로 아래처럼 짜보았다.

from hashlib import sha1

f = open("RainBow.txt","w")

for i in range(0,100000000):
    h1=str(i)+"salt_for_you"

    
    h1=sha1(h1.encode()).hexdigest()
    print(f"key:{i} = {h1}")
    f.write(f"key:{i} = {h1}\n")


f.close()

RainBow.txt를 쓰기 모드로 열고
0~100000000까지의 숫자를 반복하고 매 반복마다 hash에 해당 반복 숫자와 salt_for_you를 합쳐서 넣고

sha1로 암호화해준다.
그리고 파일에 써준다.

이렇게만 하면 느리니까 멀티 프로세싱을 써보자.
아래는 최종 익스플로잇 코드이다.

from multiprocessing import Process
from hashlib import sha1

def solve():
    f = open("RainBow.txt","w")

    for i in range(0,100000000):
        hash=str(i)+"salt_for_you"


        hash=sha1(hash.encode()).hexdigest()
        print(f"key:{i} = {hash}")
        f.write(f"key:{i} = {hash}\n")


    f.close()


if __name__ == '__main__':

    processes = []
    for _ in range(4):
        p = Process(target=solve) ## 각 프로세스에 작업을 등록
        p.start()
        processes.append(p)

    for process in processes:
        process.join()

원래 코드를 solve라는 함수에 담고 나는 4개의 프로세스를 함께 돌릴 것이다.

processes리스트를 생성하고 Process를 4번 시작한 뒤 porcesses에 담아준다.

그 후 각각 반복으로 실행해준다.

그럼 아래처럼 4배 빠른 속도 실행되는 것을 볼 수 있다.

그렇게 500만개 정도 찾았을 때,,, 내 자신에게 매우 실망했다.
범위를 0부터 잡은 것이다.

왠지 100번은 시도한 것 같은데 해쉬 값을 찾을 수 없었다....

절망스러웠지만 다시 코드를 수정하고 프로그램을 돌렸다...

그리고 한참 뒤 또 절망했다.

1000만개 정도 얻었는데 sha1로 암호화를 1번씩 밖에 하지 않은 데이터였다 ..

500번을 해야하는데 말이다.

다시 수정했다.

from multiprocessing import Process
from hashlib import sha1

def solve():
    f = open("RainBow.txt","a")

    for i in range(10000000,100000000):
        hash=str(i)+"salt_for_you"

        print(f"key:{i} = {hash}")
        for j in range(500):
            hash=sha1(hash.encode()).hexdigest()
        
        f.write(f"key:{i} = {hash}\n")


    f.close()

그리고 다른 문제들을 풀며 4000만개 정도 데이터를 만들었을 때
cmd로 find 했다.
사실 이때부터 잘못된 걸 알았다.

4개가 떴는데 사실 프로세스 4개를 돌린게 각자 나눠서 일을 해준게 아니라 똑같은 반복문을 비효율적으로 4번 한거나 똑같았다.
너무 당연한 얘긴데 또 바보같은 실수를 했다.
왠지 내 파일의 용량이 다 채우지도 않았는데 8기가 가까이 되었다.

사실 4000만개가 아니라 1.6억개 정도의 데이터가 만들어졌던 것이다.

컴퓨터에게 너무 비효율적인 일을 시켰었다 ...

아무튼 멀티 프로세스를 확실히 이해하고 key값마저 찾았으니 괜찮았다.


을 입력하고 제출하니

아래처럼 solve에 성공했다.

profile
개발/보안

0개의 댓글