[Dreamhack] strcmp write-up

😊 문제 설명

if you can bypass the strcmp function, you get the flag.

✏️ 풀이

문제 접속해서 코드를 먼저 살펴보자.

문제 코드

<?php    require("./lib.php"); // for FLAG    
	$password = sha1(md5(rand().rand().rand()).rand());  
  
    if (isset($_GET['view-source'])) {        show_source(__FILE__);  
        exit();  
    }else if(isset($_POST['password'])){        sleep(1); // do not brute force!        
    if (strcmp($_POST['password'], $password) == 0) {  
            echo "Congratulations! Flag is <b>" . $FLAG ."</b>";  
            exit();  
        } else {  
            echo "Wrong password..";  
        }  
    }  
  
?>  
<br />  
<br />  
<form method="POST">  
    password : <input type="text" name="password" /> <input type="submit" value="chk">  
</form>  
<br />  
<a href="?view-source">view-source</a>

strcmp 함수는 PHP 전형적으로 비교 함수인데 ==으로 비교할 때 취약점이 발생한다.

strcmp 함수는 string1, string2를 인자로 받고 같으면 0, 다르면 1또는 -1을 반환한다. 문제에서는 0이면 FLAG 값을 준다고 하는 것을 알 수 있다.

아래는 PHP에서 == 느슨한 비교를 사용했을 때의 결과 표를 살펴보면 NULL과 0을 비교할 때 TRUE를 반환한다. 따라서 strcmp 의 인자 하나를 배열로 만들어서 비교하면 NULL이 되기 때문에 취약점이 발생한다.

아래와 같이 파라미터 이름에 [] 문자를 넣으면 PHP에서 자동으로 배열로 변환해주어 FLAG 값을 획득할 수 있다. 참고로 PHP 8.0부터는 strcmp에 배열을 넣으면 NULL이 아니라 TypeError가 나서 이 기법이 막힌다고 한다..

카테고리:

업데이트:

댓글남기기