Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

박나겸

웹 보안 본문

cs 스터디

웹 보안

itsmekyum 2024. 2. 5. 22:30

SQL Injection

SQL Injection이란 악의적인 사용자가 보안상의 취약점을 이용하여, 임의의 SQL문을 주입하고 실행되게 하여
데이터베이스가 비정상적인 동작을 하도록 조작하는 행위이다. 이는 비교적 쉬운 방법이면서도 성공시 큰 피해를 입힐 수 있는 공격이다. 

클라이언트가 입력한 데이터를 제대로 필터링 하지 못하는 경우에 발생한다.

SQL Injection의 예시이다.

- 각 클라이언트가 자격증 번호를 조회하는 시스템

- SQL 진행은 anjinma 클라이언트가 '자격증 번호 조회'를 클릭하여 anjinma라는 이름이 웹 서버에 전송되면 DB 입력값과 비교한 다음 일치하면 자격증 DB를 출력해준다.

- 여기서 blackhat 이 anjinma의 자격증 번호를 조회하기 위해 SQL문을 수정하지만 권한이 없기에 받아올 수 없다.

- ex) http://search?=anjinma url을 전송할때 anjinma가 로그인 되어있으면 정상적으로 자격증 번호를 조회할 수 있지만 blackhat이 로그인 되어있으면 자격증 번호를 조회할 수 없다.

- 공격자인 blackhat은 url뒤에 ' or '1'='1'을 넣어줘서 항상 참이 되게 만들어서 자격증 번호를 조회해 온다.

 

이런식으로 2017년 여기어때에서도 대량의 고객 정보등이 유출이 되었다고 한다. 

 

SQL 공격 기법은 여러 가지가 있는데, 크게 다음과 같이 여섯 가지로 구분 가능하다.

 

Error based SQL injection

- 앞서 예를 든것 처럼 해당 기법이 sql injection의 기본이다.

- 논리적 에러를 사용한 SQL Injection이다.

- 정상접근 -> Select * from cliend where name='anjinma' and password='12345'

- SQL Injection -> Select * from client where name='anjinma' and password=' or '1'='1'

' or '1'='1'를 넣어서 1과 1이 같아서 항상 참이므로 로그인에 성공하게 된다.

 

Union based SQL injection

- SQL UNION이란 여러개의 SQL문을 합쳐 하나의 SQL문으로 만들어주는 방법이다.

- union injection을 위해서는 union 하는 두테이블의 컬럼수화 데이터 형이 같아야된다. 

- 밑 예시에서 1번 쿼리문은 입력값을 title과 contents 컬럼의 데이터랑 비교한 뒤 비슷한 글자가 있는 게시글을 출력하다.

여기에 Union Injection을 실행하여 컬럼 수를 맞춰서 SELECT 구문을 넣어주게 되면 두 쿼리문이 합쳐져서 출력이 된다.

따라서 성공하게 되면 id와 passwd가 게시글과 함께 하나의 테이블로 보여지게 되는 것이다.

Blind SQL Injection - Boolean based SQL Injection

- 평범한 SQL 삽입과 같이 원하는 데이터를 가져올 쿼리를 삽입하는 기술이지만 Blind SQL 삽입은 참과 거짓,
쿼리가 참과 거짓에 대한 반응을 구분할 수 있을때 사용되는 기술이다.

- 로그인 폼에 SQL injection이 가능하다고 가정했을 때, 서버가 응답하는 로그인 성공과 실패 메세지를 사용해서 DB의 테이블 정보를 알아낼 수 있다. 

\

- 위 쿼리문으로 결과를 얻어 한글자씩 끊어온 값을 아스키코드로 변환시키고 임의의 숫자와 비교하여 참과 거짓을

비교하는 과정을 거쳐가며 일치하는 아스키 코드를 찾아낸다. 위 과정을 반복하여 결과들을 조합하여 원하는 정보를

얻어내는 것이다.

 

Blind SQL Injection - Time based SQL Injection

- 어떤 경우에는 응답의 결과가 항상 동일하여 해당 결과만으로 참과 거짓을 판별할 수 없는 경우가 있을 수 있다.

이런 경우 시간을 지연시키는 쿼리를 주입하여 응답시간의 차이로 참과 거짓 여부를 판별한다.

-  위의 쿼리문은 Time based SQL Injection을 사용하여 현재 사용하고 있는 데이터베이스의 길이를 알아내는 방법이다. 로그인 폼에 임의의 abc123 이라는 계정을 만들었다. 악의적인 사용자가 주입한 문을 보면 'Length는 문자열을 길이를 반환하고 database는 데이터 베이스의 이름을 반환한다.' 는 쿼리문이다

- 주입된 구문에서, LENGTH(DATABASE()) = 1 가 참이면 SLEEP(2) 가 동작하고, 거짓이면 동작하지 않는다. 1이라면 뒤에 위치한 SLEEP(2) 함수가 동작하게 함으로써 데이터베이스의 길이를 알아낼 수 있다.

Stored Procedure SQL Injection

저장된 프로시저에서의 SQL Injection로 저장 프로시저는 일련의 쿼리들을 모아 하나의 함수처럼 사용하기 위한 것이다.

공격에 사용되는 대표적인 저장 프로시저는 MS-SQL에 있는 xp_cmdshell로 윈도우 명령어로 사용할 수 있게 된다.

단, 공격자가 시스템 권한을 획득 해야 하기 때문에 공격 난이도가 높다.

Mass SQL Injection

다량의 SQL Injection 공격으로 이름처럼 한번의 공격으로 다량의 데이터베이스가 조작되어 큰 피해를 입게 된다.

SQL Injection 대응 방안

1. 입력 값에 대한 검증

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

2. Prepared Statement 구문사용

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

3. Error Message 노출 금지

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

4. 웹 방화벽 사용

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