[Web Hacking] SQL Injection : Base #1

2023. 12. 13. 23:13정보 보안/Web

 

SQL Injection이란?

 

 

  SQL Injection이란 웹 사이트의 보안 취약점을 이용하여 특정 SQL 쿼리문을 삽입하여 공격자에게 필요한 DB 정보를 추출하거나 인증 우회 등의 공격을 하는 해킹 기법이다. 주로 클라이언트가 입력하는 값에 대한 필터링 기능이 제대로 갖춰지지 않은 경우 발생한다. SQL Injection 공격은 쉬운 난이도에 비해 그 피해는 상당히 효과적이므로 주의해야 한다.

 

  SQL Injection으로 가능한 공격으로는 다음과 같다.

 

  • Authentication  Bypass (인증 우회)
  • DB Access (데이터베이스 접근)
  • Content Change (콘텐츠 변경)

 

SQL Injection 조건

 

  SQL Injection 공격이 이루어지는 원리에 대해 설명하기 위해서는 먼저 SQL Injection 공격이 가능한 조건에 대해 알아야 한다.

 

  SQL Injection 공격이 가능한 조건은 다음과 같다.

 

  • 웹 애플리케이션이 DB와 연동되어있어야 한다.
  • 사용자가 입력한 내용이 SQL 질의문의 일부분으로 사용되어야 한다.

 

  SQL Injection 공격은 웹 애플리케이션이 DB와 연동되어있어야 가능하며 사용자가 입력한 내용이 SQL 질의문의 일부분으로 사용되어야 한다. SQL 질의문을 사용하여 DB 데이터를 조회하는 흐름에 대해서 알고 있다면 위 조건들이 어느 정도 이해가 될 것이다.

 

  DB 데이터 조회 흐름은 다음과 같다.

 

  1. 사용자가 데이터를 입력
  2. 입력 데이터는 DB 언어인 SQL 질의문에 삽입
  3. 완성된 SQL 질의문으로 DB 데이터 조회
  4. 조회된 데이터 반환

 

1) 사용자가 데이터를 입력

 

 

  사용자는 필요한 정보를 조회하기 위해 데이터를 입력한다. 이는 꼭 필요한 정보를 조회한다라는 과정뿐 아니라 로그인 시 식별/인증 과정 등 SQL 질의문이 사용되는 모든 부분에서 일어나는 일련의 과정에 해당한다.

 

2) 입력 데이터는 DB 언어인 SQL 질의문에 삽입

 

 

  입력된 데이터는 서버에서 DB에 전송하기 위해 SQL 질의문의 특정 위치에 삽입된다.

 

3) 완성된 SQL 질의문으로 DB 데이터 조회

 

 

  완성된 SQL 질의문을 DB에 전달한다. DB는 전달받은 SQL 질의문에 적합한 데이터를 조회한다.

 

4) 조회된 데이터 반환

 

 

  DB에서 조회된 데이터는 서버에 반환되고 서버는 그 데이터를 사용자에게 출력해 준다. 

 

SQL Injection 원리

 

  SQL Injection 공격은 위에 설명한 DB 데이터 흐름 중에 1번, 2번 과정에서 수행 가능하다. 공격자는 2번 과정에서 사용되는 SQL 질의문이 어떻게 구성되어 있는지 추측을 하는 과정을 거치게 된다. SQL 질의문이 어떤 형태로 구성되어 있는지는 사용되는 기능에 따라 다르기 때문에 공격자는 자신이 공격을 수행하는 위치를 인지하고 추측해야 한다. 만약 웹 개발을 했던 경험이 있다면 이 과정에 큰 어려움은 없을 것이다.

 

  로그인 페이지를 예시로 들어보자. 로그인 페이지에서는 입력되는 데이터인 ID와 Password로 식별/인증 과정이 진행된다.

 

 

  위 SQL 질의문은 식별/인증 과정에서 사용하는 SQL 질의문 중 하나를 예시로 든 것이다. 1번 과정에서 입력한 데이터는 2번 과정에서 사용하는 SQL 질의문의 일부분으로서 작용된다. 로그인 페이지에서는 주로 인증 우회 공격과 DB 데이터 추출 공격이 가능하다. 그렇다면 로그인 페이지에서 SQL Injection으로 인증 우회하는 공격을 진행할 때 사용되는 SQL 질의문이 어떤 것이 있는지 알아보자.

 

1) 입력 ID' OR '1'='1

 

  인증 우회에 가장 많이 쓰이는 구문 중 하나이다. 아이디는 알지만 비밀번호는 모르는 경우 사용된다. 

 

 

  1. 아이디 입력창에 [ 아이디' OR '1' = '1 ]을 입력한다.
  2. 논리연산자 우선순위에 의해 OR 연산자보다 AND 연산자가 우선적으로 연산된다.
  3. '1' = '1'의 결과는 참이지만 비밀번호는 모르기에 PASS='비밀번호'는 거짓이 된다. 따라서 AND 연산 결과는 거짓이 된다.
  4. 아이디는 DB에 저장되어 있는 정보와 일치하므로 ID = '아이디'의 결과는 참이므로 OR 연산 결과는 참이 된다.
  5. 따라서 ID = '아이디'인 계정으로 로그인된다.

  해당 구문은 논리연산자 AND와 OR의 우선순위를 이용하여 비밀번호에 대한 일치는 필요 없이 아이디만 알아도 로그인이 가능하도록 만들어준다. 이러한 유형은 OR 뒤에 나오는 구문의 결과가 TRUE이기만 하면 되기 때문에 꼭 '1' = '1일 필요는 없다.

 

2) [아이디]' #

 

  이번 구문도 마찬가지로 아이디는 알고 있지만 비밀번호를 모르는 경우 사용된다.

 

 

  1. 아이디 입력창에 [ 아이디' #]을 입력한다.
  2. #기호로 인해 #기호 뒤의 구문은 모두 주석처리되어 비밀번호 일치 코드는 무시된다.
  3. 아이디는 DB에 저장되어 있는 정보와 일치하므로 ID = '아이디'의 결과는 참이 된다.
  4. 따라서 ID = '아이디'인 계정으로 로그인된다.

  해당 구문은 주석으로 비밀번호 일치 코드를 무시하게 만들어 아이디만 일치하면 로그인이 가능하게 만드는 구문이다. 주석 기호는 MySQL은 '#', Oracle은 '--'으로 DB마다 다르기 때문에 공격 대상의 DB의 종류가 무엇인지 파악한다거나 DB종류마다 다른 주석 기호를 모두 사용하여 공격을 시도해 볼 수 있다.

 

3) 1' OR '1' = '1' #

 

  이번 구문은 아이디도 비밀번호도 모르는 경우 사용된다.

 

 

  1. 아이디 입력창에 [ ' OR '1' = '1' # ]을 입력한다.
  2. #기호로 인해 #기호 뒤는 주석 처리되어 비밀번호 일치 코드는 무시된다.
  3. ID = '1' OR '1' = '1' 구문은 항상 참이기 때문에 DB에 저장되어 있는 모든 계정 정보를 조회한다.
  4. 모든 계정 정보를 조회하기 때문에 DB에 저장돼 있는 순서대로 조회가 된다.
  5. 이때 가장 위에 있는 계정으로 로그인된다.

  해당 구문은 아이디도 비밀번호도 모를 때 공격 대상의 웹 애플리케이션의 인증 우회가 필요한 경우 사용된다. 주석으로 비밀번호 일치 코드를 무시하게 만들고 아이디에 해당하는 논리 연산 결과를 항상 참으로 만들어 DB에 저장되어 있는 모든 계정 정보를 조회하게 만든다. 이때 DB에 가장 먼저 저장된 계정으로 로그인이 된다. 일반적으로 DB에 가장 먼저 저장되어 있는 계정은 'admin'이라는 관리자 계정일 확률이 높으므로 주의해야 한다.

 

  이렇듯 입력 데이터에 악의적인 SQL 질의문을 삽입하게 되면 삽입된 SQL 질의문은 기존에 존재하는 SQL 질의문의 구성을 변경시킴으로써 제 기능을 발휘하지 못하게 하고 공격자가 원하는 SQL 질의문에 대한 데이터를 조회하도록 만든다.

 

SQL Injection 공격 종류

 

  SQL Injection 공격은 데이터가 출력되는 방식에 따라 사용 가능한 공격이 달라진다. 대표적으로 3가지 종류가 존재하며 이는 다음과 같다.

 

  • Union Based SQL Injection : 게시판 같이 데이터가 출력되는 곳에서 사용이 가능하다.
  • Error Based SQL Injection : 에러 메시지가 출력되는 곳에서 사용이 가능하다.
  • Blind SQL Injection : 데이터가 출력되지 않아 Error Based/Union Based SQL Injection 공격이 불가능한 곳에서 사용이 가능하다.