본문 바로가기

wargame/LOS

[LOS]3번 GOBLIN

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을 다른 숫자의 형태로 바꿔서 조건을 만들면 된다.



사실 이 문제는 WEBHACKING.kr에 같은 문제가 있어서 쉽게 해결할 수 있었다.


'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