GOBLIN
<?php
include "./config.php";
login_chk();
dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'|\"|\`/i', $_GET[no])) exit("No Quotes ~_~");
// no 필터링
$query = "select id from prob_goblin where id='guest' and no={$_GET[no]}";
// prob_goblin 테이블에서 id가 guest이고 no가 $_GET[no]인 record의 id값을 select하는 쿼리
echo "<hr>query : <strong>{$query}</strong><hr><br>"; // 쿼리 출력
$result = @mysql_fetch_array(mysql_query($query)); //쿼리 실행
if($result['id']) echo "<h2>Hello {$result[id]}</h2>"; // $result['id']가 존재하면 $result['id'] 출력
if($result['id'] == 'admin') solve("goblin"); // $result['id']가 admin이면 문제 해결
highlight_file(__FILE__);
?>
no에 1을 입력하면 hello guest가 출력된다
만약 no에 1을 제외한 다른 값을 입력하면 아무것도 출력되지 않는다.
위의 코드에서 볼 수 있듯이 where 조건을 만족한 $result['id']값이 존재해야만 "Hello ~~"가 출력되므로
prob_goblin 테이블에서 id가 guest인 record의 no 값은 1임을 알 수 있다.
no가 1인 레코드의 id 값이 guest이므로 no가 2인 record의 id 값이 admin이라고 추측할 수 있다.
한 번 해보면 추측이 맞았음을 알 수 있다.
조건이 id = guest and (FALSE인 조건) or no = 2으로 만들면 and, or 연산자 우선 순위를 통해 FALSE or no = 2인 조건이 완성된다. 따라서 no가 2인 record의 id 값이 select 되므로 원하는 값을 출력할 수 있다.
만약 id = guest and no = 1 or no = 2 으로 조건을 만들면 (id가 guest일 때) or (id가 admin일 때)인 조건이 완성된다. 따라서 어떤 값이 mysql_fetch_array에 의해 $result의 변수에 담길지 확신할 수 없다.
위의 이유로 실패!
no가 1만 아니라면 무조건 id가 admin일 때의 조건만 살아남으므로 문제를 해결할 수 있다.
참고로 no = 2 대신 id = 'admin'을 입력할 수는 없다. '(싱글 쿼터)이 필터링이 되어있다.
정석 풀이는 밑의 풀이로 보인다.
'(싱글 쿼터)를 이용할 수 없으므로 admin을 다른 숫자의 형태로 바꿔서 조건을 만들면 된다.
'wargame > LOS' 카테고리의 다른 글
[LOS]6번 DARKELF (0) | 2019.07.21 |
---|---|
[LOS]5번 WOLFMAN (0) | 2019.07.12 |
[LOS]4번 ORC (0) | 2019.07.11 |
[LOS]2번 COBOLT (0) | 2019.07.09 |
[LOS]1번 GREMLIN (0) | 2019.07.09 |