ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Webhacking.kr] Challenge 27 풀이
    Wargame/Webhacking.kr 2019. 5. 12. 02:09

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

    Challenge 27 문제 첫 화면

    개발자도구로 소스를 확인해보면, index.phps를 확인해보라고 나와있으므로 index.phps로 접속해본다.

    Challenge 27 - 개발자도구

     

    index.phps로 접속하면 Challenge 27의 소스가 나온다.

    http://webhacking.kr/challenge/web/web-12/index.phps

     

    Challenge 27 페이지가 GET 방식으로 정수형 변수인 no의 값을 입력받고, 이때 eregi 함수를 통해 #, union, from, challenge, select, (, \t, /, limit, =, 0x를 no 값에서 필터링한다. 그 다음 쿼리문을 날려 id의 값이 guest면 guest 문구를 출력하고 admin이면 solve를 실행한다.

    (※ no=($_GET[no])에서 괄호( )를 통해 no가 정수형 변수임을 알 수 있다.)

     

    쿼리문 $q는 id가 guest이고 no가 guest의 no와 일치할 때에만 쿼리가 실행되어 id를 테이블에서 가져올 수 있고, no가 일치하지 않을 경우 query error가 출력된다.

     

    다시 27번 문제 페이지로 돌아와서 숫자를 아무거나 입력해보면, 1을 입력했을 때에는 guest가 출력되고 그 이외의 숫자를 입력했을 때에는 query error가 출력된다. 이를 통해 guest의 no가 1인 것을 알 수 있고, 2는 admin이라고 추측할 수 있다.

    guest의 id = 1
    2 이상부터는 query error 출력

     

    SQL Injection을 이용해 admin으로 로그인하기 위해서는 0) or no=2와 같이 입력하면 되지만, = 기호는 eregi 함수에 의해 필터링되므로 = 대신 like를 사용해야 한다. (괄호 중에서도 여는 괄호인 '('는 필터링되지만 닫는 괄호인 ')'는 필터링 대상에 포함되지 않기 때문에 0)로 입력해도 괜찮다.)

     

    like를 사용해서 쿼리문을 작성하면 0) or no like 2가 되는데, 이렇게 입력하면 아래처럼 뒤에 ')'가 남아서 에러가 난다.

    $q = "select id from challenge27_table where id='guest' and no=(0) or no like 2)" // query error
    

     

    따라서 주석 처리 기호를 사용하여 ')'가 무시되도록 만들어줘야 한다. 주석 처리 기호에는 #--가 있는데, #은 eregi 함수의 필터링 목록에 포함되어 있으므로 --를 사용한다. 이때 주의할 점은 -- 뒤에 반드시 공백을 넣어주어야 한다는 점이다. (-- 뒤에 공백이 없으면 ')'까지 문자열로 인식해버린다.)

    $q = "select id from challenge27_table where id='guest' and no=(0) or no like 2-- "

    이렇게 되면, 앞의 id='guest' and no=(0)은 false이기 때문에 그대로 넘어가고, no=2의 id인 admin을 불러온다.

     

    Challenge 27 문제 해결!

     

     

    ※ 다른 방법

    like를 이용하는 방법 외에, order by를 이용하는 방법도 있다.

     

    order by는 SQL에서 특정 column을 오름차순 또는 내림차순으로 정렬해주는 명령어이다.

    만약 select no from user order by no라는 쿼리를 실행하면, 테이블이 no열 기준으로 오름차순으로 정렬된다. 맨 뒤에 desc를 추가하면 내림차순으로 정렬된다.

     

    위에서 해당 테이블의 구조가 아래 표와 같다는 것을 알았으므로, 해당 테이블을 내림차순으로 정렬한 뒤에 첫번째 행에 있는 id를 선택하면 admin이 출력될 것이다.

    no id
    1 guest
    2 admin

     

    따라서 0) or 1 order by no desc -- 를 입력하면 내림차순으로 정렬된 테이블의 첫 번째 행이 선택되어, 그 행의 id인 admin이 출력된다.

    $q = "select id from user where id='guest' and no=(0) or 1 order by no desc -- "

     

Designed by Tistory.