Error Based SQL Injection

DATE : 2023/12/07

what is Error Based SQL Injection?

이번에 공부해볼 주제는 바로 Error Based SQL Injection이다.

앞에서 UNION SQL Injection에 대해 다룰 때, 우리는 크게 두 가지 경우를 고려할 수 있다고 했는데

첫 번째는 Query 결과가 화면에 보여지는 경우였고,

두 번째는 Query 결과가 화면에 보이지 않는 경우였다.

UNION SQLi와 마찬가지로 Error Based SQL Injection 또한

Query 결과가 화면에 나오는 경우, 데이터를 추출하기 위한 방법이 될 수 있다.

What is Goal to perform Error Based SQL Injection?

우리가 Error Based SQL Injection을 수행하고자 하는 이유는 간단하다.

바로 데이터를 추출하고 싶기 때문이다!

데이터를 추출한다는 말은 결과적으로 SELECT문을 실행해야 한다는 뜻으로

앞에서 봤던 UNION SQL Injection의 경우에는 우리가 원하는 값을 DB에서 꺼내오기 위해

UNION으로 SELECT문을 연결해주는 방법을 사용했다.

Error Based SQL Injection에서는 이름으로 유추할 수 있듯이

SELECT문을 수행해 원하는 데이터를 추출하기 위해서 Error message를 활용한다.

즉, 우리가 원하는 데이터를 얻기 위해서는

(1) 값이 화면에 출력 되는 게 편하고

(2) 의도적으로 에러를 발생 시켜 화면에 어떤 문구가 출력 되도록 만들되,

(3) 그 안에 내가 원하는 데이터를 넣겠다는 게 Error Based SQL Injection의 컨셉이다.

따라서 Error Based SQL Injection의 목적이 데이터 추출이라면

이를 수행하기 위한 Error Based SQL Injection의 초기 목표는 에러를 발생 시키는 것이다.

Syntax Error vs Logic Error

Error Based SQL Injection은 의도적으로 발생 시킨 에러 속에

얻고자 하는 데이터를 포함 시킴으로써 정보를 추출하는 방법이라 정리했다.

여기서 중요한 건 에러 의미 있는 에러가 있고, 쓸모 없는 에러가 있다는 것..!

DB가 어떤 SQL을 실행할 때는 (1)컴파일을 한 후에 (2)실행을 하는데

만약 작성한 SQL의 문법이 틀린 경우에는 실행이 되기 전에 에러가 나버린다.

SQL 문법에 대한 에러, 이를 Syntax Error 라고 하는데 앞에서 말한

쓸모 없는 에러가 바로 Syntax Error이다.

왜 쓸모가 없다고 얘기하느냐! 하면 위에서 언급한 바와 같이 우리의 목적은 데이터 추출로,

이를 수행하기 위해서는 SELECT문이 일단 실행 되어야 한다.

하지만 Syntax Error의 경우에는 SQL이 실행되기도 전에 에러가 나기 때문에

우리에겐 아무런 의미가 없다는 뜻이다.

이와 달리 Logic Error실행이 되는 와중에 문제를 일으켜 발생한 에러이기 때문에

SQL이 실행된다는 점에서 우리에게 의미 있는 에러라고 할 수 있다.

따라서 Error Based SQL Injection을 수행하는 데에 있어 에러라는 것도

(1) 서버 측 코드로 인해 에러가 아닌, SQL과 관련된 에러

(2) Syntax Error가 아닌, Logic Error

이 두 가지 조건을 고려해야 적절한공격 포인트를 찾아낼 수 있다.

How to Generate Error

Error Based SQL Injection을 수행하기 위해서는 에러를 의도적으로 만들어낼 필요가 있음을 알았다.

그렇다면 우리에게 필요한 정보는 어떻게 에러를 발생 시킬 수 있는가!이다.

각 DB에 따라서 에러를 내기 위해 사용할 수 있는 함수들이 존재한다.

그 중에서도 MySQL - ExtractValue 함수에 대해 살펴볼 것이다.

extractvalue(xml data, XPATH expression)

ExtractValue 함수는 첫 번째 인자로 주어진 데이터에서 두 번째 인자로 주어진 값을 찾아 추출한다.

이때 두 번째 인자 자리에 규칙에 어긋난 값이 들어가면 에러가 발생한다고 한다.

따라서 우리는 규칙에 어긋난 값을 ExtractValue 함수의 두 번째 인자 값으로 넣어

에러를 만들어낼 것이다.

ID를 입력했을 때, ID 존재 유무를 출력해주는 사이트가 있다고 상상해보자.

normaltic' and extractvalue('1',concat(0x3a,(select 'hanhxx'))) and '1'='1

normaltic 계정이 존재한다는 사실을 활용해 위와 같은 Query를 작성해보았다.

normaltic' and '1'='1

까지만 보면 normaltic이라는 정보를 조회했을 때만 참이 되지만

우리는 에러가 발생하기를 바란다. 😏

따라서 에러를 야기할 함수를 중간에 넣어준 것 뿐!

extractvalue('1', concat(0x3a, (select 'hanhxx')))

ExtractValue 함수 내용을 이처럼 작성하게 되면 '1' 에서 ':hanhxx' 를 찾아내라는 의미인데

이때 콜론(0x3a)이 XPATH expression에 어긋나는 문자이기 때문에 에러가 발생하게 된다.

이때 주목할 점은 에러 메세지에 나오는 값이 ExtractValue 함수의 두 번째 인자 값이라는 점이다.

이 에러 문구는 "너가 입력한 값은 XPATH 정규식이 아니야~" 라는 뜻이기 때문에

잘못된 정규식이 무엇인지 알려주기 위해 화면과 같이 그 값을 출력해준다.

따라서 이런 동작 방식을 활용해 우리가 실행하고자 하는 SELECT문을 주입한다면

원하는 데이터를 추출할 수 있을 것이다!

ExtractValue & Concat function

위에서 사용한 Query를 조금 더 자세히 살펴보고 넘어갈까 한다.

normaltic' and extractvalue('1', concat(0x3a, (select 'hanhxx'))) and '1'='1

여기서 알아보고자 하는 건, (1)concat 함수가 무엇이고 (2)왜 위와 같은 형태로 구문을 작성했는가이다.

우리는 How To Generate Error에서 살펴본 바와 같이 에러를 발생 시키고 싶은 상황인데

기본적으로 SELECT문은 SELECT문대로 실행이 되어야한다.

즉 우리가 해결해야 하는 문제는

(1) 에러를 발생 시킨다.

(2) SELECT문을 실행한다.

2가지로 정리할 수 있다. 이게 왜 문제가 되는 지 설명해보면!

일단 (1)을 해결하기 위해 ExtractValue 함수를 선택한 건데

ExtractValue 함수가 갖는 인자는 모두 문자열이기 때문에 여기에 SELECT문을 쑤셔 넣는다고

SQL로써 실행이 되진 않을 것이다.

더불어 에러를 만들기 위해 콜론, 느낌표 등의 문자를 붙여줘야 하는 데

SELECT문에 느낌표나 콜론을 붙이면 실행이 되기도 전에 문법 에러가 날 것이다.

우리는 SELECT문의 결과를 얻고 싶은 거지,

SELECT문 자체를 출력하고 싶은 게 아니기 때문에 이 부분을 해결할 방도가 필요한 것이다.

이때 사용할 수 있는 함수가 바로, concat으로

concat 함수는 주어진 두 문자를 하나로 연결해주는 기능을 담당한다.

concat(0x3a, (select 'hanhxx'))

따라서 위와 같이 작성하게 되면 DB는 괄호 안에 들어있는 select 'hanhxx'를 먼저 수행하고

그 결과를 SELECT문 자리에 넣어주면

concat(0x3a, 'hanhxx')

그 다음으로 concat 함수가 실행되면서 결과적으로 ":hanhxx"라는 값이 만들어지게 된다.

위와 같은 과정으로

(1) SELECT문은 SQL로써 정상적으로 실행될 수 있고

(2) 에러를 발생 시키기 위한 특정 문자를 SELECT문 결과에 붙임으로써

주입한 SQL의 결과를 화면에서 볼 수 있게 되는 것이다.

이런 이유로 인해 concat 함수를 사용했던 것!

뜬금없이 나온 게 아니라 우리의 목적을 달성하기 위한 과정에서

어떤 문제가 존재하고 이를 해결하기 위한 방법으로 사용되었다는 흐름을 이해하고 넘어가도록 하자. 😎

Last updated