[webhacking.kr] old-18

asdf·약 11시간 전

web

목록 보기
9/10


기본적인 SQL INJECTION 문제입니다. 소스 코드를 제공을 해주기 때문에 먼저 확인을 해보겠습니다.

<?php
if($_GET['no']){
  $db = dbconnect();
  if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET['no'])) exit("no hack");
  $result = mysqli_fetch_array(mysqli_query($db,"select id from chall18 where id='guest' and no=$_GET[no]")); // admin's no = 2

  if($result['id']=="guest") echo "hi guest";
  if($result['id']=="admin"){
    solve(18);
    echo "hi admin!";
  }
}
?>

solve를 실행하기 위해서는 $result['id']admin이 되어야 합니다. query문 뒤의 주석에서 admin의 id가 2임을 알 수 있습니다.

select id from chall18 where id='guest' and no=$_GET[no]

and와 or 연산 사이에서는 and가 우선순위가 더 높습니다. 따라서 id='guest' and no=$_GET[no] 이후 or no=2를 붙인 후 or 앞을 false가 되도록 설정하면 DB에서 no=2인 id를 선택하게 됩니다.

따라서 입력해야 하는 값은 0 or no=2 입니다.

if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET['no'])) exit("no hack");

하지만 preg_match로 필터링을 하고 있습니다. 여기서 걸리는 값은 preg_match문 내부에 있는 공백(space)입니다. 따라서 공백만 다른 문자로 대체한 후 입력을 진행하면 문제를 해결할 수 있을 것 같습니다.

따라서 공백을 우회할 수 있는 URL 인코딩 문자인 %09(Tab) 혹은 %0a(줄 바꿈 문자)를 공백 대신 사용하면 됩니다.

최종적으로 넣어야 하는 답은 공백을 Tab으로 변경한 0%09or%09no=2가 됩니다. 이대로 답을 입력창에 넣어보겠습니다.

값을 넣었고, url에서 ?no= 뒤에 작성한 값이 들어간 것을 확인할 수 있습니다. 하지만 문제가 해결되지 않았습니다.

그 이유는 %09 같은 URL 인코딩 문자를 <input type=text name=no> 같은 브라우저에 넣게 되면 브라우저는 사용자가 입력한 값을 단순한 평문으로 취급하게 됩니다. 따라서 %09를 Tab으로 보는 것이 아니라 그냥 %09라는 평문으로 인식하게 됩니다.

이를 해결하기 위해서는 URL에 직접 ?no=...를 입력하면 정상적으로 %09가 Tab으로 변환되면서 원하던 동작이 수행됩니다.

profile
Rainy Waltz(a_hisa)

0개의 댓글