ESM에 SQL Injection 공격 관련 로그가 탐지되었다.

본 문서에서는 공격의 형태에 대한 설명 보다는 해당 로그 한 줄을 이용하여 분석자가 분석 및 유추를 통해 획득 가능한 정보에 대해서 어떠한 정보 등을 획득 할 수 있는지에 대해서 설명 한다.


○ 탐지된 로그

/services/service.php?sno=113653&subsno=113653&sa=showcontent&lang=kr&sn=board&code=free&page=1'%20and%201=2%20union%20select%20CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c)

그냥 보면 그냥 지나쳐도 될 만한 무효한 공격이거나 탐지된 정보일지도 모른다. 실제로도 그럴 거 같다.  한눈에 봐도 무슨 의도로 저런 공격 코드를 보냈는지 난감하기만 하다. 무효해 보인 SQL Query를 예제로 해서 획득 가능한 정보에 대해서 하나하나 알아보자.


○ 로그에서 획득 가능한 정보


1. SQL Query는 유효한 공격 구문인가?

결론부터 말하지만 해당 구문은 오류를 포함한 유효한 구문이 아니다. 하지만 이렇게 결론을 내릴 수는 없다. 뭔가 석연찮은 면을 가지고 있기 때문이다.

page=1' and 1=2 union select ~~~~~,CONCAT(0x27,0x7c,0x5f,0x7c)

위의 구문에서 page 파라메터의 값에 Single Quote(인용구)를 삽입하였다. 이 의미는 해당 파라메터에 String Type의 SQL Query를 삽입하였다는 의미가 된다.

공격 구문을 삽입하여 강제 Escape 처리를 하였다면 사용자가 삽입한 Single Quote로 인하여 에러가 발생하게 된다. 즉 문자열을 표현하기 위해서는 Single Quote를 쌍으로 써야 하지만 사용자가 삽입한 문자열로 인하여 ''' 처럼 Single Quote가 세 개가 되어서 에러가 발생한다는 의미이다.
그렇다면 위의 쿼리는 무효한 공격인가에 대해서 알아보자.


2. 무효한 공격 인가?

해당 구문이 무효한 공격이라고 단정 짓기는 이르다. 왜냐면 아직 우리는 로그를 쌓는 방식에 대해서 알아보지 않았기 때문이다.

먼저 해당 방식은 "/services/service.php?sno=113653~"에서 GET방식에 의한 요청임을 알 수 있다. 계속적으로 분석하기 전에 GET방식의 특징에 대해서 먼저 알아보자.

GET 메서드 : 별도의 메시지 바디를 사용하지 않으며 전송 가능한 데이터의 길이는 rfc2616 표준문서에도 명시적으로 정의되어 있지 않다. 국내에서 대표적으로 쓰이는 IE는 2048까지 지원한다고 한다.
※ 참조 SITE : http://support.microsoft.com/kb/208427

GET Method : 2,048 characters

위의 공격 요청 구문의 길이를 보면 총 1,024 characters이다. GET Method를 이용해서 충분하게 전송 가능한 데이터의 길이이며 또한 공격구문의 마지막을 보면 ~CONCAT(0x27,0x7c,0x5f,0x7c)으로 구문이 끊겨 보이지도 않는다.

그렇다고 무효한 공격 구문이라 단정 짓기는 어렵다고 생각한다. 로그를 관리하는 시스템의 로깅 길이가 1024로 제약되어 있거나 다른 이유로 절삭 되었을 수 있기 때문이다. 그렇다면 1,024 보다 공격 구문의 길이가 좀더 길 수 있다고 예상 할 수 있다.

해당 구문을 보면 select 다음에 CONCAT(0x27,0x7c,0x5f,0x7c) 패턴이 반복적으로 나타나고 있다. 해당 구문을 평문으로 복원하면 '|_|의 문자열이다. 흔히 문서에서 사용되는 문자열 패턴은 아니라는 것을 알 수 있다.

그렇다면 해당 구문을 Google을 통해서 검색해보자.

사용자 삽입 이미지


의외의 결과가 나타났다. 3200건이나 검색이 된 것이다. 즉 해당 구문을 이용한 SQL Injection 공격 시도가 대량으로 시도 되었다는 것을 예상해 볼 수 있다.

인터넷에 남겨진 공격 구문을 검색해서 완벽한 공격 구문 획득이 가능하였다.

page=1' and 1=2 union select CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c, 0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c) /*

검색 결과 여러 사이트에서 CONCAT(0x27,0x7c,0x5f,0x7c)구문이 3번 또는 그 이상의 횟수가 반복된 형태가 다수 발견이 되었다.

이 구문을 보면 해당 구문은 유효한 공격 구문인 것은 명확하다. 또한 수천 건이 인터넷에서 검색된 점을 감안하면 자동화 툴에 의한 탐지 코드로 유추되지만 탐지 효율성이 매우 낮지 않을까 예상된다.

위에서 해당 공격 구문이 비효율적이지만 유효하다는 것을 알 수 있었다. 그렇다면 공격자가 어떤 DB를 공격하기 위한 구문일까?


3. 타겟 DB는 무엇인가?

 질의어만 보고 공격 DB의 종류를 유추 할 수 있다.  해당 공격 구문에서는 CONCAT 함수를 사용하였으며 CONCAT함수는 다음과 같은 특징이 있다.

                ORACLE              MySQL MSSQL
   CONCAT        2개의 파라머터 허용     하나 이상의 파라메터 허용 미지원

위에서 보면 해당 공격 구문은 CONCAT(Param1,Param2,Param3)로 3개의 파라메터를 사용하고 있기에 DB가 MySQL 이라는 것을 알 수 있다.

하도 인터넷에서 구한 파라메터에 /* 를 사용하고 있음을 알 수 있다. 질의어에서 /* */이용하여 주석 처리를 할 경우 쌍으로 사용해야 하나 단일 사용을 허용하는 DB는 MySQL에서만 가능하므로 공격 대상 DB는 MySQL임을 알 수 있다.

○ CONCAT  함수란?

문자열 필드나 데이터를 단순하게 합치는 함수로 MySQL과 Oracle에서 사용된다.

※ 위의 설명에서는 DB를 MSSQL, MySQL, Oracle로 제한해서 설명한다. 세계적으로 가장 많이 사용되는 DB이므로 주 공격 타겟이 되기 때문이다.



4. 공격자는 왜 동일 패턴의 코드를 반복하였는가?

CONCAT(0x27,0x7c,0x5f,0x7c) 코드가 계속적으로 반복된 형태가 많이 발견되었다. 그렇다면 해당 코드는 무엇을 하기 위한 역할이었을까?

먼저 공격 구문을 다시 한번 확인해 보자.

page=1' and 1=2 union select CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c, 0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c) /*

인터넷에 구한 구문이 훨씬 간결하기에 위의 구문을 이용해서 설명한다.

여기서 page=1' and 1=2 ~를 볼 수 있다. SQL Injection 공격에서 and 1=2를 사용한 경우는 null-based sql injecton 공격 임을 알 수 있다. null-based란 말은 정상적으로 해당 사이트에 접속하였을 경우 사용자에게 보여주는 DB의 데이터로 모두 안보이게 하겠다는 의미로 공격자가 원하는 데이터만 나오게 하려는 의도이다.

다음에 union select concat~ 구문이 나타난다. 해당 구문은 UNION의 특징에 대해서 이해하면 쉽게 알 수 있다.

UNION 연산자
- 열의 개수와 순서가 모든 쿼리에서 동일해야 함
- 데이터 형식이 호환되어야 함

위의 공격 구문은 열의 갯수를 찾기 위해서 사용된 구문으로 유추된다. 아마도 탐지코드를 1회, 2회, 3회 증가해 가면서 리턴 되는지를 탐지하기 위한 것으로 보인다. 하자만 몇 가지 오류가 있다. 여기에서 칼럼 타입이 맞아야 한다. 하지만 공격자는 모든 칼럼에 동일 탐지 코드를 사용했다.

보통의 환경이라면 아마 취약해도 DB의 에러만 발생 했을 것으로 보인다. 그렇다면 왜 공격자는 이러한 문자열을 대량으로 스캔을 수행 했을 거라는 의문이 남게 된다.


5. 추가로 발견된 공격구문

네이버의 SecurityPlus에 유사한 구문에 대한 질문이 있었다.

' union select 1,2,concat(0xB9DCC0EDD4B1A3BA,userid),4,concat(0xC3DC5EC2EB,substring(pwd,9,16)),6 from think_admin%23

위의 구문을 보면 공격자는 union을 통해서 자릿수와 칼럼 수를 획득한 다음에 db의 데이터를 취득하기 위한 용도로 사용한 것으로 보인다.

여기서 CONCAT 각각의 첫 번째 값은 0xB9DCC0EDD4B1A3BA, 0xC3DC5EC2EB이며 취약점을 통해 획득된 데이터를 구분하기 위한 식별자로 쓰인 것으로 보인다.

※ 참고SITE : http://www.netbarghost.com/pocle/channel3/programming/20081214_2557.html



○ 분석 결과 종합

공격자는 MySQL DB를 대상으로 대량의 공격을 시도한 것으로 보인다.

MySQL은 Ver5.0 미만에서는 DB의 스키마를 제공하는 테이블이나 뷰가 없으므로 테이블 획득이 불가하다는 점을 감안할 때 무차별 대입 또는 DB의 구조가 열려진 공개 게시판이나, 취약한 게시판 등에서 획득한 테이블과 칼럼을 바탕으로 Dictionary 만들어서 Dictionary 공격을 시도하기 위해서 사전에 취약점 탐지를 위한 공격으로 보인다.
Posted by n3015m
:
BLOG main image
'네오이즘'의 보안LAB 블로그입니다........... n3oism@gmail.com by n3015m

카테고리

분류 전체보기 (228)
[ HappyDevTool ] (29)
[ HappyToolRelease ] (4)
[Book] (6)
[ Security Studies ] (0)
- CII (2)
- BigData (2)
- Web Hacking (10)
- SQL Injection (25)
- Mobile Security (9)
- Network (6)
- OperatingSystem (4)
- Malware & Reversing (4)
- Phishing (5)
- Compliance (0)
- Programming (13)
- Tools (13)
- IoT (6)
- etc (21)
[Pentration Testing] (3)
[OS X] (4)
[ Security Trends ] (16)
[ Fixing Guideline ] (7)
My Way, My Life (34)
About Me (2)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

Total :
Today : Yesterday :