webhacking.kr challenge 27
첫 화면에 sql injection이라고 써 있다. 아무것도 모르니 소스 페이지를 확인했다.
주석 부분에 index.phps 가 써있다. 이동해 보자.
페이지의 php코드까지 상세하게 나와있다. 이 부분을 해석해보자.
if($_GET[no])
{
if(eregi("#|union|from|challenge|select|\(|\t|/|limit|=|0x",$_GET[no])) exit("no hack");$q=@mysql_fetch_array(mysql_query("select id from challenge27_table where id='guest' and no=($_GET[no])")) or die("query error");
if($q[id]=="guest") echo("guest");
if($q[id]=="admin") @solve();
}
no라는 변수값을 GET방식으로 전달 받는다.
그리고 no 라는 변수에서 "#|union|from|challenge|select|\(|\t|/|limit|=|0x" 에 해당하는 문자열이 있으면 no hack을 띄운다.
challenge27 이라는 테이블에서 id=guest와 입력한 no의 값에 해당하는 데이터를 가져와 변수 q에 저장한다. 그렇지 않으면 querry error라는 문자를 띄운다.
만약 q의 id가 guest라면 guest를 띄우고 q의 id가 admin이라면 문제가 해결된다.
처음에는 그냥 0부터 넣었다.
0은 아무것도 나오지 않았다. 1을 넣었을 때는 아래와 같이 guest라고 나왔다.
그리고 2부터는 querry error가 떴다.
문제를 해결하기 위해서는 위의 코드에서 봤던것처럼 id가 admin 이 되어야 한다. 하지만 쿼리문에서 id=guest라는 데이터를 꺼내기 때문에 이를 바꾸기 어렵다.
그렇다면 ("select id from challenge27_table where id='guest' and no=($_GET[no])")) or die("query error") 에서 직접 넣을 수 있는 부분인 $_GET[no] 을 이용하는 방법을 생각했다. 구글링을 통해 살펴보니 or 과 --(주석, eregi부분을 우회하기 위해 #대신 사용)을 통해 해결 할 수 있다.
입력을 임의의 수) or no=0 -- 또는 임의의 수) or no=2 -- 를 입력하면 문제를 해결 할 수 있다.
먼저 임의의 수) or no=0 --를 살펴보자. 입력을 하면 ("select id from challenge27_table where id='guest' and no=(임의의 수) or no=0 --)")) or die("query error") 가 된다. 이렇게 된다면 주석처리(--)때문에 )")) or die("query error") 이 모두 코드로 읽히지 않는다. and와 or이 함께 있을 경우 or을 기준으로 먼저 나누기 때문에 and로 이어진 한 묶음과 no=0 -- 를 비교해야 한다. and를 살펴보면 위에서 guest의 no는 1인걸 확인했다. 따라서 거짓이 된다. or 앞쪽이 거짓이니 뒤에 있는 no=0 만 살펴서 진짜인지 거짓인지 확인하는 것이다.
임의의 수) or no=2 -- 도 마찬가지 이다. 임의의 수는 1만 아니면 어떤 수도 괜찮다. no의 값은 0과 2로 예측하는데 그 이유는 guest가 1이기 때문이다.
먼저 no=0을 입력했다.
querry error가 뜬다. 그렇다면 no=2를 입력해보자.
똑같이 querry error가 떴다. 뭐지 해서 봤더니 --뒤에 띄어쓰기를 넣어줘야 한다.
성공!
댓글
댓글 쓰기