
주어진 문제 파일에서 check.php 파일의 소스코드를 확인해보니 특정 조건 5개를 모두 만족하면 플래그를 주는 형식이었다. 조건은 아래와 같다.
if($input_1 != "" && $input_2 != ""){
if(strlen($input_1) < 4){
if($input_1 < "8" && $input_1 < "7.A" && $input_1 > "7.9"){
if(strlen($input_2) < 3 && strlen($input_2) > 1){
if($input_2 < 74 && $input_2 > "74"){
echo "</br></br></br><pre>FLAG\n";
echo $flag;
echo "</pre>";
} else echo "<br><br><br><h4>Good try.</h4>";
} else echo "<br><br><br><h4>Good try.</h4><br>";
} else echo "<br><br><br><h4>Try again.</h4><br>";
} else echo "<br><br><br><h4>Try again.</h4><br>";
} else{
echo '<br><br><br><h4>Fill the input box.</h4>';
}
$input_1 조건
- 4자리 미만
- ($input_1 < "8" && $input_1 < "7.A" && $input_1 > "7.9")
$input_2 조건
- 2자리 수
- ("74" < $input_2 < 74)
우선 세 번째 조건을 보면 "8", "7.A"보다 작으면서, "7.9" 보다 커야한다. 딱 봐도 ASCII 코드를 이용해야 할 것 같다.
그럼 해당 문제의 키는 "PHP에서 숫자,문자 비교와 문자, 문자 간의 비교를 어떻게 수행하는가"이다.
숫자 비교일 경우 문자열의 처음부터 숫자 부분까지만 숫자로 변경하고 나머지는 무시.
"3:" => 3
":3" => 0
문자로만 이루어진 경우 혹은 문자로 시작하는 경우 0으로 처리된다.
사전식 비교는 문자열의 각 문자를 ASCII 코드 값으로 변경해서 높은 자리부터 한 자리씩 비교한다.
"7.A" < "8.B"를 비교한다 하면,
1) 우선 각 문자가 ASCII 값으로 변경돼 배열에 저장되고,
"7.A" => [55,46,65]
"8.B" => [56,46,66]
2) 각 배열에 저장된 값을 순서대로 비교한다.
첫 번째 값을 비교했을 때 55가 56보다 작기 때문에 "7.A"의 값이 "8.B" 보다 작다고 판단해 True를 반환하게 된다.
대부분의 프로그래밍 언어는 이와 같이 문자와 숫자를 비교한다고 한다.
$input_1의 조건을 보면, "7.A"보다 작다는건"8"보다 작다는 의미이므로, 결국 만족해야할 조건은 ("7.9"< $input_1 < "7.A")이다.
문자와 문자 비교는 사전식 비교를 하기 때문에 7.까지는 동일해야하며, 마지막 자리가 9와 A의 사잇값이면 된다.
- ASCII 코드 9와 A의 사잇값
:, ;, <, =, >, ?, @
따라서 $input_1의 값은 7.:~7.@까지.
다음으로 $input_2의 조건은 2자리 수이면서 ("74" < $input_2 < 74)를 만족해야한다.
해당 조건은 먼저 "74"와 사전식 비교를 수행한 후, 74와 숫자 비교를 한다.
"74"를 ASCII 코드로 변환하면 [55,52]이기 때문에 첫 번째 값에 ASCII 코드 55보다 큰 값이 들어가면 된다.
다음으로, 74와의 숫자비교는 문자로만 이루어진 경우 0이 되기 때문에, 결국 7보다 큰 특수문자 2개를 입력하면 해당 조건도 통과가 된다.
따라서 최종 답은
$input_1 : 7.: ~ 7.@ $input_2 : :: ~ @@

올바른 값을 입력하면 아래와 같이 플래그 값이 반환된다.
