[SK shieldus Rookies 16기] 클라우드 기반 스마트 융합 보안 과정 교육 정리(38일차)
오늘 학습 주제
1. SQL Injection
SQL Injection
- Injection(삽입) -
외부 입력값을 내부 처리에 사용하는 경우
외부 입력값에 처리를 조작하는 문자열 포함 여부를 확인하지 않고 사용하는 경우
원래 의도했던 처리가 변경되어 수행되는 것
이때, 처리가 쿼리문을 만들고 실행하는 처리 ⇒ SQL 삽입
XPath 또는 XQuery 구문을 이용해서 XML 문서를 조작하는 처리 ⇒ XPath 삽입, XQuery 삽입
LDAP 서버에 쿼리를 실행하는 처리 ⇒ LDAP 삽입
운영체제 명령어를 실행하는 처리 ⇒ Command 인젝션 = 운영체제 명령어 삽입
- Injection 방어 -
입력값을 검증, 제한하여 외부에서 전달되는 값에 처리를 조작하는 문자열 포함 여부를 확인하고 사용
처리를 조작하는 문자열을 사용하지 않거나 안전하게 변경(이스케이프 처리)하여 사용실행될 내용(구조)를 미리 정의하고 구문에 입력값을 맵핑하는 방식으로 처리
- SQL Injection -
외부 입력값에 쿼리 조작 문자열 포함 여부를 확인하지 않고 쿼리문 생성 및 실행에 사용하는 경우,
쿼리의 구조와 의미가 변경되어서 실행되어
권한 밖의 데이터에 접근이 가능, 해당 DBMS 시스템의 제어권을 탈취, 쿼리를 통해 제공할 기능을 우회 또는 오용이 가능
select * from member where id = ___ ⇐ 사용자가 입력한 ID와 일치하는 회원 정보를 조회해서 제공
- Error Based SQL Injection -
입력값으로 오류를 유발하는 값을 전달하여
생성되는 오류 메시지를 통해서 정보를 수집하고 이용하여 추가 공격을 계획
select * from member where id = 123'
⇒ ID 컬럼의 값으로 문자열을 사용할 수 없습니다. 형식의 메시지가 출력 ⇒ ID 컬럼은 Number 타입인 것을 알 수 있음
- 항상 참이 되는 입력의 SQL Injection -
쿼리문의 조건식의 결과가 항상 참이 되게 만드는 입력
권한 밖에 데이터에 접근, 조회가 가능
예) ___ or 항상참이되는조건
select * from member where id = 123 or 1 = 1
⇒ 모든 회원의 정보가 조회
- Union Based SQL Injection -
원래 서비스를 통해서 실행되는 쿼리 구문에 공격자가 알고자 하는 쿼리를 UNION 구문을 이용해서 결합하여 실행
원래 서비스를 통해서 제공되는 정보와 함께 공격자가 알고자 하는 정보가 함께 노출(제공)
select * from member where id = 123 ⇒ 회원의 이름, 나이, 성별, 전화번호 정보가 조회되어 출력
select * from member where id = 123 and 1 = 2 UNION select 1, 2, 3, 4 from 어떤테이블 ⇒ 1, 2, 3, 4가 출력
- Stored Procedure 호출 -
데이터베이스에서 제공하는 Stored Procedure를 실행하는 구문을 입력값으로 전달해서 실행
데이터베이스의 제어권을 탈취하는 것이 가능
Stored Procedure: 데이터베이스에서 사전에 컴파일되어 저장된 하나 이상의 SQL 문으로 구성된 프로그램
select * from member where id = 123 ; exec xp_cmdshell 'cmd.exe /c dir'
; : 쿼리문의 종결을 의미
exec : Stored Procedure를 실행
xp_cmdshell : MS-SQL에서 제공하는 시스템 Stored Procedure로,
매개변수로 전달된 값을 DBMS의 쉘에서 실행하고 그 결과를 반환
'cmd.exe /c dir' : 현재 디렉터리의 내용을 반환
- Blind SQL Injection -
쿼리 실행 결과에 따라서 서버의 반응이 달라지는 경우
공격자가 원하는 내용을 조회하는 쿼리를 작성해서 전달하고 실행 결과를 보면서 정보를 수집
[정상적인 실행]
select * from member where id = 123 ⇒ ID가 123인 사용자의 정보가 제공
select * from member where id = 999 ⇒ ID가 999인 사용자가 존재하지 않으므로 존재하지 않습니다. 메시지가 제공
[공격 가능 여부를 확인]
select * from member where id = 123 and 1 = 1 ⇒ ID가 123인 사용자의 정보가 제공
select * from member where id = 123 and 1 = 2 ⇒ 존재하지 않습니다. 메시지가 제공
[공격자가 알고자 하는 정보를 전달]
select * from member where id = 123 and 공격자가 알고자하는 정보를 조회하는 쿼리
⇒ 사용자 정보가 제공되면 쿼리의 실행 결과가 참인 것을
메시지가 제공되면 쿼리의 실행 결과가 거짓인 것을 알 수 있음
- PreparedStatement -
쿼리의 구조를 미리 정의하고 변수에 값을 맵핑해 실행하는 방법으로,
정의된 쿼리 구조로 실행되는 것을 보장 ⇒ 구조화된 쿼리 실행
- Union 구문 -
FirstQuery union SecondQuery두 쿼리의 실행 결과를 하나로 합쳐주는 역할
사용 조건두 쿼리의 실행 결화로 반환되는 컬럼의 개수가 같아야 함두 쿼리의 실행 결과의 각 컬럼의 데이터 타입이 호환 가능해야 함
- SQL Injection 방어 -
구조화된 쿼리를 이요해서 쿼리문을 정의하고 실행(PreparedStatement)
입력값에 쿼리 조작 문자열 포함 여부를 확인하고 사용(이스케이프)
특정 프레임워크(iBatis, myBatis 등)를 사용할 경우 외부 입력값을 # 기호 사용하여 쿼리맵에 적용한다
오류 메시지에 시스템 중요 정보가 포함되지 않도록 한다
오류가 발생하면 오류에 대한 구체적인 내용이 아닌 일반화된 메시지가 제공되도록 설정
(로그를 통해서 관리)
어플리케이션에서 사용하는 DB 사용자 계정의 권한을 최소한으로 설정
시스템 Table, View, Stored Procedure에 접근 권한을 제거하는 것이 필요
UNION Based SQL Injection과 같은 형태의 공격 예방 가능
4, 5번 방어 기법은 직접적인 방법이 아닌 공격이 심화, 확산되는 것을 방어하는 기법