티스토리 뷰

SQL 인젝션 



Injection이란?
  • 애플리케이션에서 서버로 전달되는 명령, 쿼리, 스크립트등의 값을 변도하여 비정상적인 방법으로 시스템에 접근하는    공격기법이다. 
  • 웹 어플리케이션에만 국한되지 않고 데이터 베이스와 연결된 모든 어플리케이션에서 고려해볼 수 있는 공격 기법이다.

데이터 베이스와 연동된 웹 어플리케이션에서 SQL 질의문에 대한 필터링이 제대로 이루어지지 않을 경우 공격자가
입력이 가능한 폼( 웹 브라우저 주소 입력창 또는 로그인 폼 등)에 조작된 질의문을 삽입하여 웹 서버의 데이터 베이스
정보를 열람 또는 조작할 수 있는 취약점

 injection의 특징

  • 파라미터, 쿠리, 내부외부 웹 서비스 등 거의 모든 데이터가 인젝션 공격 대상이 된다.

파급효과



데이터 베이스 정보노출, 데이터 삽입, 삭제 및 변경, 데이터 베이스 서비스 중지, 사용자 인증 우회

 

공격 예상도



데이터 베이스(DB)와 연동된 응용 프로그램에서 입력된 데이터에 대한 유효선 검증을 하지 않을 경우, 공격자가 입력
데이터에 SQL 쿼리문을 삽입하여 DB로 부터 정보를 열람하거나 조작할 수 있는 보안 취약점을 말한다.

위 그림과 같이 공격자는 쿼리를 조작할 수 있는 문자열을 입력하여 조작된 요청을 보낸다. 서버가 입력값을 검증하지
않고 DB쿼리 실행에 사용하는 경우 인가 되지 않는 사용자가 DB 데이터를 무단으로 조회 또는 삭제할 수 있다.


SQL 인젝션 원인과 결과


  • 임의의 SQL쿼리 입력에 대해 검증이 적절히 이루어지지 않아 발생
  • 민감한 정보 유출등의 위험이 존재
  • 웹 서비스 상 회원 정보 유출 사고의 상당수가 인젝션 공격에 의해 발생된다.

 

 

SQL 인젝션 취약점에 대한 대응방안


점검시 고려사항
SQL 인젝션 로그 유형
  • 공격 패턴 삽입 과정 중에 Internal Server Error인 500번 종류의 에러 발생 ( 스크립트 에러 )
  • 동일한 IP에서 동일한 페이지에 대한 반복된 접속 시도
  • 업무와 관련이 없는 페이지 및 패턴이 존재
SQL 인젝션 공격 대응방안
  • 사용자 입력 값 검증 / 비 정상적 입력값( ' , ", #, --, = 등 ) 필터링
  • 데이터 길이 제한
  • 적절한 오류 처리 /웹 서버 오류 페이지 구성
  • IDS/웹 방화벽 구축


설계시 고려사항
1. 어플리케이션에서 DB연결을 통해 데이터를 처리하는 경우 최소 권한이 설정된 계정을 사용해야 한다.
→ 취약한 어플리케이션으로 인해 침해 사고가 발생하더라도 나머지 부분에 대해 공격자가 액세스 권한을 가지지
않도록 어플리케이션에서 사용하는 DB연결 계정은 해당 어플리케이현이 사용하는 데이터에 대한 읽기,쓰기,삭제,
업데이트 권한만 설정한다.

2.외부입력값이 삽입되는 SQL 쿼리문을 동적으로 생성해서 실행하지 않도록 해야 한다.
→ 쿼리문의 구조가 외부입력값에 의해 변경되지 않는 API를 사용하도록 시큐어 코딩 규칙을 지정한다.

3.외부 입력값을 이용해 동적으로 SQL쿼리문을 생성해야 하는 경우, 입력값에 대한 검증을 수행한 뒤 사용한다.
→ 클라이언트와 서버 양층에서 입력값에 대해 안전한 값만 사용할 수 있도록 검증 작업을 수행한다.

    3-1. 필터를 이용한 입력값 검증
    → 외부입력값에서 SQL 삽입이 가능한 문자열들을 필터링하여 안전한 값으로 치환하도록 하는 필터링을 
        생성하고 , DB에서 관리하는 데이터를 처리하는 모든 애플리케이션에 일괄 적용한다.
    3-2. 인터셉트를 이용한 입력값 검증
    → MVC프레임워크를 사용하는 경우 인터셈터 컴포넌트를 사용하여 입력값에 대한 검증 작업을 수행 한 뒤 
       요청을 차단하거나 허용하는 정책을 어플리케이션에 일관 적용한다.
    3-3. 라이브러리 또는 Validator컴포넌트를 이용한 입력값 검증
    → 입력값을 검증하는 Validator 컴포넌트를 공통 코드로 생성하고, 모든 개발자가 SQL문에 삽입되는 
        입력값에 대해 검증작업을 해당 컴포넌트에서 수행하도록 시큐어 코딩 규칙을 정의한다.



SQL 인젝션 취약점 실습




웹 어플리케이션의 일반적인 인증 절차
  1. 계정정보(ID/PW) 입력
  2. SQL 쿼리(Query) 생성
  3. DB로 쿼리(Query) 전송
  4. DB에서 쿼리(Query) 실행
  5. 반환되는 return 값에 따라 인증 여부 판단

데이터 베이스 정보가 노출되는지 시도하는것을 목표로 두는것이 모의해킹의 목표이고, SQL injection 취약점 
존재 유무를 파악하는것이 취약점 진단이라고 할 수 있다. 
SQL injection은 크게 Error-based SQL injection, Blind injection 등으로 나눠생각해 볼 수 있다.



Error-based 취약점




공격자가 쿼리(Query) 를 이용해서 의도적으로 에러를 발생시키고 에러를 발생 시켰을 떄 웹 서버에는 디폴트 
에러 페이지를 만들어서 사용자에게 반환해준다. 디폴트 에러 페이지는 소스코드 오류나 디버깅, 에러를 
해결하기 위한 형태로 구성된 페이지이며 이러한 형태는 공격자에게 매우 큰 도움이되기 때문에 공격자는 에러
 페이지를 유발  시켜 웹서버의 기본정보나, DB정보를 얻을 수 있다.

실습환경 MS-SQL

1). Database 이름 알아내기
    1-1). MS-SQL의 Database 이름을 반환하는 함수를 이용한다. → DB_NAME()
    1-2). SQL injection 취약점이 있는 로그인 페이지
         → 'and DB NAME() >1 --

↑ 문자열과 정수를 비교할 수 없기 때문에 오류가 발생 했다. 
   # 해당 오류를 통해서 oyesmall이라는 DB명을 알아낼 수 있다.

2). Table 및 Column 이름 알아내기
    2-1). Having
         → Group by절을 이용하여 지정한 컬럼의 필드값을 집계(묶음)후 조건 비교할 떄 사용한다.
         Group by user id 를 사용하면 user id 컬럼안에 값을 같은 필드값들을 묶어 준다. Having은 묶어진
         필드값들을 한번 더 조건 검사를 수해한다.

         Having을 group by뒤에 쓴다. having은 group by와 함께 쓰이기 때문에 having을 써서 오류를 만들어
         낸다면 group by와 함께 쓰라는 오류를 표시하면서 컬럼값을 알아낼 수 있다.


having 1=1 --

↑ SELECT * FROM Members WHERE user_id = "having 1=1 --
   # having 오류 특정상 모든 컬럼을 알려주지만 에러 페이지 특성으로 인해 첫번째 컬럼 값만 알려준다.
   # Table : Members, Column : num


'group by(num) --

↑ 동일한 데이터를 묶어서 무엇을 할건지 나와있지 않기 때문에 에러가 발생했다.
   # 해당 에러를 통해서 다음 컬럼값을 유추해 낼 수 있다. 


3)Field값(Record) 값 알아내기 
SELECT user_id FROM members WHERE num > 0 → members 테이블의 user_id 컬럼의 모든 필드값을 가져온다.

WHERE 조건의 in과 not in을 이용한 field값 조회

'or 1 in (select user_id from members where num > 0) -- 
=>oyes 

'or 1 in (select user_id from members where num > 1) -- 
=>bisang2da 
=>kisec 

'or 1in(select user_id from members where user_id not in('oyes','bisang2da') ) -- 
=>kisec 


'or 1in(select user_id from members where user_id not in('oyes','bisang2da','kisec') ) -- 
=> kisectest 

고객사의 특성에따라 모의해킹 시나오도 달라진다. 현재는 위험성을 확인하는 수준의 모의해킹 시도라고 
볼 수 있다  권한이 있는 사용자가  SQL문을 이용해서 특정 테이블의 컬럼값을 알아야 하는데 
이때 테이블,필드값을 알아야한다. 때문에 공격자도 테이블과 컬럼값을 알아야 한다.

members table의 필드값을 획득할 수 있다면 다른 사용자의 권한으로 로그인할 수 있다. 이는 SQL injection의
가장 기본적인 목표이다. 이를 위해 Error-based, UNION등 다양한 유형의 injection을 시도해 볼 수 있다.



참고


- K-shield.jr 2기 정보보호 관리진단 과정
- KISA : 웹 취약점 분석 및 기술지원
- KISA : SW개발 보안 가이드