wargame/webhacking.kr

Webhacking.kr(old) 4번

LimeLee 2019. 11. 13. 20:14

웹케알이 리뉴얼 되었다.

너무 옛날 버전의 취약점은 약간씩 고쳐지고 문제의도를 잘 모르겠는 문제들도 개편되었다.

 

4번도 이에 해당된다.

기존문제는 base64로 인코딩된 값을 풀어 나오는 sha1의 값을 rainbow 테이블로 찾아내면 되는 문제였다. 

 

sha1의 레인보우 테이블은 웹에서 지원하는 경우가 많기 때문에 쉽게 찾을 수 있었지만, 리뉴얼 되면서 의도된 바는 레인보우 테이블이 어떻게 만들어지는 지에 대한 원리를 직접 느껴보길 바라는 의도인 것으로 보인다.

 

바뀐 문제를 풀어보자.

 

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

 

  • $hash rand(10000000,99999999)."salt_for_you";

10000000에서 99999999 사이의 숫자를 하나 뽑아 salt_for_you와 합친다.

예로 49202176이라는 숫자라면 변수 $hash에는 "49202176salt_for_you"가 들어간다.

 

  • $_SESSION['chall4'] = $hash;

$hash의 값을 가진 $_SESSION['chall4']를 정의한다. 

위의 예시와 동일하다면 $_SESSION['chall4']에는 "49202176salt_for_you"가 들어간다.

 

  • for($i=0;$i<500;$i++) $hash sha1($hash);

$hash 변수의 값을 sha1 암호화 한다. 이를 500번 반복한다.

위의 예시라면 $hash의 변수에는 "e4ce8502d7361793cee6c94ffedc4f5262877406"가 들어간다.

 

최종적으로 화면상에 출력되는 $hash의 값을 보고 $_SESSION['chall4'] 를 맞추는 것이 이번 문제의 목표라고 할 수 있다.

 

md5나 sha1 등의 알고리즘은 base64와 달리 단방향 암호화 알고리즘으로 암호화된 해시 값으로 원래의 문자열로 복호화 할 수 없다. 즉 이론상으로는 $hash의 값을 보고 $_SESSION['chall4']의 값을 알아내는 것이 불가능. 

하지만 레인보우 테이블을 이용하면 $_SESSION['chall4']의 값을 알아내는 것이 가능하다. 

 

단방향 암호화 알고리즘의 특징인 문자열 A를 암호화하면 어떤 경우에도 문자열 B가 된다는 특징을 이용하여 특정 문자열에 대한 암호화를 시도하여 나온 결과값을 데이터베이스에 저장하여 매핑시키도록 한 것이 레인보우 테이블이다.

 

위에서 말했다시피 sha1에 대한 레인보우 테이블을 지원해주는 웹 사이트가 많이 존재하지만, 이를 방지하기 위해 sha1 암호화를 500번 반복하였다. 

 

푸는 방법은 직접 sha1 암호화를 500번해서 문제에 나온 hash와 비교하면 된다.

 

python으로 실시간으로 비교하는 코드를 짤 수 있다.

#python3
from hashlib import sha1
import random

t=1
while(t==1):
    thash = str(random.randint(10000000,99999999))+"salt_for_you"
    temp = thash
    for i in range(0,500):
        thash = sha1(thash.encode('utf-8')).hexdigest()
    
    if (thash == "48df44120d72fb68bc2748474c2e4cbc96edbc51"):
        print(temp)
        t=0

 

다만 단점은 지금까지 시도한 해시값들이 저장이 안되어 세션이 끊기면 안되기 때문에 계속적으로 세션을 유지해야하는 것과 문제 페이지에 떠있는 1건에 대해서만 비교를 해야한다는 것, 그리고 random으로 뽑기 때문에 운이 좋으면 금방 값이 나오지만 운이 나쁘면 약 9천만건에 대해 반복해야 값이 나올 수 있다는 것이 있다.

 

처음 문제를 풀 때는 위 코드로 얻어걸려(;) 금방 풀었지만, 위의 코드로 다시 풀려고 하니 역시나 잘 안되서 레인보우 테이블을 만드는 방법으로 다시 풀었다. 

from hashlib import sha1
from multiprocessing import Process, Queue


def work(id,start,end,result):
    f = open("sha1_"+str(id)+".txt", 'w')
    for i in range(start,end):
        thash = str(i)+"salt_for_you"
        temp = thash
        for k in range(0,500):
            thash = sha1(thash.encode('utf-8')).hexdigest()
        data = temp+" - "+thash+"\n"
        f.write(data)
    f.close()
    return

if __name__ == "__main__":
    START, END = 10000000,100000000
    result = Queue()
    th1 = Process(target=work, args=(1, START, END//2, result))
    th2 = Process(target=work, args=(2, END//2, END, result))

    th1.start()
    th2.start()
    th1.join()
    th2.join()

 

DB를 사용하지 않고 파일시스템을 사용했다. DB를 사용해도 된다.

라즈베리파이 서버가 있지만 파일시스템으로 만들것이기 때문에 하드웨어 성능이 부족할거 같아 일반 개인용 노트북을 이용했다. 

프로세스는 2개 사용했다. 8기가 램 환경에서 4GB가량을 쓰면서 시간상 하루정도 돌렸다.  

 

약 5천 4백만건에 대한 레인보우테이블이 완성되었다.

 

용량이 커서 notepad는 커녕 sublime text로도 열기 버겁다.

grep을 통해서 찾다보면 간간히 얻어걸리는 건이 존재한다.

 

 

환경이 더 좋거나 메모리를 효율적으로 사용하면 더 많은 프로세스를 생성해서 하루에 더 많은 데이터를 만들수 있을 것같다.

 

 

터지기 일보 직전

 

+

현재 채팅창에서 사라진 채팅은 일반 유저가 다시 열람할 수 없기에 스크린샷으로 남겨둔다.

문제 운영자께서 원래 의도했던 것은 레인보우 테이블을 효율적으로 제작하지 않으면 시간이 너무 오래걸리는 문제를 만들고자 했지만 레인보우 테이블만 만들기만 하면 되는 문제로 바뀌었다고 한다.

 

운영자가 생각한 효율적으로 레인보우 테이블을 구현하는 아이디어는 위와 같다.

문제를 얼떨결에 푼 사람들도 효율적으로 구현하는 방법을 생각해서 풀어보면 재밌을 것 같다. 

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

Webhacking.kr(old) 52번  (0) 2019.12.05
webhacking.kr 42번 풀이  (1) 2018.08.13
webhacking.kr 18번 풀이  (0) 2018.08.13
webhacking.kr 34번 풀이  (1) 2018.08.10
webhacking.kr 8번 풀이  (0) 2018.08.08