ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Webhacking.kr] Challenge 18 풀이
    Wargame/Webhacking.kr 2019. 3. 30. 23:09

    이번 문제는 SQL Injection 문제이다.

     

    Challenge 18 첫 화면

    먼저 index.phps 페이지를 확인해보자.

    index.phps

    코드를 확인해보면, no를 GET 방식으로 입력받아야 아래 소스가 실행된다는 것을 알 수 있다.

    여기서 no는 입력칸에 입력된 값이 저장되는 변수이다.

    입력칸 부분의 코드

     

    eregi는 php의 입력 문자열 필터링 함수이다. 이 함수로 인해 공백, /, 괄호, \t, |, &, union, select, from, 0x는 no의 입력값으로 올 수 없다. 만약 이 문자들이 입력되면 exit 함수가 실행되어 no hack 문구가 출력된다.

     

    그 뒤에 나오는

    $q=@mysql_fetch_array(mysql_query("select id from challenge18_table where id='guest' and no=$_GET[no]"));

    코드는 id가 guest이고 입력 받은 no값과 일치하는 id를 검색한 결과값을 q에 저장한다는 뜻이다.

    q의 값이 guest이면 guest 계정으로 로그인되고, admin이면 admin 계정에 로그인되어 solve( ) 함수가 수행된다.

     

    따라서 admin 계정으로 로그인하면 이번 문제는 해결된다.

     

    일단 입력칸에 1을 입력해 제출해보면 hi guest 문구가 출력된다.

    1 입력 후 화면
    GET 방식으로 no가 전송되었기 때문에 URL에 no의 값이 나타난다.

    이를 통해 guest의 no는 1임을 알 수 있다.

     

    admin으로 로그인하기 위해서 admin의 no가 0 또는 2라고 가정하고 SQL Injection을 시도해보자.

     

    1을 입력했을 때의 쿼리는 아래와 같다.

    select id from challenge18_table where id='guest' and no=1 

     

    반면 3 or no=2를 입력할 경우, 쿼리는 아래와 같이 된다.

    select id from challenge18_table where id='guest' and no=3 or no=2 

    이 경우 id='guest' and no=3은 false가 되기 때문에 그대로 넘어가고, no=2인 id를 불러오게 된다.

     

    하지만 3 or no=2를 그대로 입력하면 eregi 함수가 공백을 필터링하고 그대로 종료시키기 때문에, 공백을 우회해야 한다.

     

    공백을 우회하는 방법에는 여러 가지가 있는데,

    \t, \n, \r, 주석(/* */), 괄호 등을 공백 대신 사용한다.

     

    하지만 \t와 괄호는 eregi 함수의 필터링 목록에 포함되어 있으므로 여기서는 \n을 사용하도록 한다.

    \n을 인코딩한 값인 %0a를 공백 부분에 삽입해 URL에 입력한다. 

    no=3%0aor%0ano=2

     

    hi admin

    hi admin이 출력된 것을 확인할 수 있다.

    (원래는 Congratulation 팝업창이 뜨는데 나는 이미 한번 풀었기 때문에 저렇게 표시된다.)

Designed by Tistory.