Hongfluenza

SQL 인젝션 본문

STUDY/WEB

SQL 인젝션

Hongfluenza 2019. 7. 13. 17:12

1> SQL 인젝션?

1.1> SQL(Structured Query Launguage)

 

- 데이터베이스(DB)를 만들고 유지하는 데 사용하는 프로그래밍 언어 중 하나.

- DB를 구축하고 조작하기 위해 사용하는 일종의 명령어.

- SQL을 이용해 데이터 정의·조작·제어 가능

 

 

1.2> Injection

 

애플리케이션에서 서버로 전달되는 명령, 쿼리, 스크립트 등의 값을 변조하여 비정상적인 방법으로 시스템에 접근하는 공격기법

- 웹 애플리케이션에만 국한되지 않고 DB와 연결된 모든 애플리케이션에서 고려해볼 수 있는 공격 기법

- 특징 : 파라미터, 쿠키, 내·외부 웹 서비스 등 거의 모든 데이터가 인젝션 공격 대상이 된다.

 

 

1.3> SQL Injection

 

- 입력창에 정상적인 값(데이터)을 입력하는 것이 아닌, SQL Query문의 일부분을 입력하면서 DB에서 처리가 되도록 하는 것

- DB에 처리되는 결과에 따라 로그인 우회·데이터 접근·수정·삭제 등을 할 수 있음

- 불법 로그인·DB 데이터 추출·시스템 명령 등의 수행 가능

- 다양한 종류의 SQL 공격 기법이 존재함 > Blind SQL 인젝션, 에러 기반 SQL 인젝션, Union SQL 인젝션 등 …

 

 


 

2> 형태에 따른 SQL 인젝션 분류

2.1> 논리적 에러를 이용하는 SQL Injection

 

- SQL 인젝션의 기본적인 기법

- ' 기호를 통해 에러 확인, or 1=1 등의 논리적인 에러를 통해 시스템 권한 체크를 우회하는 기법

SELECT * FROM Users WHERE Username='$username' AND Password='$password

외부에서 입력될 수 있는 계정($username)과 암호($password)에 참 조건(or 1=1)을 수행하는 문장을 삽입하여 계정과 암호 없이도 로그인 우회가 가능하다.

SELECT * FROM Users WHERE Username='1'or'1'='1' or '1' AND Password='1' or '1'='1'

 

 

or 1=1
or 1=1--
or 1=1#
or 1=1/*
admin'-- (※ 여기서 admin문자열 대신 test 또는 이미 존재할 것으로 추정되는 문자열로 대체해서도 시도 해보아야 한다.)
admin' #
admin' /*
admin' or '1'='1'
admin' or '1'='1'--
admin' or '1'='1'#
admin' or '1'='1'/*
admin') or ('1'='1
admin') or ('1'='1'--
admin') or ('1'='1'#
admin') or ('1'='1'/*
admin') or '1'='1
admin') or '1'='1'--
admin') or '1'='1'#
admin') or '1'='1'/*
admin" --
admin" #
admin" /*
admin" or "1"="1
admin" or "1"="1"--
admin" or "1"="1'#
admin" or "1"="1'/*
admin" or 1=1 or""="
admin" or 1=1
admin" or 1=1--
admin" or 1=1#
admin" or 1=1/*
admin") or ("1"="1
admin") or ("1"="1"--
admin") or ("1"="1"#
admin") or ("1"="1"/*
admin") or "1"="1
admin") or "1"="1"--
admin") or "1"="1"#
admin") or "1"="1"/*

 

 

2.2> 쿼리 가능 여부를 이용하는 Blind SQL Injection

 

- 악의적인 문자열 삽입 대신 쿼리 결과(참 또는 거짓)에 따라 정보를 취득하는 방법

- 에러가 발생되지 않는 사이트에서 에러를 기반으로 하는 공격 기법들을 사용할 수가 없기 때문에 공격을 통해 정상적인 쿼리가 수행되는지 혹은 쿼리가 수행되지 않아 쿼리 결과가 없는지를 통해 판단할 수 있기 때문에 사용한다.

http://www.xxx.com/page.php?id=5 and 1=1 (참 조건)

id=5 다음에 and 1=1을 삽입하였고 이는 where id=5 and 1=1로 처리될 것이다.

id=5(참) and 1=1(참)이기 대문에 page.php?id=5 입력한 것과 동일한 결과 페이지가 제공 될 것이다.

 

http://www.xxx.com/page.php?id=5 and 1=2 (거짓 조건)

그러나 and 1=2를 삽입한 경우, 

id=5(참)와 1=2(거짓)의 거짓조건으로 인해 정상적인 쿼리가 수행되지 않아 화면에 결과가 출력되지 않을 것이다.

 

※ POST 형식으로 전달된 데이터에도 Blind SQL 인젝션 공격을 수행할 수 있다.

Searchbrand=nike&up_type=like 와 같은 형태로 서버나 파라미터 값이 전달되는 경우가 있다고 하자.
이 때, post 방식의 body 부분의 데이터를 SearchBrand=nike'+and+'1'='1&up_type=like로 변경한 후, response 값을 보고 취약점 존재 여부를 확인할 수 있다.

참일 경우의 response body 값 : {"message":"검색 완료","status":"SUCCESS"}
거짓일 경우의 response body 값 : {"message":"","status":""}
반대로 거짓 DB쿼리('+and+'1'='2)를 입력하면, 거짓 response body 값을 얻을 것이다. 취약점이 확인되면 blind 인젝션 툴을 이용하여 공격을 수행할 수 있다.

 

 

2.3> 두 개 이상의 쿼리를 이용하는 Union SQL Injection

 

-Union은 두 개 이상의 쿼리를 요청하여 결과를 얻는 SQL연산자

-공격자는 이를 악용하여 원래의 요청에 한 개의 쿼리를 삽입하여 정보를 얻어내는 방식이다.

 

http://www.site.com/news.php?id=5 union all select 1,table_name,3 from information_schema.tables

information_schema.tables에서 테이블 정보를 요청하여 정보를 얻으려는 시도이다.

 

 

Union SQL Injection 사용 이유?

→ 에러가 발생하지 않는 사이트에서 다른 기법(에러 노출을 시작으로 하는)을 사용할 수가 없기 때문에 공격을 통해 정상적인 쿼리가 수행되는지 혹은 쿼리가 수행되지 않아 쿼리 결과가 없는지를 통해 판단 가능

 

 

2.4> 저장 프로시저를 사용하는 Stored Procedure SQL Injection(확장형 저장 프로시저 종류 검색)

 

- 저장 프로시저는 운영상 편이를 위해 만들어준 SQL 모음집 형태로 이해하면 됨.

- 특히 MS SQL에서 사용할 수 있는 xp_cmdshell은 윈도우 명령어를 실행하도록 역할을 제공하는 대표적인 저장 프로시저.

- 확장 프로시저(master,xp_cmdshell,xp_startmail,xp_sendmail 등)는 운영체제 명령 실행 및 SQL 인젝션에 이용되기 때문에 제거하는 것이 안전하다.

- 저장 프로시저의 역할

: 저장 프로시저(Stored Procedure)는 일련의 쿼리를 마치 하나의 함수처럼 실행하기 위한 쿼리의 집합이다. 이는 일반적인 쿼리 문장을 사용하는 것보다 성능상의 이점을 제공받을 수 있다.
일반적인 쿼리 문장은 네트워크를 통해 DB 서버와의 연결을 수행하는데, 이는 쿼리 문장 길이에 따라 전송 시간이 길어질 수 있으므로 저장 프로시저 이름과 필요한 몇몇 변수만을 DB서버에 전송하면 추가적인 리소스 소모를 최소화 할 수 있다.

 

http://www.site.com/member/checkid.asp?id=';CREATE.....r.dbo.xp_cmdshell%20'netstat%20-an';

 

 

2.5> 타임기반의 Blind SQL Injection

 

- 쿼리 결과를 특정시간만큼 지연시키는 방법을 이용하는 기법

- 에러가 발생되지 않는 조건에서 사용할 수 있는 기법

 

http://testphp.vulnweb.com/listproducts.php?cat=1 AND SLEEP(5)

MYSQL에서 SLEEP()함수를 이용하여 5초 후에 쿼리 결과를 얻도록 공격문자열을 삽입하였다.
만약 5초 후에 쿼리 결과가 화면에 출력된다면 취약점이 있다고 판단할 수 있을 것이며, 데이터베이스가 MYSQL이라고 추측해 볼 수 있을 것이다.

 

 

3> 점검 방법에 따른 SQL 인젝션 분류

3.1> 사용자 인증 우회 점검

 

- 홈페이지의 로그인 폼의 입력 값에 대한 점검

- 보통은 ID와 PW를 입력하는 로그인 페이지를 타켓으로 행해지는 공격

- SQL 쿼리문의 TRUE / FALSE의 논리적 연산 오류를 이용하여 로그인 인증 쿼리문이 무조건 TRUE의 결과값이 나오게 하여 인증을 무력화시키는 기법

 

'or 1=1--
'or 1=1# (MySQL일때)
'or'dog'='dog'--
'or'ab'='a'+'b'--
'or 2>1--

인증우회를 위한 공격 쿼리 패턴들은 다음과 같다.
쿼리의 결과를 무조건 참(TRUE)로 만들 수 있는 쿼리라면 무엇이든 그 패턴이 될 수 있다.

 

 

3.2> 에러 기반의 점검

 

- 에러 기반 점검은 문자열 검색을 통해 에러 페이지를 출력하게 하고, 해당 페이지를 통해 DB 종류, 데이터 등의 정보를 습득하는 점검 방식

- 검색창에 싱글쿼터('), 더블쿼터("), #, --, /*, 'and 1='a'(불가능한 연산)을 입력하여 에러 발생 여부를 판단하게 한다.

group by와 having 구문을 사용하여 에러를 유발하여 에러 정보를 바탕으로 DB명이나 table, column, 궁극적으로 data를 획득할 수 있다.

 

 

3.3> 문자열 데이터 기반의 점검 (연결 연산자를 활용한 점검)

 

- 각각의 데이터베이스는 종류에 따라 연결 연산자를 갖고 있는데 이 점검은 다음과 같은 연결 연산자를 활용하여 SQL Injection 취약점 점검을 진행한다.

데이터베이스 종류 연결 연산자
oracle ||
MS-SQL +
My-SQL "

+) 추가적으로 ' 는 문자 데이터 구분 기호, ;는 쿼리 구분 기호, /* */는 주석이다.

 

만약 개인정보 수정 페이지에서
test@gamil.com으로 되어 있는 메일주소를 te'+'st@gamil.com으로 수정해도, 다시 개인정보 확인 페이지에서 조회했을 때 test@gmail.com로 변경되어 있다면 문자열 기반 SQL 인젝션 공격에 노출되어 있다는 것이다.

 

 

3.4> 정수 데이터 기반의 점검

 

- 정수 데이터를 입력하는 부분에서 단순 값과 산술 연산자를 통한 연산 값이 이와 같은 결과를 내는지에 대해 점검한다.

xxx.xxx.xxx.xxx/test?list=1
xxx.xxx.xxx.xxx/test?list=2-1

위의 두 url의 결과가 동일하면 정수 기반의 인젝션 공격에 노출된 것이다.

 

 

3.5> 응답 기반의 점검

 

xxx.xxx.xxx.xxx/test?list=6+and+1=1--

위와 같이 url 끝부분에 and 1=1--를 추가했을 때(+는 자동으로 추가됨) 응답 기반 취약점이 존재한다면 and 이후의 참/거짓 여부에 따라 정상/에러 페이지가 결정된다.

 

<DBMS 종류에 따른 코멘트>

MSSQL --
ORACLE --
MySQL #
MS Access  

 

 

4>대응 방안

4.1> 문자열 필터링 및 길이 제한

 

- DB와 연동하는 스크립트의 모든 파라미터를 점검하여 사용자의 입력 값에 이용되는 특수문자

(', ", \, ;, :, %, space, --, # 등) 및 SQL 관련 문자열(select, union, insert, delete, update 등)을 필터링한다.

- 또한, 문자열의 길이를 제한하고, 숫자는 숫자인지 점검하는 함수를 사용한다.

 

4.2> 확장 프로시저 제거

 

- MS-SQL의 경우 확장 프로시저(master, xp_cmdshell, xp_sendmail 등)는 운영체제 명령 실행 및 SQL 인젝션에 이용되기 때문에 제거하는 것이 안전하다.

 

4.3> DB 사용자 권한 제한

- 웹 프로그램을 사용하는 DB 사용자의 권한을 제한한다.

 

4.4> 선처리 질의문(Prepared Statement) 이용

- 선처리 질의문을 이용하면 SQL 쿼리문을 선처리하여 이후 입력되는 변수 값을 항상 문자열 변수로 다루기 때문에 사용자가 악의적인 SQL 구문을 삽입하더라도 SQL문에 영향을 미치지 않아 SQL 인젝션이 발생하지 않는다.

 

4.5> hash function 사용

- 사용자의 입력값을 DB 그대로 저장하고 사용하지 않아야 한다. 특히 비밀번호의 경우가 그렇다. 무조건 SHA-256 이상의 보안성을 갖는 해시함수로 해싱한 뒤에 저장해야 한다.

 

 

 

...더보기