php로 작성된 페이지다. 일단 사이트에 들어가면 ID와 Password가 나온다.
현재 대회가 종료된 고로 코드 리뷰랑 정답만 간략히 정리하도록 하겠다.
사실 플래그에 대한 단서는 문제 파일 중 check.php 파일에만 있다고 보면 된다.
여기서,
(int)$input_id == $id && strlen($input_id) === 10) 랑 (int)$input_pw == $pw && strlen($input_pw) === 8)
부분을 보면 알겠지만 int형으로 형변환 해서 id, pw와 비교하는 것을 알 수 있고, 또 자릿수에 대한 힌트도 얻을 수 있다.
php 문제에서, 어떠한 조건이나 필터링 없이 바로 비교해서 값을 판별하는 코드의 경우, magic hash를 이용해서 id, pw값을 true로 만들고 로그인 할 수 있다.
매직해시: 링크텍스트
(위 링크 참조)
==라는 비교적 약한 비교를 사용하고 있고, php의 경우 두 값의 데이터만 같으면 형태가 달라도 알아서 최적의 형태로 형변환을 해서 비교하기 때문에 여기서 취약점이 발생할 수 있다.
input_id가 0e로 시작할 경우, int 형변환에 의해 0으로 해석되고, 최적의 형태를 맞추기 위해 string으로 이루어진 id의 값도 int형으로 변하면서 0으로 해석된다. 이를 이용해 앞자리가 0e로 시작하고 나머지 6자리는 아무거나 입력해도 id가 같다고 인식하고 넘어가는 것을 볼 수 있다.
마찬가지로, 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값을 구할 수 있다.