4번 문제이다.
3번 문제는 DB 모양이여서 SQLi 공격을 이용하면 될것같았지만
4번 문제는 뭘 의미하는지 모르겠다.
원래 저 모양은 소스코드나 코드를 의미할때 많이 쓰이는 그림인데...
일단 문제를 클릭해서 보자.
클릭하면 초록색 글씨로 어떤 값이 나오고 Passwrod를 입력하는 칸이 나온다.
test라고 입력하고 발생하는 패킷을 한번 보자.
POST 형식으로 key라는 파라미터 우리가 입력한 test를 볼 수 있다.
그 후 페이지 소스를 보니 딱히 뭐 별다른게 없어보인다.
따라서 문제에서 주어진 [view-source]를 클릭해서 소스를 보자.
[view-source]를 클릭하면 해당 문제의 소스코드를 볼 수 있다.
php 코드를 보여주는데 핵심은 여기인것 같다.
일단 sleep(1)함수가 먼저 보인다.
주석으로는 anti brute force가 적혀있다.
나는 이 주석을 보고 힌트를 얻었다.
일단 굳이 sleep을 준 이유도 없을것이고 주석으로 친절히 anti brute force로 적어준것으로 보아
몇번으로 해결된 문제가 아닌거 같았다.
그 다음줄을 보자.
if문을 크게 2개로 나눠보면 (isset($_SESSION['chall4']) 과 ($_POST['key'] == $_SESSION['chall4']) 로 나눌 수 있다.
이 2개가 참이면 solve(4)가 실행되면서 문제를 clear 할 수 있을것 같다.
php에서 isset은 $_SESSION['chall4']) 이라는 변수가 설정되어있는지 확인하는 함수이다.
다음 우리가 password에 입력한 key값이 $_SESSION['chall4']) 와 &&,
즉 같다면 solve(4) 함수를 실행 할 수 있다.
그 후 코드를 보자.
$hash = rand(10000000,99999999)."salt_for_you";
위의 코드는 rand 함수를 사용하여 랜덤한 숫자를 만들어내는 함수이다.
범위는 10000000 ~ 99999999이다.
그리고 뒤에 salt로 "salt_for_you"에가 존재한다.
예를들어 rand 함수에서 12345678가 생성되었다면
$hash 라는 변수에는 12345678salt_for_you가 저장된다.
그 다음은 $_SESSION['chall4'] = $hash;으로 위의 12345678salt_for_you의 값이 해당 변수에 저장된다.
마지막 코드는 for문을 돌리는데 12345678salt_for_you 값은
sha1 함수를 돌리고 다시 hash 변수에 넣어주고 이걸 500번 반복한다.
여기까지 정리해보자면 다음과 같다.
- 주석에 anti brute force이 있는걸 보아 한번에 답을 찾을수는 없을것 같다.
- 우리가 입력하는 key값 즉 password와 hash값이 같아야한다.
그럼 내가 출제자가 원하는 방향으로 문제를 해결하기위해서는
rand 함수의 범위를 10000000,99999999를 주고 위에 솔트 문장을 짜서 brute force로
값을 서버로 날려봐도 소용이 없다.
sleep 함수도 있고 주석에도 친절하게 anti brute force라고 적혀있으니..
조금 생각해보니 문제를 클릭했을때 무슨초록색으로 무슨 값이 나왔었다.
총 크기도 20 바이트고.. sha1으로 나온 hsah 값인것같다.
그러면 저기 나오는 초록색 hsah 값은 총 sha1을 500번 돌린 값이라는걸 알 수있다.
하지만 sha1이 처음 실행되는 인자에는 rand 함수에서 12345678가 생성되었다면
제일 처음 $hash 라는 변수에는 12345678salt_for_you가 들어간다.
그 후 sha1을 500번 돌린 hash값을 변수 $hash에 최종적으로 넣는다.
그 값이 우리가 볼 수 있는 초록색 값이고 이것은
즉, 처음 만들어진 12345678salt_for_you이 값을 찾아야하는 문제인것 같다. (Point 1)
그럼 이 문제를 풀기위해서는 다음과 같이 생각할 수 있다.
- 먼저 문제에서 나오는 해쉬값을 본다.
- 그 후 문제처럼 rand(10000000,99999999)를 통해 숫자를 정한다.
- 나온 숫자 뒤에 "salt_for_you"를 합쳐준다.
- 나온숫자+salt_for_you(ex 12345678salt_for_you)를 sha1으로 500번 돌린다.
- 500번 돌린 hash값과 문제에서나오는 hash 값을 비교한다.
- 맞으면 정답은 12345678salt_for_you
- 아니면 다시 처음부터 수행한다.
하지만 이렇게 하다보면 webhacking.kr 서버와 세션이 끊어질 수 있다.
실컷 답을 찾아 12345678salt_for_you를 입력하려고 할때 로그인을 다시해야한다.
그러면 다시 찾아야한다.
따라서 이번 문제는 핵심 포인트는
rand이 아닌 처음값인 10000000부터 마지막 값인 99999999 까지 값을 미리 사전에 만들어
sha1으로 500번 돌린 값을 미리 구해 비교하면 훨씬 빠르다. (Point 2)
그리고 모든 10000000~99999999 까지 모든 값을 할 필요도 없다.
물론 10000000~99999999 까지 모든 값을 사전에 준비하면 한번에 문제를 풀 수는 있지만
어차피 이번 문제는 확률문제이다.
따라서 나는 4분의 1인 값인 10000000~25000000만 미리 계산하였다.
이렇게 총 만들어진 파일의 용량은 761MB이다.
해당 소스는 다음과 같다.
이렇게 hash.txt라는 파일을 만든 후 문제에서 주어진 hash값을 파일에서 찾으면 이번 문제는 clear다.