newprog

SQL Injection의 유형 알아보기 본문

보안

SQL Injection의 유형 알아보기

newprog 2016. 10. 22. 06:00

오늘은 SQL Injection 유형들을 살펴보겠다.


본 포스트는 책 - [웹 모의해킹 및 시큐어코딩 진단가이드]를 참고하였다.

웹 모의해킹 및 시큐어코딩 진단가이드

저자 최경철, 김태한

출판 SECUBOOK

발매 2014.04.07.




​1. 논리적 에러를 이용하는 SQL Injection​

에러가 발생되는 사이트(즉, 에러의 내용이 사용자에게 보이는 사이트)에서 에러정보를 이용하여 데이터베이스 및 쿼리 구조 등의 정보를 추측할 수 있다.

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

위의 $username 부분과 $password 부분에 참 조건을 수행하는 문장을 삽입하여 계정과 암호 없이도 우회 가능하다.

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


'1' OR '1' = '1' 뿐만 아니라 다양한 패턴을 사용할 수 있다.

or 1=1 or 1=1-- or 1=1# or 1=1/* admin' -- admin' # admin' or '1'='1

이 밖에도 다양한 패턴들이 있다.


2. 두 개 이상의 쿼리를 이용하는 Union SQL Injection

알다시피 UNION은 2개 이상의 쿼리를 요청하여 결과를 얻는 SQL 연산자이다. 공격자는 이를 악용하여 원래의 요청에 한 개의 추가 쿼리를 삽입하여 정보를 얻어내는 방식이다.

아래 예제는 id=5라는 1개의 쿼리와 테이블 정보가 들어있는 information_schema.tables를 얻어내려는 추가 쿼리가 합쳐진 공격패턴이다.

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



3. 쿼리 가능 여부를 이용하는 Blind SQL Injection


에러정보가 나오면 쉽겠지만 에러정보를 가리는 사이트들은 이와 같은 방법을 사용한다.
악의적인 문자열 삽입 대신 쿼리 결과(참 혹은 거짓)에 따라 정보를 취득하게 된다.

아래 예제는 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=1


그러나 and 1=2를 삽입하면 id=5(참)과 1=2(거짓)으로 인해 정상적인 쿼리가 수행되지 않아 화면에 결과가 출력되지 않을 것이다.

http://www.xxx.com/page.php?id=5 and 1=2


정상적인 쿼리가 수행되지 않아 화면에 결과가 출력되지 않는다는 말에 주목하여야 한다.

자, id=5 부분을 1=2 부분을  라고 해보자.

화면에 정상적인 결과가 출력된다는 말은 전 후 모두 참이라는 소리이다.

그런데 만약 후 부분에 참일지 아닐지 모르는 문장을 삽입해보자.

예를 들어 테이블에 있는 필드의 개수를 모른다고 할 때.

이 상태에서 UNION 을 사용해서 NULL을 계속 추가하면 언젠가 필드의 개수에 딱 들어맞는 NULL 개수를 추가하게 되지 않겠는가?

여러가지 조건을 시도해보다가 갑자기 화면이 출력이 된다면,

그 상태가 바로 쿼리 내에서 인 상태인 것이다.


4. 에러 기반의 SQL Injection


GET, POST 요청필드, HTTP헤더 값, 쿠키값 등에
특수문자(싱글쿼트(') 혹은 세미콜론(;)) 삽입시, SQL 에러가 발생된다면 취약점이 있다고 판단할 수 있다.

먼저, 출력되는 에러의 형태로 데이터베이스의 종류를 추측할 수가 있다.

대표적으로 많이 사용하는 MySQL은

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'' at line 1

이러한 에러가 나왔을 때 MySQL이라고 추측할 수 있다.


5. PostgreSQL


MySQL 데이터베이스에 공격 수행 시 발생될 수 있는 500번 및 에러 정보를 웹 로그에서도 추적이 가능함을 보인다.

1 Number=2002-002412' |63|80040e14|'2002-002412''_문자열_앞에_닫히지_않는_인용부호가_있습니다. 500 2 Number=2002-002412' and user=1 and ''=' |63|80040e07|nvarchar_값_'team'()_int_데이터_형식의_열로_변환_하는_중_구문_ 오류가_발생했습니다. 500 3 Number=2002-002412' And Cast(IS_SRVROLEMEMBER(sysadmin)) as varchar(1))+char(124)=1 And ''=' |63|80040e07|varchar_값_'0|'()_int_데이터_형식의_열로_변환_하는_중_구문_ 오류가_발생했습니다. 500 4 Number=2002-002412'And Cast)IS_MEMBER(db_owner) as carchar(1))+char(124)=1 And ''=' |63|80040e07|varchar_값_'1|'()_int_데이터_형식의_열로_변환_하는_중_구문_ 오류가_발생했습니다. 500

1번째 라인에서는 게시판에 사용되는 URL 정보에 특수문자(') 삽입을 통해 시스템에러가 발생되기 때문에 취약점을 판단할 수 있다.

2번째 라인에서는 Number=2002-002412와 ' and user=1의 조합은 에러가 발생되는 조건을 만들기 위해 삽입되었다.

이를 통해 에러정보 내에 DB정보인 'team' 문자열이 노출되고 있다.

3번째 라인에서는 MS SQL 함수 IS_SRVROKEMEMBER(DB 계정이 sa(system admin) 권한을 가지는 멤버인지를 확인)를 이용하여 관리자 권한여부를 확인하고 있다.

에러 페이지에는 'varchar_값_1'이므로 True로 판명되었다.

결국 'team' 계정은 sysadmin 계정은 아니지만 DB Owner 중의 1명이라는 사실을 알아냈기 때문에 관리자 권한을 수행할 수 있음을 짐작할 수 있다.

SQL Injection의 유형들을 간단하게 살펴보았다.

추후에 자세한 내용들을 포스팅하겠다.


네이버 블로그 : http://newprog.blog.me

blogger : http://progjw.blogspot.com