webhacking.kr - old 18 (SQL Injection)
대놓고 'SQL INJECTION' 쓰여 있다.
먼저 코드를 확인해보자.
php 코드를 중점으로 보면 될 거 같다.
<?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!";
}
}
?>
if($_GET ['no']) 에서 'no'라는 매개변수를 확인하는 거 같다.
데이터베이스를 연결하고 그 밑에는 필터링이 있다.
if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET ['no'])) exit("no hack");
여기서 특수기호들과 select, from 등 SQL injection를 막는 거 같다.
preg_match에서는 공백을 필터링시켜버린다
위에 코드에는 없지만 원본을 보면 주석으로 '// admin's no = 2'라고 힌트를 줬다.
2가 아닌 1을 먼저 대입해 봤더니 guest로 접속이 되었다.
2를 넣었을 때는 아무 일도 일어나지 않았다.
(select id from chall18 where id='guest' and no=2' 부분에서 and연산으로 인해 거부당한 것)
일단 핵심은 no 값에다가 2를 넣으면 될 거 같다.
select id from chall18 id='guest' and no=0 or no=2
이렇게 공격을 하면 필터링에서 걸러진다 그러면 필터링을 우회해야 한다.
url encode 방식으로 문자열을 URL로 사용할 수 있도록 인코딩 시키는 것이다.
하지만 굳이 이렇게 쓸 필요 없고 no값만 건 들여보도록 하자.
no=0%09or%09no=2
input 칸에 다가 넣으면 문자열로 받아들이기 때문에 URL로 인코딩 시킨 만큼 URL 에다가 대입해 보자.
문제가 풀렸다.