SQL Injection

SQL Injection 이란 악의적인 사용자가 보안상의 취약점을 이용하여, 임의의 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위를 말한다. 인젝션 공격은 OWASP Top10 중 첫 번째에 속해 있으며, 공격이 비교적 쉬운 편이고 공격에 성공할 경우 큰 피해를 입힐 수 있는 공격이다.

 

2017년 3월에 일어난 "여기어때" 의 대규모 개인정보 유출 사건도 SQL Injectrion 으로 인해 피해가 발생하였다.

 

"과속방지 카메라에 SQL Injection하기"로 돌아다니고 있는 사진

 

출처 나무위키 (https://namu.wiki/w/SQL%20injection)

 

위의 만화에 대해 설명하자면, 저 학교에서 입력한 명령은 다음과 같을 것이다.

INSERT INTO students (이름) VALUES ('학생 이름');

여기서 Robert'); DROP TABLE students;-- 을 '학생 이름' 자리에 넣을 경우 다음과 같은 명령문이 된다.

INSERT INTO students (이름) VALUES ('Robert');
DROP TABLE students;
--');

첫 번째 줄에서는 Robert라는 학생이 입력되었지만, 두 번째 줄에서 학생들의 데이터가 있는 테이블을 제거한다. 그리고 세 번째에서는 뒤에 오는 내용을 모두 주석 처리한다. 결과적으로 ‘모든 학생 기록을 삭제한다.’라는 뜻의 명령문이 완성된다. 위에서 설명한 방법은 논리적인 에러를 이용한 SQL Injection 이라고 한다. 이 방법 이외에 다양한 방법이 존재한다.

UNION based SQL Injection

여러개의 SQL문을 합쳐 하나의 SQL문으로 만들어주는 방법이다. UNION과 UNION ALL로 나뉘는데 중복 값을 제외하고 안하고의 차이다.

SELECT name FROM tableA;
UNION 
SELECT name FROM tableB;

tableA와 tableB의 name이 중복된 이름을 제외한 튜플들이 합쳐져서 출력된다. 여기서 중요한 점은 두 테이블은 컬럼 갯수가 일치해야만 오류가 나지 않는다.

[ 입력 값 ]
ID : test' UNION SELECT 1,1 --
PW : hello

입력 값이 이렇게 되었고, 모든 validation을 통과했다는 전제하에는 쿼리는 아래와 같이 실행된다.

SELECT * FROM users WHERE id = 'test' UNION SELECT 1,1 -- and password='hello'

쿼리대로 실행되면 users 테이블에 모든 튜플들이 조회된다.

 

Blind SQL Injection

이것은 공격자가 웹에서 SQL Injection을 이용하여 모든 튜플을 조회가 가능해도 결과 값을 확인할 수 없을 때 사용한다. 즉, 쿼리를 삽입했을 때 쿼리의 값을 서버의 반응 만으로 데이터를 얻어내는 기술이다. 말이 잘 이해되지 않는다면 이 게시글을 참고하면 이해가 더 쉬울 것 같다.

https://blog.naver.com/lstarrlodyl/221541453346

 

[웹해킹] webhacking.kr 2번 문제

장치나 인명의 안전을 위한 보안기(arrester) → arrester 피뢰기에 감동? 받으며 IT보안 공부하는 김주...

blog.naver.com

위에서 사용한 방식은 SQL Injection을 시도해도 결과 값이 날짜(사실은 숫자형)로 밖에 확인할 수 없기에 먼저 비밀번호의 길이를 확인한 후 비밀번호를 한글자씩 끊어 아스키 코드를 찾아낸다. 그러한 과정을 반복하여 원하는 정보를 얻어냄으로써 공격을 이루어지게 한다. 많은 비교과정이 필요하기 때문에 악의적인 목적을 가진 해커들은 Blind SQL 삽입 공격을 시도할 때는 매크로를 사용하여 공격한다.

Time based SQL Injection 출처 (https://noirstar.tistory.com/264)

이외에 Blind SQL Injection의 일종인 Time based SQL Injection 도 있다. 응답의 결과가 항상 동일하여 해당 결과만으로 원하는 값을 판별할 수 없는 경우가 있을 수 있다. 이런 경우는 시간을 지연시키는 쿼리를 Injection 하여 응답 시간의 차이로 참과 거짓 여부를 판별할 수 있다.

 

대응 방안

입력 값에 대한 검증

SQL Injection 에서 사용되는 기법과 키워드는 엄청나게 많다. 사용자의 입력 값에 대한 검증이 필요하다. 서버 단에서 화이트리스트 기반으로 검증해야 하고, 블랙리스트 기반으로 검증하게 되면 수많은 차단리스트를 등록해야 하고, 하나라도 빠지면 공격에 성공하게 되기 때문이다. 공백으로 치환하는 방법도 많이 쓰이는데, 이 방법도 취약한 방법이다. 예를 들어 공격자가 SESELECTLECT 라고 입력 시 중간의 SELECT가 공백으로 치환이 되면 SELECT 라는 키워드가 완성되게 되기 때문에 공백 대신 공격 키워드와는 의미 없는 단어로 치환되어야 한다.

 

Prepared Statement 구문사용

Prepared Statement 구문을 사용하게 되면, 사용자의 입력 값이 데이터베이스의 파라미터로 들어가기 전에DBMS가 미리 컴파일 하여 실행하지 않고 대기하기 때문에 그 후 사용자의 입력 값을 문자열로 인식하게 하여 공격쿼리가 들어간다고 하더라도, 사용자의 입력은 이미 의미 없는 단순 문자열 이기 때문에 전체 쿼리문도 공격자의 의도대로 작동하지 않는다.

 

Error Message 노출 금지

공격자가 SQL Injection을 수행하기 위해서는 데이터베이스의 정보(테이블명, 컬럼명 등)가 필요하다. 데이터베이스 에러 발생 시 따로 처리를 해주지 않았다면, 에러가 발생한 쿼리문과 함께 에러에 관한 내용을 반환한다. 여기서 테이블명 및 컬럼명 그리고 쿼리문이 노출이 될 수 있기 때문에, 데이터 베이스에 대한 오류발생 시 사용자에게 보여줄 수 있는 페이지를 제작 혹은 메시지박스를 띄우도록 하여야 한다.

 

웹 방화벽 사용

웹 공격 방어에 특화되어있는 웹 방화벽을 사용하는 것도 하나의 방법이다. 웹 방화벽은 소프트웨어 형, 하드웨어 형, 프록시 형 이렇게 세가지 종류로 나눌 수 있는데 소프트웨어 형은 서버 내에 직접 설치하는 방법이고, 하드웨어 형은 네트워크 상에서 서버 앞 단에 직접 하드웨어 장비로 구성하는 것이며 마지막으로 프록시 형은 DNS 서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법이다.

'보안 > DBMS' 카테고리의 다른 글

Clustered Index vs Non-Clustered Index  (0) 2022.07.01