web_security/Lord Of SQL

[LOS : Lord Of SQL Injection] 18번 Nightmare 문제 풀이

HawordFREAKEK 2022. 6. 15. 02:11

네 안녕하세요. Godhaword 입니다.
예전엔 막 오전 3~4시에 자고, 그 때까지 게임이나 과제하면서 담날 9시~10시에 일어나곤 했었는데요.
요즘은 회사에 다니고 6시에는 기상해야하다보니 이렇게 늦게 깨어 있는게 오랜만인 것 같네요.

문제로 넘어가겠습니다.

<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)|#|-/i', $_GET[pw])) exit("No Hack ~_~"); 
  if(strlen($_GET[pw])>6) exit("No Hack ~_~"); 
  $query = "select id from prob_nightmare where pw=('{$_GET[pw]}') and id!='admin'"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) solve("nightmare"); 
  highlight_file(__FILE__); 
?>

일단 pw에 입력을 받을수 있고 뒤에 id != 'admin' 이라고 쓰며 admin 임을 부정하고 있습니다.

그런데 코드를 쭉 읽다가 더 까다로운점을 봤는데 pw 의 길이가 6자가 넘어가게 되면 No hack 필터링에 걸립니다.

일단 기본적으로 쿼리를 닫으려면 ') 이렇게 두글자가 사용되는데요. 나머지 네 글자로 최대한 효율적인 injection 시도를 해보겠습니다.

 

그런데 또 여기서 하나 보셔야 할 부분이

  if($result['id']) solve("nightmare");

이 부분입니다. id에 admin을 어떻게 띄워놓고는 있지만 id는 admin이 아니다라는 뜻이고, solve를 하기 위해선 어떤 id의 값이라도 긁어오면 됩니다.

정리하자면, 그냥 주석처리 할 수 있으면 pw 부분에 아무값이나 넣고, 뒤에 주석처리로 날려버린다면 pw는 거짓이다라는 값만 입증해주면 문제는 풀리게 됩니다.

그래서 그냥 구분자 닫고 주석만 잘 처리해주면

풀리게 됩니다.

 

  • 이 문제로 알 수 있는 것
    - 이 쯤 오니까 기본기, 실력은 기본으로 두고 센스를 많이 테스트 하는 것 같다.
    - 머리를 많이 써야한다
  • Key Point
;%00 으로도 주석처리가 된다