1. SQL injection 이란?

1)

-코드 인젝션의 한 기법으로 클라이언트의 입력값을 조작하여 서버의 데이터베이스를 공격할 수 있는 공격방식

-SQL 구문을 임의로 삽입하여 기존 쿼리문을 변조, 인가되지 않은 데이터 열람 등을 수행할 수 있는 취약점

- SQL 삽입, SQL 주입으로도 불린다.



2) SQL injection에 주로 사용되는 문자열

문자열

설명

'

 문자 데이터 구분 기호 

 ; 

쿼리 구분 기호

-- , #

해당 라인 주석 구분 기호

-- Oracle, MSSQL

# MySQL 

 /* */

 /* 와 */  사이 구문 주석

 ||

문자 연결 ( Oracle에만 해당 ) 




3)

SQL injection을 크게 두 종류로 본다면 Numeric injection과 String injection으로 나뉜다.


3-1) Numeric Injection

- SQL injection 취약점이 존재하는 입력의 형태가 정수일 때의 injection이다.

정수의 타입으로 입력하기 때문에 String과 달리 작은 따옴표(')가 없다.


EX) select * from u_table where no=1 union select * from u_table

* 띄어쓰기를 할 수 있어야 추가적인 명령을 할 수 있다.

( 만약 코드 상에 trim()이나 공백을 지워주는 함수가 있다면 불가능하다. )


3-2 )String Injection

- Injection 취약점이 존재하는 입력의 형태가 문자일 때의 Injection이다.

입력하는 것이 작은따옴표(') 안으로 들어가기 때문에 Numeric Injection처럼 바로 명령을 이어 붙이지는 못하나

' 따옴표를 사용해 문자열을 잘라주면 된다.




2. SQL injection 공격 종류

1) 데이터베이스 구조 파악

데이터베이스의 오류를 낼 수 있는 SQL query를 입력하여 데이터베이스의 오류 결과를 분석하면 구조를 파악할 수 있다.

테이블명, 필드명,레코드 값 등을 파악할 수 있다.


2) Blind SQL injection

웹 서버에서 SQL injection을 방어하기 위해 데이터베이스의 오류 메시지를 출력하지 않도록 설정하는데

이때 오류 메시지를 보지않고 injection 공격을 한다고 해서 Blind injection으로 불린다.

오류 메시지가 출력되지 않기 때문에 참과 거짓만으로 공격하여 참으로 처리되는 값들만 파악하는 기법이다.


3) Stored Procedure SQL injection

보안상 취약한 프로시저를 이용하여 쉘을 수행, query 결과를 html로 제공, 레지스트리 조작, 서비스 시작 및 중지, 시스템 정보 획득 등

시스템 상에 공격하는 것이다.


4) Union SQL injection

2개 이상의 query를 요청하여 결과를 얻는 UNION 이라는 SQL 연산자를 이용한 SQL injection 공격을 말하며 공격자는 이 연산자를 이용하여 원래의 요청에 한 개의 추가 쿼리를 삽입하여 정보를 알아낼 수 있다.

하지만 컬럼의 갯수가 같아야 하고, 데이터 형식도 같아야 한다.



3. 예시

1) Login



(아래 내용은 위 사진과 일치하지 않습니다.)


로그인 폼에선 사용자가 값을 입력하면 데이터베이스를 조회하여 데이터와 일치할 때 로그인을 할 수 있다.

이때 데이터베이스에 값을 조회하기 위해 사용되는 언어를 SQL이라고 하며

일반적인 형태는 다음과 같다.


SELECT user FROM user_table WHERE id='입력한 아이디' AND password='입력한 비밀번호';


사용자의 id가 guest이고 password가 asdf1234이면 


SELECT user FROM user_table WHERE id='guest' and password='asdf1234'; 가 될 것이다.


sql injection으로 비밀번호에 ' or  '1' = '1 을 넣으면


SELECT user FROM user_table WHERE id='admin' and password=' ' or '1' = '1'; 이 되고,

 

AND연산은 OR보다 연산의 우선순위가 빠르기 때문에 위 구문 전체가 true가 되어 올바른 값으로 판단하게 된다.

즉,  ' or '1' = '1'' 구문 때문에 입력받은 id와 password가 데이터베이스와 일치하지 않아도 로그인을 할 수 있다.



또, id 부분에 주석을 넣어서 id = guest 이후 부분을 다 생략해버리면 password을 입력하지 않아도 로그인이 될 가능성도 있다.


SELECT user FROM user_table WHERE id='guest'-- and password='';








4. 방어 방법

- 유저에게 받은 값을 직접 SQL로 넘기지 않는다.

- 정규 표현식을 사용하여 적법한 입력 외에는 거부한다

- query 빌드 시 문자열 연결이 아닌 매개변수 query를 사용한다. -> 저장 프로시저 사용

- 최소 권한 계정으로 데이터 베이스에 연결하게 한다.

- 데이터베이스 연결 문자열을 가급석 config 파일에 저장하지 않는다 + 암호화

- 데이터베이스에 유저별로 접근 권한과 사용 가능한 명령어를 설정하면 피해를 최소화 할 수 있다.

- 클라이언트 측 자바스크립트로 폼 입력값을 한 번 검증하고, 서버측은 클라이언트 측 필터가 없다고 가정한 뒤 한번 더 입력값을 필터링한다.

- 공격자에게 너무 많은 오류 정보를 노출하지 않는다



+ Recent posts