7주차_CTF과제(Dreamhack : Type c-j)

2024. 5. 25. 13:23hacking : p_study/Dreamhack

 

https://dreamhack.io/wargame/challenges/960

 

Type c-j

Description php로 작성된 페이지입니다. 알맞은 Id과 Password를 입력하여 플래그를 획득하세요. 플래그의 형식은 DH{...} 입니다.

dreamhack.io

 

 

해당 문제는 php로 작성된 페이지로, 알맞은 id와 password를 입력하면 플래그를 획득할 수 있다고 설명이 나와있다.

 

 

서버를 생성하였다.

id와 password를 입력받아 submit하도록 간단하게 구성되어있다.

 

 

php 파일도 확인해보자.

 

 

해당내용은 check.php 내용이다.

 

일단 코드를 살펴보면, 아이디 문자열 길이가 10, 비밀번호는 8일 것으로 (자릿수 제한이 있음) 예상되지만, 느낌상 해당 아이디와 비밀번호를 직접적으로 찾는 것은 어려울 것으로 보여져서, 우회를 해서 로그인을 시도해야할 것같다.

 

 

id -> swlug , password -> 123을 넣었을 때 try again이 떴다.

 

이제부터 우회하는 방법에 대해 생각해볼건데, 지난 주차는 strcmp 즉, 문자열 비교할 때 php우회하는 방법이 있었다.

strlen에 관해서도 혹시 우회하는 방법이 따로 있을까하여 찾아보았다.

 

확실히 php에 관한 strcmp는 취약점, 인증 우회방법에 대해 많은 정보들이 나와있었다.

해당 내용이 훨씬 다루기 좋아보이고, 다양한 방법들이 나와있는 걸 보니 strlen에 관해서는 취약점이나 특정 우회방법을 다루는 것 같지는 않았다.

 

$id = getRandStr();
$pw = sha1("1");

 

해당 내용을 살펴보자.

 

이 문제를 통해 알게된 내용

 

1) 위 코드는 id는 랜덤으로 생성되어 저장된 사실을 알 수 있다. 

2) pw는 sha1을 1로 해싱한 값이 저장되어 있다는 사실을 알 수 있다.

 

 

sha1를 통해서 1로 해싱된 값은 356A192B7913B04C54574D18C28D46E6395428AB인데, 코드를 자세히 보게 되면 모든 해싱된 값이 들어가지 않는다는 것을 알 수 있다고 한다.

 

pw 값은 8자리 제한이 있기때문에 , sha1로 해싱된 값에서 앞자리 8자리가 password가 된다고 보면 된다.
따라서 , pw 값은 356A192B 이다.

 

더보기

 input_pw도 동일한 논리로, 위에 보면 $pw=sha1("1"); 을 통해 pw에 1이 sha-1에 해시된 값이 들어간다는 것을 알 수 있음.

여기서 magic hash를 이용할 수 있는데, str을 int로 형변환할 경우, 0이 되고, 마찬가지로 string 값을 가진 pw도 0이 됨을 알 수 있음.

즉, input_pw에 1이 sha-1 해시로 인해 해시된 값의 0 전까지의 값 + 8자리를 맞추기 위한 잉여 0을 채워 입력하면 pw값을 구할 수 있음.

 

[ 참고자료 : 매직 해시 ]

https://blog.lael.be/post/1238

 

PHP Magic Hash Vulnerability 취약점

PHP 의 Magic Hash 취약점에 대해서 알아보았다.     실제로 Magic Hash 는 취약점이 아니라 특수동작입니다.   이론 우리가 다루는 대부분의 자료형은 “문자형(String)” 입니다. 일부 프로그래밍 언어

blog.lael.be

 

이제 id를 알아보자. 랜덤으로 생성되어 변수에 지정되고 변수에 저장된 값을 비교한다.

 if((int)$input_pw == $pw && strlen($input_pw) === 8){
    echo "<pre>FLAG\n";
    echo $flag;
    echo "</pre>";
}

 

int으로 되어있는데,  int으로 되어 있는 경우 첫번째 글자가 숫자가 아니면 0으로 인식한다고 한다.

새롭게 알게된 내용 : int으로 되어 있는 경우 첫번째 글자가 숫자가 아니면 0으로 인식함.

 

더보기

input_id가 0e로 시작할 경우, int 형변환에 의해 0으로 해석되고, 최적의 형태를 맞추기 위해 string으로 이루어진 id의 값도 int형으로 변하면서 0으로 해석됨

이를 이용해 앞자리가 0e로 시작하고 나머지 6자리는 아무거나 입력해도 id가 같다고 인식하고 넘어감.

 

10자리이므로 최종적으로 id 0000000000일 것이다.

 

 

해시값은 평문을 해시값으로 변환해주는 변환사이트를 이용했다.

매직해시라는 것을 처음 접한 것 같은데 , 해당 내용은 블로그를 참고해서 추후에 추가 공부를 진행해야할 것 같다.

오늘 문제는 내가 평소 php문제를 풀때, 우회하는 방법들을 위주로 봐왔어서 이 문제도 당연히 우회해서 풀겠거니 생각했는데, 우회를 하지않고 직접 값을 도출해서 문제를 푸는 점이 인상깊었다.

여러가지 문제를 풀어서 경험치를 쌓는 것이 가장 중요한 시기인것 같다.

 

 

[ 참고 자료 ]

 

https://velog.io/@vina1601/CTF-Write-up-yjjguhdv

 

CTF-Write-up

php로 작성된 페이지다. 일단 사이트에 들어가면 ID와 Password가 나온다.현재 대회가 종료된 고로 코드 리뷰랑 정답만 간략히 정리하도록 하겠다.사실 플래그에 대한 단서는 문제 파일 중 check.php

velog.io