chipkkang9's story

SQL Injection 취약점 본문

Hacking/Web

SQL Injection 취약점

chipkkang 2022. 2. 11. 04:35

SQL Injection이란?

 SQL Injection은 응용프로그램, 특히 웹 사이트의 보안상 허점을 이용하여 특정 SQL 문을 보내서 DB의 중요 정보나 공격자가 원하는 정보를 가져오는 해킹 기법이다.

 

 주로 사용자가 입력한 데이터를 제대로 필터링, 이스케이핑하지 못했을 경우에 발생한다. 공격이 쉽지만 파괴력은 어마어마한 수준이기에 시큐어코딩의 기초가 되는 부분이기도 하다.

 

* SQL에 대하여,

 SQL(Structured Query Language)은 관계형 DB의 데이터를 다루는 표준형 프로그램 언어로서, 실행 과정을 알아보면 다음과 같다.

 

이름 국어 수학 영어 과학
권나라 80 40 50 90
김세정 90 60 40 70
유지민
60 80 60 80

< DB의 성적 테이블 >

 

 

"이름이 '김세정'인 학생의 점수를 알고 싶다."

< 알고 싶은 데이터 >

 

 

"select 국어, 수학, 영어, 과학 from 성적 where 이름='김세정'"

< SQL 실행 >

 

 

이름 국어 수학 영어 과학
김세정 90 60 40  70

< 결과 >

 

 이때, 공격자가 웹 프로그램의 보안상 허점을 이용하여 악의적인 SQL을 주입하여 해킹을 시도할 수 있다.

ex) 프로그램에서는 '김세정' 학생 본인의 성적만 확인할 수 있지만 공격자는 SQL 구문을 변경하여 '권나라'라는 특정인의 성적 정보를 조회한다.

 

SQL Injection의 공격 방법

해당 부분은 NoirStar Space 이름의 tistory 블로그에서 빌려온 내용입니다.

https://noirstar.tistory.com/264

 

SQL Injection 이란? (SQL 삽입 공격)

1. SQL Injection  1.1 개요 Ÿ   SQL Injection SQL Injection 이란 악의적인 사용자가 보안상의 취약점을 이용하여, 임의의 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작

noirstar.tistory.com

 

방법 1. Error based SQL Injection - 논리적 에러를 이용한 SQL Injection

가장 많이 쓰이며, 대중적인 공격 기법이다.

 

SQL 쿼리에 고의적으로 오류를 발생시켜, 출력하는 에러의 내용을 통해 정보를 찾아낸다.

 

 기본적으로 '(작은 따옴표, 싱글 쿼테이션) 또는 "(큰 따옴표, 더블 쿼테이션)을 이용하며, Group BYHAVING 등을 이용하기도 한다.

 

 보통은 관리자 계정을 맨 처음 만들기 때문에 관리자 계정에 로그인할 수 있게 하기도 한다. 관리자 계정을 탈취한 악의적인 사용자는 관리자의 권한을 이용해 또 다른 2차피해를 발생시킬 수 있게 된다.

 

방법 2. Union based SQL Injection - Union 명령어를 이용한 SQL Injection

 Union은 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드이다. 정상적인 쿼리문에 Union을 사용하여 인젝션에 성공하면, 원하는 쿼리문을 실행할 수 있게 된다.

 

 Union Injection을 성공하기 위해서는 두 가지 조건이 있다. 하나는 Union하는 두 테이블의 column(열) 수가 같아야 하고 데이터 타입이 같아야 한다.

 

방법 3. Blind SQL Injection

방법 3-1. Boolean based SQL

 

 Blind SQL Injection은 데이터베이스로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참과 거짓의 정보만 알 수 있을 때 사용한다. 로그인 폼에 SQL Injection이 가능하다고 가정했을 때, 서버가 응답하는 로그인 성공과 로그인 실패 메시지를 이용하여, DB의 테이블 정보 등을 추출해 낼 수 있다.

 

방법 3-2. Time based SQL

 

 Time Based SQL Injection도 마찬가지로 서버로부터 특정한 응답 대신에 참 혹은 거짓의 응답을 통해서 데이터베이스의 정보를 유추하는 기법이다. 사용되는 함수는 MySQL 기준으로 SLEEP과 BENCHMARK이다.

 

* SLEEP 함수

 : 단어의 의미대로 잠깐 잠을 잔다. 즉, 잠시 프로그램(쿼리)을 중단하게 만드는 함수이다. SLEEP은 대체적으로 DB에 트랜젝션을 유지시키는 등 테스트 용도로 주로 사용하게 된다.

 

** BENCHMARK 함수

: count만큼 반복적으로 expr을 실행하는 함수로서 MySQL이 expr을 얼마나 빨리 실행하는지 시간을 측정하며, 결과값은 항상 0을 반환한다.

SELECT BENCHMARK(count, expr);

방법 4. Stored Procedure SQL Injection - 저장된 프로시저에서의 SQL Injection

 Stored Procedure는 일련의 쿼리들을 모아 하나의 함수처럼 사용하기 위한 것이다. 공격에 사용되는 대표적인 Stored Procedure는 MS-SQL에 있는 xp_cmdshell로 윈도우 명령어를 사용할 수 있게 된다.

 

 단, 공격자가 시스템 권한을 획득해야 하므로 공격난이도가 높으나 공격에 성공한다면, 서버에 직접적인 피해를 입힐 수 있는 공격이다.

방법 5. Mass SQL Injection - 다량의 SQL Injection 공격

 2008년에 처음 발견된 공격기법으로 기존 SQL Injection과 달리 한 번의 공격으로 다량의 데이터베이스가 조작되어 큰 피해를 입히는 것을 의미한다. 보통 MS-SQL을 사용하는 ASP 기반 웹 애플리케이션에서 많이 사용되며 쿼리문은 hex 인코딩 방식으로 인코딩하여 공격한다.

 

 보통 데이터베이스 값을 변조하여 데이터베이스에 악성 스크립트를 삽입하고, 사용자들이 변조된 사이트에 접속 시 좀비PC에 감염되게 한다. 이렇게 감염된 좀비PC들은 DDoS 공격에 사용된다.

 

대응방안

입력 값에 대한 검증

 SQL Injection에서 사용되는 기법과 키워드는 엄청나게 많다. 따라서 사용자의 입력 값에 대한 검증이 필요한데, 서버 단에서 화이트리스트 기반으로 검증해야한다.

 

 블랙리스트 기반으로 검증하게 되면 수많은 차단리스트를 등록해야하고, 혹여나 하나라도 빠지면 해커의 위협에 노출되기 때문이다.

 

 취약 키워드를 공백으로 치환하는 방법도 많이 쓰이는 방법인데, 이 또한 취약한 방법이다. 예를 들어, 공격자가 SESELECTLECT라고 입력 시, 중간의 SELECT가 공백으로 치환되면 SELECT는 키워드가 완성된다. 공백 대신 공격 키워드와는 의미없는 단어로 치환되는 것이 더 안전한 방법이라고 할 수 있다.

Prepared Statement 구문 사용

 Prepared Statement 구문을 사용하면, 사용자의 입력 값이 데이터베이스의 파라미터로 들어가기 전에 DBMS(DataBase Management System, 데이터베이스 관리 시스템)가 미리 컴파일하여 실행하지 않고 대기한다.

 

 그 후, 사용자의 입력 값을 문자열로 인식하게 하여 공격 쿼리가 들어간다고 하더라도, 해커의 입력은 이미 의미 없는 단순 문자열이기 때문에 전체 쿼리문도 공격자의 의도대로 작동하지 않는다.

웹 방화벽 사용

 웹 공격 방어에 특화되어 있는 웹 방화벽을 사용하는 것도 하나의 방법이다.

 

 웹 방화벽은 소프트웨어 형, 하드웨어 형, 프록시 형 이렇게 세 종류가 있다.

 - 소프트웨어 형 : 서버 내에 직접 설치하는 방법

 - 하드웨어 형 : 네트워크 상에서 서버 앞 단에 직접 하드웨어 장비로 구성하는 방법

 - 프록시 형 : DNS 서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법

Comments