[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가 나서 이 기법이 막힌다고 한다..

댓글남기기