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

id와 pw에 '를 쓸 수가 없다. 문제를 풀려면 백슬래시(\)를 사용해서 escape 처리를 해야 한다. 
참고로 한국의 돈 단위 ₩(원)도 백슬래시 역할이다.

sql에서 문자 앞에 백슬래시(\)를 붙이면 문자 그자체로 인식한다. '도 마찬가지다.
sql에서 '는 문자(열)을 표현하는 역할인데 \'은 ' 문자 그 자체로 인식한다.

이 문제에서 id엔 \을 대입하고 pw엔 or 1%23을 대입하자. 아래와 같은 쿼리가 완성된다.
query : select id from prob_succubus where id='\' and pw='or 1#'

id엔 파란색 문자열이 대입된다. 두번째 등장하는 ' 은 백슬래시(\)로 인해 문자로 인식된다. 

따라서 id의 값은 ' and pw= 가 된다. or 뒤에 1은 늘 참이다.

따라서 쿼리 실행 결과 모든 행들이 조건을 만족할 것이며 id가 반드시 존재하기에 문제가 풀린다.

#은 url에서 예약 문자이기 때문에 %23으로 URL 인코딩한 값을 전달해야 '#'으로 PHP에서 인식한다.

답: ?id=\&pw=or 1%23

728x90

'Lord of SQL Injection' 카테고리의 다른 글

nightmare  (0) 2022.12.23
zombie_assassin  (0) 2022.12.23
assassin  (0) 2022.12.23
giant  (0) 2022.12.23
bugbear  (0) 2022.12.22

+ Recent posts