Web Hacking/Webhacking.kr

Webhacking.kr old-04 풀이

프레딕 2024. 1. 7. 00:17
728x90

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

 

사실 상 볼 코드는 중간에 <?php 부터 ?> 까지이다.

session에 chall4가 post로 온 key값과 일치하면 풀리는 문제이다.

그러면 chall4값을 봐야하는데

1. hash 변수에 10000000~99999999까지의 랜덤 값과 + salt_for_you를 합친 값을 저장한다.

2. 이 hash를 chall4 세션값에 저장하고 

3. hash는 sha1암호화를 500번 진행한다.

4. 그다음 이 암호화된 hash가 화면에 뜬다.

 

먼저 sha1암호화는 단방향 암호화로 다시 복호화 할 방법이 없다. 그렇지만 같은 값을 암호화 할 시 똑같은 암호화 값을 가진다는 문제점이 있다. 이를 위해선 브루트 포스도 방법인데 sleep(1)으로 막아놨다. 

그러면 10000000~99999999까지 암호화를 진행하며 암호화된 값과 같은 값이 나오는걸 찾는다...?

이론상으론 가능하지만 이 많은 값을 500번 암호화 진행하다간 컴퓨터가 맛이 갈것 같고 심지어 세션이 이 많은 값을 암호화할 시간동안 버티지도 못할 것이다. (중간에 세션이 풀려 로그아웃됨)

그렇다면 레인보우 테이블을 만들면 될 것 같다.

레인보우 테이블이란 암호화된 모든 값을 저장한 테이블 같은 것이다. 

그렇다고 10000000~99999999사이의 값이 대략 1억개인데 모두 만들다간 하루가 꼬박 갈것이다. 

그래서 10000000~20000000까지의 값 대략 천만개만 레인보우 테이블을 만든 후 세션을 계속 새로고침하며 이 사이의 값이 뜨길 빌 수 밖에 없을 것 같다.

 

import hashlib

def sha1_500(text):
    for i in range(500):
        text = hashlib.sha1(text.encode("ascii")).hexdigest()
    return text

f = open("dict.txt",'w')
SALT = 'salt_for_you'

for i in range(10000000,20000000):
    text = str(i)+SALT
    f.write(str(i) + " : " + sha1_500(text) + '\n')
f.close()

파이썬으로 10000000~20000000까지의 레인보우 테이블을 만드는 코드이다.

파이썬에서 sha1암호화를 위해선 먼저 인코딩(아스키나 utf8 등)을 한 값을 hashlib.sha1함수로 암호화 시키고 hexdigest()로 표현시키면 된다.

그다음 dict.txt 파일에 500번 암호화된 값을 계속 저장했다.

그런데 천만개도 많은 건지 몇십분 이상 기다려도 계속 코드가 돌아갔다.

어쩔 수 없이 dict.txt파일이 다만들어지지 않은 채로 열은 다음 화면에 표시된 $hash값과 dict.txt파일에 있는 값에 동일한 값이 있는지 계속 찾아주었다.

한 20번째 새로고침하니 겨우 하나 떴고 해당되는 숫자와 salt_for_you를 합친 값을 입력했더니 풀리게 되었다.  

(풀이를 위해 다시 풀어볼려고 했지만 시간이 좀 들어서 해결된 페이지만 첨부했다...)

dict.txt 일부

728x90
반응형