[목 차]
1. SQL 인젝션
1.1 SQL 인젝션이란?
1.2 SQL 이란?
1.2.1 SQL 구문
1.2.1.1 데이터 정의 언어 (DDL)
1.2.1.2 데이터 조작 언어 (DML)
1.2.1.3 데이터 제어 언어 (DCL)
1.2.2 SQL Select
1.3 공격 방법
1.3.1 인증 우회
1.3.1.1 로그인 인증 우회
1.3.1.2 공격 기법 설명
1.3.2 데이터 노출(Data Disclosure)
1.3.2.1 Error based 방식
1.3.2.2 에러 유발
1.3.2.3 다른 컬럼 찾기
1.3.2.4 각 컬럼의 자료형(Datatype) 알아내기
1.4 결론
1. SQL 인젝션
1.1 SQL 인젝션이란?
SQL 인젝션은 웹 애플리케이션의 허점을 악용해 애플리케이션의 개발자가 예상하지 못했던 SQL 문장이 실행되게 함으로써 데이터베이스를 비정상적으로 조작하는 공격이다.
쉽게 말해 웹사이트 취약점을 찾아, DB를 관리하는 SQL 명령어에 악성코드를 삽입해 해커가 원하는 식으로 조작하는 웹 해킹 공격이다. 이를 통해 개발자가 의도하지 않은 SQL 명령을 실행해 DB를 비정상적으로 조작하고, 개발자도 모르게 DB에 저장한 정보를 유출할 수 있다.
[그림 1] 웹 공격 비중
2016년 4분기 기준으로, SQL 인젝션 공격은 웹 공격 전체 중 26%의 비중을 차지하고 있다.
1.2 SQL 이란?
SQL 인젝션에 대해 알아보기에 앞서, 먼저 SQL이 무엇인지 알아볼 것이다.
SQL은 관계형 데이터베이스 관리 시스템(RDBMS)의 데이터를 관리하기 위해 설계된 특수 목적의 프로그래밍 언어이다. 관계형 데이터베이스 관리 시스템에서 자료의 검색과 관리, 데이터베이스 스키마 생성과 수정, 데이터베이스 객체 접근 조정 관리를 위해 고안되었으며, 많은 수의 데이터베이스 관련 프로그램들이 SQL을 표준으로 채택하고 있다.
1.2.1 SQL 구문
SQL의 문법의 종류는 세가지가 존재한다.
1) 데이터 정의 언어 (DDL : Data Definition Language)
2) 데이터 조작 언어 (DML : Data Manipulation Language)
3) 데이터 제어 언어 (DCL : Data Control Language)
1.2.1.1 데이터 정의 언어 (DDL)
- CREATE (데이터베이스 개체의 정의)
- DROP(데이터베이스 개체 삭제)
- ALTER(데이터베이스 개체 정의 변경)
데이터 정의 언어는 테이블과 인덱스 구조를 관리한다.
※ 참고
- 테이블이란?
[그림 2] 테이블
쉽게 말해서 위 사진과 같은 표를 뜻함
- 인덱스란?
어떤 데이터가 어디에 있는지 위치 정보를 가진 주소록 (데이터들의 ROWID(위치 주소) 정보를 별도의 세그먼트에 넣어 저장하고 관리)
1.2.1.2 데이터 조작 언어 (DML)
- INSERT (삽입, 등록)
- UPDATE (업데이트, 수정)
- DELETE (삭제)
- SELECT (검색, 질의)
데이터 조작 언어는 데이터베이스 사용자 또는 응용 프로그램 소프트웨어가 컴퓨터 데이터베이스에 대해 데이터 검색, 등록, 삭제, 갱신을 위한 데이터베이스 언어이다.
1.2.1.3 데이터 제어 언어 (DCL)
- GRANT (특정 데이터베이스 사용자에게 특정 작업 수행 권한 부여)
- REVOKE (특정 데이터베이스 이용자에게 부여한 특정 권한을 박탈)
데이터 제어언어는 데이터베이스에서 데이터에 대한 액세스를 제어하기 위한 데이터베이스 언어이다.
1.2.2 SQL Select
SQL SELECT문은 하나 또는 그 이상의 테이블에서 데이터를 추출하는 SQL의 데이터 조작 언어(DML) 중 하나이다.
- WHERE : 어떤 열을 불러올지를 지정
- GROUP BY : 연산 함수가 각 그룹에 적용되도록 하기 위해 속성을 그룹 열에 공유하는 것
- HAVING : GROUP BY 절에서 정의된 그룹들 중에서 검색
- ORDER BT : 반환하는 열에 순서를 지정
SQL SELECT문의 예시는 다음과 같다.
구문 | 설명 |
SELECT * FROM My_Table | My_Table로부터 모든 칼럼 조회 |
SELECT No_Emp,Nm_Kor,Age FROM My_Table | My_Table의 No_Emp,Nm_Kor,Age 칼럼 조회 |
SELECT Nm_Kor,Age FROM My_Table WHERE Age=25 | 나이가 25살인 사원의 한국이름과 나이 조회 |
SELECT * FROM My_Talbe WHERE Nm_Kor LIKE '김%' | '김'으로 시작하는 사원 조회 |
SELECT * FROM My_Table WHERE Age IN(20,24,26) | 나이가 20살,24살,26살인 사원 조회 |
[표 1] SELECT 구문
1.3 공격 방법
1.3.1 인증 우회
아이디와 패스워드를 입력하는 로그인 페이지를 타겟으로 행해지는 공격이며, SQL 쿼리문의 TRUE/FALSE의 논리적 연산 오류를 이용하여 로그인 인증 쿼리문이 무조건 TRUE의 결과값이 나오게 하여 인증을 무력화시키는 기법이다.
1.3.1.1 로그인 인증 우회
[그림 3] 정상적인 로그인 인증과정
정상적인 과정은 사용자가 입력한 로그인 정보가 DB에 있다면 로그인이 인증되는 구조이다.
[그림 4] 비정상적인 로그인 인증과정
SQL 쿼리를 이용한 로그인 우회방법은 사용자가 ID와 PW 입력창에 SQL 쿼리 일부분을 적어서 DB에 처리 결과를 참으로 만들어 로그인이 한다.
1.3.1.2 공격 기법 설명
SQL 쿼리 입력만으로 어떻게 로그인 인증 우회가 가능할까?
[그림 5] ID, PW 입력
[그림 5]와 같은 로그인 인증 페이지 코드가 있다고 가정하자.
빨간 박스부분을 설명하면, 사용자가 입력한 ID(user_id)를 id라는 변수에 담고, 사용자가 입력한 PW(user_pw)를 password라는 변수에 담는다.
[그림 6] SQL 구문
위 부분을 설명하자면, member라는 테이블에서 user_id, user_pw, name, email, homepage의 필드를 출력하라는 뜻이며, [그림 5]를 통해 입력한 id, password에 담긴 값을 "&id", "&password"로 호출하여 where부분을 완성시킨다.
id = cert, password = 1234라는 값이 대입되어 있다면, where user_id = 'cert' and user_pw='1234'라는 구문으로 표현되는 것이다.
위의 코드를 정리하면 user_id='cert' and user='1234'의 조건을 만족하는 member 테이블에서 user_id, user_pw, name, email, homepage의 필드 값을 출력하라는 뜻이며, 만일 사용자가 입력한 ID/PW가 없다면 로그인에 실패할 것이고, where 조건이 참이 되기만 한다면 로그인에 성공할 것이다.
[그림 4]에서 ID 입력창에 ' or '1' = '1' -- 을 입력한 후 PW 입력창에 아무거나 입력한 이유는 where 조건을 참으로 만들기 때문이다.
로그인 인증 페이지에 select 조건인
where user_id='"&id"' and user_pw='"&password"' |
[표 2] select 조건
에 사용자가 입력한 값이 대입된다.
"&id" => 'or '1' = '1' --
"&password" => any
where user_id='' or '1' -- and user_pw='any'
user_id = '' or '1'='1' | -- and user_pw='any' |
or이기 때문에 ‘’, ‘1’=‘1’ 둘 중 하나만 만족하면 참이 된다. ‘1’=‘1’은 참이기 때문에 user_id 는 조건에 참이 된다, | --은 한 줄짜리 주석을 뜻하며, 해당 부분은 주석처리가 된 것이기 때문에 where 조건에서는 무시된다. |
[표 3] 대입
[표 3]을 통해서 알 수 있듯이, 결국 where 조건이 참이 되었기 때문에 로그인에 성공하게 된다.
1.3.2 데이터 노출(Data Disclosure)
타겟 시스템의 주요 데이터 절취를 목적으로 하는 방식이며, Error based, Union based, Blind based, Time bsed 방식이 있다. 해당 공격 기법은 웹사이트에서 Database의 에러 정보를 확인할 수 있는지 유무에 따라 공격방식이 결정된다. 이번 장에서는 Error based 방식만을 서술할 것이며, 다른 공격방식에 대해서는 참고문헌의 링크를 참고하길 바란다.
공격방식을 결정하기에 앞서 공통적으로 반드시 필요한 것은 공격 가능한 포인트를 찾는 것이 우선이다. 웹사이트는 사용자와의 상호작용을 위해 사용자의 입력 혹은 사용자의 특정 행위에 따라 URL상의 파라미터로 특정 값이 전달되어
뒷단에 있는 Database에 질의를 던지고, 그에 따른 적절한 결과를 사용자에게 제공한다.
(HTTP 메소드가 GET방식인 경우)
우선, URL주소의 파라미터를 받는 부분이나 폼 입력칸 같은 Database와 직접적으로 연결되어 있는 부분을 찾아야 한다. 예를 들자면 아래 URL주소에서 product_id란 파라미터에 114라는 값이 설정되어있는 부분이다.
www.example.com/?product_id=114
예시에서 설명할 사이트는 MSSQL Database를 사용한다고 가정할 것이다.
1.3.2.1 Error based 방식
Dababase의 에러 메세지를 기반으로 한 공격이며, SQL 구문 중 group by 와 having 구문을 사용하여 일부로 에러를 유발시켜 에러 정보를 바탕으로 Database명이나 Table, Column, 궁극적으로 Data를 절취하는 것이 가능하다. 주로 MSSQL Databse를 사용하는 웹사이트에 사용되는 기법이나, Oracle, MySQL에서도 통하는 기법이다.
www.example.com/?idx=1 |
[표 4] 공격 포인트
시작에 앞서, [표 4]와 같은 공격 포인트를 찾았다고 가정한다.
1.3.2.2 에러 유발
SQL구문에도 반드시 함께 써야할 구문들이 있다. 위에서 소개했듯이 group by와 having 구문이 바로 그것이다.
having은 group by가 사용된 SQL문에서 필터링이나 어떤 조건을 줄 때 사용하는 구문으로 반드시 group by와 함께 사용해야 한다.
이 점을 이용하여 group by없이 having을 사용하여 일부로 에러를 유발시킨다.
www.example.com/?idx=1' having 1=1-- |
[표 5] having 에러 유발
위 URL을 실행하면 당연히 에러가 난다. 이 에러가 웹페이지에 보여 지느냐가 관건인데, 이번 글에서는 보여 진다고 가정할 것이다.
Microsoft OLE DB Provider for SQL Server (0x80040E14) 'member.idx' 열이 집계 함수에 없고 GROUP BY 절이 없으므로 SELECT 목록에서 사용할 수 없습니다. |
[표 6] 에러 메시지
[표 6]와 같은 에러가 발생했다. 이 에러 정보로 무엇을 파악할 수 있는 것은 member.idx 열이 집계 함수에 없으며, 현재 쿼리에서 사용되는 테이블은 member이고, 첫번째 컬럼은 idx이라는 정보이다.
1.3.2.3 다른 컬럼 찾기
첫번째 컬럼이 idx인 것을 알아냈다면, 이를 이용하여 다른 컬럼의 이름들도 알아낼 수 있다.
www.example.com/?idx=1' group by idx having 1=1-- |
[표 7] 두 번째 컬럼
이번에는 group by 와 having을 함께 쓸 것이다. 대신 group by 에는 이미 알아낸 첫 번째 컬럼인 idx를 집계하는 컬럼으로 사용해야 한다.
이번에는 [표 8]과 같은 에러가 발생했다.
Microsoft OLE DB Provider for SQL Server (0x80040E14) 'member.bId' 열이 집계 함수에 없고 GROUP BY 절이 없으므로 SELECT 목록에서 사용할 수 없습니다. |
[표 8] 에러 메시지
[표 8]을 통해 알 수 있듯이, 두 번째 컬럼은 bId이다.
www.example.com/?idx=1' group by idx, bId having 1=1-- |
[표 9] 세 번째 컬럼
세번째 컬럼을 알아내기 위해서는 쿼리를 [표 9]와 같이 조작하여 실행하면 될 것이다.
계속해서 알아낸 컬럼 명을 group by절에 추가하여 순차적으로 컬럼 명을 알아갈 수 있다.
이를 계속 반복하다가 더 이상 에러가 발생하지 않고 정상적인 페이지가 보인다면 모든 컬럼 명을 알아낸 것으로 판단할 수 있다.
1.3.2.4 각 컬럼의 자료형(Datatype) 알아내기
모든 컬럼명을 알아냈다면 각 컬럼의 자료형을 알아내보자. 이 때 사용되는 대표적인 SQL 함수로는 sum(컬럼)이 있다.
sum(컬럼)은 말그대로 지정된 컬럼의 값을 모두 합하는 함수이다. 컬럼은 숫자 형이어야 하고, 숫자 형이 아닌 자료형의 컬럼을 지정하게 되면 에러가 발생한다.
해당 에러가 발생하면 지정된 컬럼 명의 자료형이 무엇인지 나오기 때문에 각 컬럼의 자료형을 파악할 수 있다.
1.4 결론
이번 글에서는 SQL 인젝션이 무엇이며, SQL 구문에는 어떠한 것들이 있고, 이를 통해 로그인 인증 우회 및 DB내 컬럼 명과 자료형을 알아내는 방법을 배웠다. 실제 SQL 인젝션 공격에는 더욱더 다양한 기법들이 존재하며, 위에 언급한 것들은 아주 기초적인 지식들만 나열한 것이다. 위에 서술된 내용을 통해 SQL 인젝션을 이해하는데 조금이나마 도움이 되었으면 한다.
[참고 문헌]
[1] https://blog.naver.com/shackerz/220424695783
[3] http://mrrootable.tistory.com/25
[4] https://blog.lael.be/post/55
'Security > Study' 카테고리의 다른 글
2018.12.24 야간 보안 공부 - NAT (0) | 2018.12.23 |
---|---|
2018.12.20 야간 보안 공부 - VPN (0) | 2018.12.21 |
181217 공부일지 (0) | 2018.12.18 |
181205 공부일지 (0) | 2018.12.05 |
카테고리 설명 (0) | 2018.12.05 |