Level 17을 보면 flag값을 추측 할 수 있냐? 라는 질문과 함께 소스코드를 확인하라고 나와있다. 클릭해보자.
소스를 확인해 보니 POST로 보내준 flag 값과 $flag 값이 일치할 경우 flag 값을 출력해주고 틀리면 "Invalid flag, sorry."라는 문구를 출력해 주는 것을 확인할 수 있다.
이때 flag값을 비교하는 strcasecmp에서 발생하는 취약점(비교 할때 '=='를 사용)을 이용해서 flag를 찾을 수 있었다.
strcasecmp에서는 값을 비교 할때 strcasecmp($a, $b)를 실행하게 되면 $a가 작을때 음수, $b가 작을때 양수, $a와 $b가 같으면 0이 반환된다.
즉, 0을 리턴할 수 있는 방법이 있다면 flag 값을 얻을 수 있다는 의미이다.
0을 리턴할 수 있는 방법은 아래를 통해서 해결할 수 있었다.
response 값을 통해서 php 버전(PHP/5.6.26-1) 이 노출 되고 있는것을 확인할 수 있었고 php 5.3 이상의 버전에서는 문자열과 배열을 비교하게 되면 NULL이 출력된다. 그렇기 때문에 NULL과 0을 비교하면 True가 되므로 문자열을 알지 못하더라도 배열을 넣으면 두 가지 값이 동일해지면서 flag 값을 얻을 수 있는 것이다.
위와 같이 flag[] 값으로 넣어주니 flag 값을 보내주는 것을 확인 할 수 있다.
flag = WEBSEC{It_seems_that_php_could_use_a_stricter_typing_system}