sql injection bypass WAF


소스코드 분석

def index()

  • 루트 경로(/)로 GET 혹은 POST 요청이 들어오면 uid 파라미터 값을 가져와 check_WAF 함수 인자로 전달한다.
  • check_WAF 함수는 사용자로부터 입력된 값을 검증하는 함수이며, 검증에 통과하면 그 아래 쿼리문이 실행된다.
  • 쿼리문이 실행되면, 반환된 응답 결과(result)의 1번째 인덱스 값이 화면에 출력된다.
    • 이 값을 플래그 출력에 활용해야 한다.

def check_WAF(data)

  • 이 함수에서는 사용자의 입력 값 중 keywords 리스트 문자열이 포함되는지 검증한다.
  • 대소문자 구분은 하지 않기 때문에 영문자의 경우 대문자를 입력하면 우회 가능하다.

init.sql

  • DB 테이블에는 컬럼이 3개 있다.
    • (0) idx / (1) uid / (2) upw


EXPLOIT

  • 아래와 같이 LIKE 문을 통해 플래그 출력을 시도했다.
  • result[1] 값이 upw 라고 생각하고 쿼리를 짰는데, 다시 생각해보니 result[1]은 uid 값이었다.
    • LIKE 문으로는 result[2] 값을 가져올 수 없으므로 쿼리문을 수정해야 한다.

  • UNION 절을 이용하면 DB 테이블에 정의된 컬럼의 순서를 바꿔 값을 가져올 수 있다.
    • 기존에는 idx,uid,upw 순서로 값을 가져왔지만 이 순서를 idx,upw,uid로 바꿔주었다.
    • 패스워드에 해당하는 값이 result[1] 으로 변경됐기 때문에 이제 패스워드 값이 화면에 출력된다.
      • (참고) UNION을 사용하기 위해서는 컬럼 개수와 속성 값을 일치해줘야 하는데 앞 셀렉트 절에서는 *가 사용됐기 때문에 뒤 셀렉트 절의 컬럼 순서를 따르게 된다. 따라서 컬럼 개수만 동일하게 맞춰주면 오류가 발생하지 않는다.
  • UNION 절로 값을 가져오도록 하고 WHERE 절로 upw 값이 DH{ 로 시작하는 행을 가져오면 플래그 확인 가능했다!

🐛.. 🐛.. 🐛..


REFERENCE

  1. https://binaryu.tistory.com/31