ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Webhacking.kr] Challenge 59 풀이
    Wargame/Webhacking.kr 2019. 5. 19. 03:34

    59번 문제로 들어가보면, 회원가입과 로그인을 할 수 있는 입력창이 보인다.

     

    개발자도구를 실행해서 각 입력칸이 무엇을 의미하는지 알아보았다.

     

    Join: id, phone
    Login: lid, lphone

     

    소스코드를 통해 두 입력칸이 각각 id와 phone을 입력받는 곳임을 알 수 있었다.

     

    개발자도구로는 더 알아낼 정보가 없어서 이번엔 소스 링크를 클릭해보니 해당 페이지의 소스코드가 나왔다.

     

    Challenge 59의 소스코드

     

    아래에 있는 if문이 JOIN에 대한 조건인 것 같으니 아래 조건문부터 먼저 살펴보자.

     

    JOIN

     

    이 조건문에서는, 입력받은 phone의 길이가 20 이상이거나, 문자열 내에 admin, 0x, #, hex, char, ascii, ord, from, select, union 중 하나라도 포함되어 있으면 Access Denied 문구와 함께 페이지를 종료한다. 또한 입력받은 id가 admin이어도 페이지를 종료한다.

    위 조건문을 모두 통과하면 입력받은 id와 phone 값을 테이블에 삽입한다. ($_POST[phone]만 싱글쿼터(')로 묶여있지 않은 것으로 보아, phone 변수는 숫자형이라는 것을 알 수 있다.)

     

    이제 LOGIN에 대한 코드를 해석해보자.

     

    LOGIN

     

    LOGIN에서는 입력받은 id와 phone이 JOIN에서 등록한 id와 phone과 같으면 해당 계정의 id와 lv를 불러온다. 이때, lv가 admin이면 문제가 해결된다. 

     

    일단 아무거나 입력해보자. JOIN에서 id와 phone을 각각 '1234'로 등록한 뒤에 LOGIN을 해본다.

     

    로그인 결과 lv가 guest로 설정된 것을 알 수 있다. 이는 JOIN에서 insert를 할 때 lv가 guest로 고정되어 있기 때문에 그런 것이다.

     

    따라서 lv를 조작하려면 JOIN을 할 때 phone에서 SQL 인젝션을 시도해야 한다.

    SQL 인젝션이 제대로 먹히는지 확인하기 위해 JOIN의 phone 입력칸에 1, 1)-- 를 입력한 뒤에 로그인을 해보았다. (-- 뒤에 공백을 필수로 넣어주어야 한다.)

     

    로그인 결과 lv의 값이 1로 바뀐 것으로 보아, SQL 인젝션이 제대로 수행된다는 것을 확인할 수 있었다.

     

    이제 SQL 인젝션을 이용하여 lv를 admin으로 변조하면 문제는 해결된다. 그러나 JOIN에서 id, phone 모두 eregi 함수로 admin을 필터링하기 때문에 이를 우회해야 한다. 

     

    이 문제에서는 reverse 함수를 사용하여 필터링을 우회할 수 있다. reverse 함수는 인자로 들어온 문자열을 거꾸로 반환해주는 함수이다. 따라서 JOIN의 id에 admin을 거꾸로 뒤집은 nimda를 입력해주고, phone에는 1, reverse(id))-- 를 입력한 뒤 id=nimda, phone=1로 로그인해주면 문제가 해결된다.  

     

     

Designed by Tistory.