SQL Injection 공격(Union, Error, Blind...)

SQL Injection

Injection(삽입)은 외부 입력값을 내부처리에 사용하는 경우, 외부 입력값 처리를 조작하는 문자열 포함 여부를 확인하지 않고 사용하는 경우 또는 원래 의도했던 처리가 변경되어 수행되는 것을 의미합니다.

=> 처리가 쿼리문을 만들고 실행하는 처리 : SQL Injection

=> XPath 또는 XQuery 구문을 이용해서 xml 문서를 조작하는 처리 : XPath 삽입, XQuery 삽입

=> LDAP 서버에 쿼리를 실행하는 처리 : LDAP 삽입

=> 운영체제 명령어를 실행하는 처리 : Command Injection(운영체제 명령어 삽입)

 

Injection(삽입) 취약점을 방어하기 위해 입력값을 검증 및 제한하여 외부에서 전달되는 값에 처리를 조작하는 문자열 포함여부를 확인하고 사용해야합니다.

=> 외부 값을 사용하지 않기

=> 안전하게 변경하여 사용(이스케이프 처리)

=> 실행될 구조를 미리 정의하고 정의한 구문에 입력값을 매핑하는 방식으로 처리

 

SQL Injection은 외부 입력값에 쿼리 조작 문자열 포함 여부를 확인하지 않고 쿼리문 생성 및 실행에 사용하는 경우, 쿼리의 구조와 의미가 변경되어 실행되는 것을 뜻합니다. 권한 밖의 데이터에 접근이 가능하고, DBMS 시스템의 제어권을 탈취할 수 있으며, 쿼리를 통해 제공할 기능을 우회 또는 오용이 가능합니다.

 

select * from member where id = 사용자 입력 값

=> 사용자가 입력한 ID와 일치하는 회원정보를 조회

 

1. 에러를 유발하는 입력 : Error Based SQL Injection

사용자 입력값으로 오류를 유발하는 값을 전달합니다. 생성되는 오류 메시지를 통해 정보를 수집하고 수집한 정보를 이용하여 추가 공격을 계획합니다.

ex) ' (홑따옴표)

select * from member where id = 1217'

=> "ID 컬럼 값으로 문자열을 사용할 수 없습니다." 라는 형식의 메시지가 출력되면, ID 컬럼의 타입은 number인 것을 알 수 있게 됩니다.

 

2. 항상 참이 되는 입력

쿼리문의 조건식의 결과가 항상 참이 되게 만드는 입력으로 권한 밖의 데이터에 접근하거나 조회할 수 있습니다.

ex) or

select * from member where id = 1217 or 1=1

=> 모든 회원 정보 조회 가능

 

3. UNION 구문 이용 : Union Based SQL Injection

원래 서비스를 통해 실행되는 쿼리 구문에 공격자가 알고자 하는 쿼리를 UNION 구문을 이용해서 결합하여 실행하게 되면, 기본 제공되는 정보와 함께 공격자가 알고자하는 정보가 함께 노출됩니다.

ex) union 구문

select * from member where id = 1217 

select * from member where id = 1217 and 1=2 UNION select 1,2,3,4 from 테이블명

=> (테이블명)의 1,2,3,4(공격자가 알고자하는 정보) 값이 조회되어 출력됩니다.

 

4. Stored Procedure를 호출하는 입력

DB에서 제공하는 Stored Procedure를 실행하는 구문을 입력값으로 전달해서 실행하는 것으로, DB의 제어권을 탈취하는것이 가능합니다.

ex) Stored Procedure 호출

select * from member where id = 1217; exec xp_cmdshell 'cmd.exe /c dir'

=> ; 쿼리문의 종결을 의미

=> exec Stored Procedure를 실행

=> xp_cmdshell MS-SQL에서 제공하는 시스템 Stored Procedure로, 매개변수로 전달된 값을 DBMS의 쉘에서 실행하고 그 결과를 반환

=> 'cmd.exe /c dir' 현재 디렉토리의 내용을 반환

 

5. Blind SQL Injection

쿼리 실행 결과에 따라서 서버의 반응이 달라지는 경우 공격자가 원하는 내용을 조회하는 쿼리를 작성해서 전달하고 실행 결과를 보면서 정보를 수집합니다.

ex)

[정상적인 실행]

select * from member where id = 1217

=> ID 값이 1217인 사용자 정보 조회

 

[공격 가능 여부 확인]

select * from member where id = 1217 and 1=1     => ID 값이 1217인 사용자 정보 조회

select * from member where id = 1217 and 1=2     => 정보 조회 불가

 

[공격자가 원하는 내용 전달]

select * from member where id = 1217 and 공격자가 알고자하는 내용

=> 사용자 정보가 제공되면 쿼리의 실행 결과가 참 / 에러 메세지가 제공되면 쿼리의 실행 결과가 거짓임을 알 수 있음