[DB] SQL Injection
SQL Injection은 웹 어플리케이션에서 데이터베이스와의 상호작용을 조작하여 공격자가 비정상적인 SQL 쿼리를 실행하도록 하는 보안 취약점이다.
해커에 의해 조작된 SQL 쿼리문이 데이터베이스에 그대로 전달되어 비정상적 명령을 실행시키는 공격 기법
공격을 통해 공격자는 민감한 정보를 조회하거나 조작할 수 있고, 심한 경우 시스템을 완전히 장악할 수도 있다.
공격 목적
- 정보 유출
- 저장된 데이터 유출 및 조작
- 원격 코드 실행
- 일부 DB의 경우 확장 프로시저를 이용하여 원격으로 시스템 명령을 실행할 수 있다.
- 시스템 명령 실행은 원격 자원 접근 및 데이터 유출, 삭제가 가능하다.
- 인증 우회
- 공격의 대표적인 경우는 로그인 폼에서 발생한다.
- 이때 상위 권한을 가진 사용자의 권한으로 인증 절차를 우회하여 로그인할 수 있다.
발생 조건
- 사용자로부터 받은 입력 값을 검증하지 않거나 escape 하지 않은 경우
- 동적으로 SQL 쿼리를 생성하고 사용하는 경우, 사용자의 입력값이 직접 쿼리에 삽입되면서 발생
- 사용자가 실행할 수 없는 쿼리를 실행하려고 하는 경우에 이를 불허하지 않아 실행하게 되면서 발생
공격 종류 및 방법
1. Classic SQLi
기본적인 SQL 인젝션으로 UNION, OR 등을 사용해 데이터를 유출하는 기법
(1) Error-based SQLi (인증 우회)
논리적 에러를 이용한 SQL 인젝션
ex. 로그인 상황에서 username과 비밀번호를 다음과 같은 쿼리로 입력받는다고 할 때
SELECT * FROM users WHERE username = '입력된_사용자명' AND password = '입력된_비밀번호';
사용자가 다음과 같이 입력한다면
'' OR '1'='1'; --
최종적으로 다음과 같은 SQL문이 실행된다.
SELECT * FROM users WHERE username = '' OR '1'='1'; --' AND password = '입력된_비밀번호';
- '1' = '1'
- where 절을 모두 참으로 만들고
- -- 을 넣음으로써 뒤의 구문을 모두 주석 처리
- 쿼리문 실행 결과
- User 테이블에 있는 모든 정보 조회
- 가장 먼저 만들어진 계정으로 로그인에 성공한다.
- 보통은 관리자 계정을 제일 처음 많듦
- 관리자 계정 탈취 → 관리자 권한을 통해 또 다른 2차 피해가 발생할 수 있다.
- 보통은 관리자 계정을 제일 처음 많듦
(2) Union-based SQLi
UNION : 합집합 - 두 개의 쿼리문에 대한 결과를 통합하여 하나의 테이블로 보여주는 키워드
- UNION Injection 성공 조건
- Union 하는 두 테이블의 칼럼 수가 같아야 한다.
- Union 하는 두 테이블의 데이터 형이 같아야 한다.
ex. 사용자의 아이디와 패스워드 확인
SELECT username, password FROM users WHERE id = '$id';
이때 '$id'에 다음과 같은 값을 입력한다면
$id: 1 UNION SELECT null, table_name FROM information_schema.tables --
최종적으로 다음과 같은 SQL 쿼리문이 실행된다.
SELECT username, password FROM users WHERE id = '1'
UNION
SELECT null, table_name FROM information_schema.tables --';
- UNION SELECT null, table_name FROM information_schema.tables
: 사용자 테이블 대신 information_schema.tables 에서 테이블 이름을 가져온다. - 위 쿼리문은 users 테이블과 information_schema.tables 테이블의 데이터를 결합하려는 시도를 한다.
- 이때 information_schema.tables 은 데이터베이스에 존재하는 모든 테이블의 목록을 저장하는 시스템 테이블이다.
- 따라서 쿼리문이 실행되면 사용자 테이블 대신 information_schema.tables 에서 테이블 이름을 가져와 두 개의 결과가 합쳐서 반환되고
- 공격자는 데이터베이스 내의 모든 테이블의 이름을 알아낼 수 있다.
- username과 password를 출력하는 곳에 데이터베이스의 테이블 이름이 표시되는 현상이 발생할 수 있고, 테이블 목록을 알게된 공격자는 민감한 데이터가 포함된 테이블을 찾아 공격을 진행할 수 있다.
2. Blind SQLi
(1) Boolean-based SQLi
SQL 쿼리의 참/거짓 기반으로 공격자가 DB 정보를 추출하는 기법
ex. 아이디가 '1'인 사용자의 비밀번호 길이 확인
SELECT username, password FROM users WHERE id = '$id';
공격자가 아이디가 '1'인 사용자의 비밀번호 길이를 확인하는 쿼리를 실행하려고 한다.
$id: 1' AND LENGTH(password) > 10 --
이 입력을 SQL 쿼리에 삽입하면 다음과 같이 된다.
SELECT username, password
FROM users
WHERE id = '1' AND LENGTH(password) > 10 --';
해당 값의 결과가 웹 페이지에 반영되면 공격자는 비밀번호의 길이를 추출할 수 있다. 이런 과정을 반복하여 결과들을 조합한다면 원하는 정보를 얻을 수 있다.
(2) Time-based SQLi
DB 서버의 응답 시간을 기반으로 공격자가 데이터베이스 정보를 추출하는 기법
ex. 아이디와 비밀번호 조회 코드
SELECT username, password FROM users WHERE id = '$id';
공격자가 아이디가 '1'인 사용자 비빌번호의 첫 번째 글짜가 'a'인지 확인하고자 한다.
$id: 1' AND SUBSTRING(password, 1, 1) = 'a' AND SLEEP(5) --
이 입력을 SQL 쿼리에 삽입하면 결과적으로 아래와 같이 변한다.
SELECT username, password
FROM users
WHERE id = '1' AND SUBSTRING(password, 1, 1) = 'a' AND SLEEP(5) --';
대응 방안
- 화이트리스트 기반 검증
- 허용되는 값의 목록을 작성하고, 입력 값이 이 목록에 속하는지 확인하는 방식
- 허용되지 않는 문자나 특수 문자를 입력으로 거부함으로써 공격을 방지할 수 있다.
- Prepared Statement 사용
- preparestatement를 사용하면, 특수문자를 자동으로 escaping 해준다.
- (statement와는 다르게 쿼리문에서 전달인자 값을 ?로 받는다.)
- 이를 활용해 서버 측에서 필터링 과정을 통해서 공격을 방어한다.
- 에러 메세지 최소화
- 웹 방화벽 사용
- 입력 값의 정규화
- 최소 권한 원칙
- 보안 업데이트
- 저장 프로시저 사용
- 사용하고자 하는 쿼리에 미리 형식을 지정하는 것을 의미한다.
- 지정된 형식이 데이터가 아니면 쿼리가 실행되지 않기 때문에 보안성이 크게 향상한다.
화이트 리스트 vs. 블랙 리스트
화이트 리스트
- 엑세스 허용 목록
- 기본적으로 모든 접근을 막고, 접근 허용 대상을 등록하는 방식
- 조직 내에서 신뢰할 수 있는 사람, 실행 파일, 응용 프로그램, 웹 사이트만 실행 가능하도록 허용
- 장점
- 엄격한 보안 체계를 구축할 수 있다
- 단점
- 보안 담당자의 업무량 증가 : 특정 업무 시스템의 접근 권한을 통제하면, 자신도 등록해달라는 요청 발생
블랙 리스트
- 엑세스 거부 목록
- 기본적으로 모든 접근을 허용하고, 접근하지 못하는 예외를 두는 방식
- 컴퓨터 보안에서 가장 오래된 알고리즘 중 하나
- 방화벽이나 백신 등에 사용하는 방식
- 장점
- 쉽고 빠른 보안 조치가 가능하다
- 담당자의 업무량 ↓
- 단점
- 거부하지 않는 출처로부터 엑세스가 있는 경우 막기 어렵다.
reference
https://github.com/jmxx219/CS-Study/blob/main/database/SQL%20Injection.md
CS-Study/database/SQL Injection.md at main · jmxx219/CS-Study
Computer Science && Tech Interview . Contribute to jmxx219/CS-Study development by creating an account on GitHub.
github.com
tech-interview-for-developer/Computer Science/Database/SQL Injection.md at master · gyoogle/tech-interview-for-developer
👶🏻 신입 개발자 전공 지식 & 기술 면접 백과사전 📖. Contribute to gyoogle/tech-interview-for-developer development by creating an account on GitHub.
github.com