SQL INJECTION

세렌디·2023년 4월 26일
0

정보보안

목록 보기
5/11
post-thumbnail

What is SQL INJECTION?

SQL Injection 은 공격자가 웹 양식을 통한 작업 요청 형태로 SQL를 웹/앱에 직접 제공하여 백엔드 데이터베이스 및/또는 앱 데이터에 액세스할 수 있는 보안 공격을 말합니다.
그러니까 간단하게 말하자면, 악의적인 사용자가 웹 어플리케이션의 입력 폼에 악성 SQL 쿼리를 삽입하여, 데이터베이스에 대한 비인가된 접근 및 조작을 시도하는 공격 기법이다.
한마디로, 해킹이라고 보면 편할 듯 하다.

Purpose?

SQL INJECTION을 하는 목적은 여러가지 겠지만, 대표적으로 4개라고 생각한다.

1. 정보 유출(Information Leakage)

2. 저장된 데이터 유출 및 조작(Disclosure & Manipulation of stored Data)

3. 원격 코드 실행(Remote Code Excution)

4. 인증 우회(Bypassing authorisation controls)

피해 사례

1. 2017년 3월 발생한 "여기어때" 고객 정보 및 고객 투숙 정보 노출 사고

2. 2015년 "뽐뿌" 개인정보 노출 사고가 SQL Injection 공격이 원인

원인?

공격의 핵심은 클라이언트 측에서 SQL 쿼리에 신뢰할 수 없는 데이터가
입력되었을 때, 데이터가 쿼리 로직의 일부로 해석되어 DB에서 실행될 때
발생한 것이라고 한다.

공격 방식

1. Classic SQL Injection (Union-based SQLi, Error-based SQLi)

SQL 에서 Union 키워드는 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드 이다. 정상적인 쿼리문에 Union 키워드를 사용하여 인젝션에 성공하면, 원하는 쿼리문을 실행할 수 있게 된다. Union Injection을 성공하기 위해서는 두 가지의 조건이 있는데, 하나는 Union 하는 두 테이블의 컬럼 수가 같아야 하고, 데이터 형이 같아야 한다.

예시 데이터베이스 테이블 "users"가 다음과 같다고 가정해봅시다.

SELECT * FROM users WHERE id='input_id' AND password='$input_password'

보안 취약점이 있는 로그인 페이지에서 사용자가 입력한 값을 다음과 같이 SQL 쿼리에 삽입하는 경우,

SELECT * FROM users WHERE id='' OR '1'='1' --' AND password='' OR '1'='1' --

이 쿼리는 id와 password가 입력값과 상관없이 '1'='1' 이 참(true)인 모든 레코드를 반환하게 된다. 즉, 공격자는 아이디와 패스워드를 모르더라도 로그인을 성공시킬 수 있게 된다는 것이다.

2. Blind SQL Injection (Boolean-based SQLi, Time-based SQLi)

아래와 같은 테이블이 있다고 가정해봅시다.

로그인 페이지에서 사용자가 입력한 아이디와 패스워드를 다음과 같이 SQL 쿼리에 삽입하는 경우에는,

SELECT * FROM users WHERE id='input_id' AND password='$input_password'

다음과 같이 INJECTION을 시도할 수 있다.

SELECT * FROM users WHERE id='1' OR 1=1 --' AND password='foobar'

이 쿼리는 id가 '1'이거나 1=1(항상 참)인 모든 레코드를 반환하게 된다. 따라서, 공격자는 아이디를 모르더라도 로그인을 성공시킬 수 있게 된다.
Boolean-based SQL Injection은 주로 WHERE 절에 사용되는 불리언 연산자 (AND, OR, NOT) 및 비교 연산자 (=, <, >)를 이용하여 SQL Injection을 시도한다.

3. Out of band SQL Injection

시스템 외부로 데이터를 전송하여 공격자가 해당 데이터를 수집하는 방식으로, 쿼리 결과가 네트워크 트래픽, DNS 등의 채널을 통해 전송된다. 이 방식은 시스템 내부에 접근할 수 없는 경우, 외부적인 수집 방법으로 정보를 수집할 때 유용하다.

앞에 했던 예제들과 같은

테이블이 있다고 가정할 때,

사용자가 로그인 할 때 다음과 같이 SQL 쿼리에 삽입하는 경우,

SELECT * FROM users WHERE id='inputidANDpassword=input_id' AND password='input_password'

다음과 같이 INJECTION을 시도할 수 있다.

SELECT * FROM users WHERE id='1'; SELECT pg_sleep(10)--' AND password='foobar'

이 쿼리는 id가 '1'인 레코드를 반환하면서, pg_sleep 함수를 이용하여 10초간 대기한다. 이 때, 시스템 외부로 네트워크 트래픽이 발생하게 되어 공격자는 이를 수집하여 SQL Injection을 성공시킬 수 있는 것이다.
Out-of-band SQL Injection은 보통 UNION-based나 Blind SQL Injection과 함께 사용된다고 한다.

profile
당당하게 자신을 개발자라고 할 수 있는 사람이 될 때 까지

0개의 댓글