2024-03-29 10:40 (금)
[강명훈의 로그분석②] 텍스트 정규화 이용 대량 로그분석 방법!
상태바
[강명훈의 로그분석②] 텍스트 정규화 이용 대량 로그분석 방법!
  • 길민권
  • 승인 2013.08.05 00:07
이 기사를 공유합니다

“어떤 규칙으로 정규화할지를 선택해야 한다”
텍스트 정규화를 이용해서 대량의 로그를 분석해 보자. 먼저 어떤 규칙으로 정규화할지를 선택해야 한다. 탐지 패턴을 기준으로 분류하는 것도 좋은 시도이지만, 제시된 사례처럼 사용자의 웹 접속 과정에서 발생한 로그에 대해서 URI(웹 요청 정보), Referer(URI의 출발지), Host(URI의 목적지), User-Agent(요청 도구) 지시자 정보 기준에 의한 분류가 이루어지면, 어떤 도구를 이용해서, 어디에서, 어디로, 어떤 정보를 전송했는지에 대한 전체 발생 현황을 쉽게 파악할 수 있다. 변환 작업은 최종적으로 엑셀의 '텍스트 나누기' 기능을 이용할 것이며, 이를 위해서는 분류를 원하는 텍스트에 '구분 기호'를 추가해야 한다.
 
먼저 해당 로그에서 URI를 추출해보자. 웹브라우저 등 웹 요청 정보를 전송하는 도구는, 지원하는 HTTP의 버전을 URI 이후에 표시한다. 이 특성을 이용하면 로그에서 URI 정보만을 추출할 수 있다. 다음 그림은 텍스트 에디터인 VI(www.vim.org)에서 '/HTTP/.*' 이란 검색 명령어를 이용하여 URI를 제외한 정보를 검색한 화면이다. 

 
사용된 명령어의 의미는 다음과 같다.

 
검색이 가능하면 치환도 가능하다. 다음 그림은 Vi의 문자열 치환 기능을 이용한 명령어(:%s/http/.*//i)를 입력하여 URI를 제외한 모든 정보를 삭제한 결과이다.

 
사용된 명령어의 의미는 다음과 같다.

 
다음 그림을 보면 URI 정보만을 추출하는데 성공했음을 알 수 있다.

 
이제 사용자가 과거에 요청한 URI이자, 현재 요청한 URI의 출발지인 Referer 정보를 추출해보자. Referer 정보의 값은 'Referer: ' 이후에 표시되며, 공백이 포함되지 않는다. 이런 특성을 이용하면 매우 쉽게 추출이 가능하다. 참고로 현재 요청한 URI의 목적지인 Host 정보 역시 값에 공백이 포함되지 않는다. 일단 검색 결과는 다음과 같다.

 
사용된 명령어의 의미는 다음과 같다.

 
URI 추출과 마찬가지로 검색 명령어를 이용해서 치환이 가능하다. 다음 그림은 ':%s/referrer:sS+/ㅋ&ㅋ/i' 명령어를 이용하여 치환한 결과이다. 1,146개의 로그 중 1,074개만 치환됐는데, 그 이유는 상황이나 환경에 따라 HTTP 지시자가 사용되지 않을 수도 있기 때문이다.

 
사용된 명령어의 의미는 다음과 같다.

 
구분 기호로 한글 자음인 'ㅋ'을 사용한 이유는 트래픽 정보를 표시하는데 사용되는 알파벳 등의 기호와 중복되는 것을 방지하기 위해서이며, 중복되지 않는다면 어떤 기호를 써도 상관 없다. 하지만 구분 기호가 통일되지 않고 중복된다면 텍스트 정규화는 실패할 것이다. 다음 그림은 치환이 끝난 로그를 엑셀로 옮긴 후, '텍스트 나누기' 기능을 이용하는 과정이다.

 
다음 그림을 보면 전체 로그가 Referer 정보를 기준으로 3개의 열로 분리됐음을 알 수 있다. 필요 없는 B와 D열의 정보는 삭제하면 된다.

 
Host 정보 역시 Referer와 같은 방식으로 분류하면 된다. 문제는 User-Agent 정보이다. Referer와 Host 정보의 값은 공백이 포함되지 않기 때문에 분류가 단순하지만, User-Agent 값은 공백이 포함되며, 다양한 표현 방식이 사용되기 때문에 분류하기가 매우 까다롭다. 그러나 정규표현식을 잘 활용하면 어느 정도 극복이 가능하다. 실제 사례를 보자.

 
User-Agent 정보는 표시 형식에서 Referer나 Host와 같은 특성(공백이 없다)이 없기 때문에 User-Agent 지시자 다음에 표시되는 지시자 앞에서 검색을 멈춰야 한다. 사용된 명령어의 의미는 다음과 같다. 

 
'{-}'란 VI의 수량 옵션이 사용되었는데 pcre(Perl Compatible Regular Expressions)의 '*?'와 같은 기능이다. '*'은 패턴의 수량을 0개 이상으로 제한하는 수량자인데, 기본적으로 최대 범위를 검사하려는 성질이 있다. 그런데 0 또는 1개로 수량을 제한하는 '?'와 함께 쓰이면 최소 범위로 검사가 제한된다. 다음 그림의 'w.*com'은 'w로 시작해서 com으로 끝나는' 모든 패턴을 검사하는 정규표현식이다. 해당 표현식에 의해 일치하는 패턴을 보면, 'w'로 시작한 후, 'abc.com' 패턴을 통과해서 'img.abc.com'에서 검사가 멈췄음을 알 수 있다. 검사할 수 있는 'com' 패턴이 더 이상 안 나올 때까지 검사하는 것이다.


 
다음 그림을 보면 'abc.com' 패턴이 나오자마자 검사가 멈췄다. '?'가 '*'의 최대 범위 검사 성질을 최소로 제한하고 있음을 알 수 있다. 이런 성질을 잘 이용하면 정교한 패턴 검사가 가능해진다. 참고로 이런 성질 때문에 '*', '+'는 탐욕적인 수량자, '?'는 탐욕적이지 않은 수량자라고도 한다. 

 
'전방 탐색'이란 이란 기능도 사용되었는데 VI에서는 '()@=' 형식으로 사용하며, pcre에서는 '(?=)' 형식으로 사용한다. 간단히 설명하면 'abc(de)@='는 'de'로 끝나는 'abc'만을 찾아주는 기능이다. 다음 그림을 보면 좀더 이해가 빠를 것이다. 그림의 표현식들은 모두 '공백'으로 끝나는 'com'만을 검사하며, '공백'을 제외한 'com' 패턴만을 검사 결과로 보여주고 있다.

 
HTTP 지시자는 지시자와 값이 ':'으로 구분되는 특성이 있는데, User-Agent 값에도 ':'이 사용될 수 있기 때문에 '[^(v|p)]:' 형식을 이용하여 'rv', 'http'로 끝나는 ':'을 제외시켰다. 그러나 User-Agent 값의 발생 양상에 따라 이런 형식은 얼마든지 변화가 가능함을 알아야 한다. 정규표현식은 매우 강력하고 편리한 패턴 검사 기능을 제공하지만 이러한 기능을 제대로 사용하기 위해서는 검사를 원하는 패턴을 결정하는 많은 경험을 쌓을 필요가 있다. 다음 그림은 ':%s/user-agent:sp{-}(sS+[^(v|p)]:)@=/ㅋ&ㅋ/i' 명령어를 이용하여 치환한 결과이다.

 
사용된 명령어의 의미는 다음과 같다.

 
최종 텍스트 정규화 결과는 다음 그림과 같다. 다음 시간에는 정규화된 원시데이터를 이용해서 룰의 문제점을 찾고, 개선 방안을 도출하는 과정을 살펴보겠다.

 
글. <빅데이터 분석으로 살펴본 IDS와 보안관제의 완성> 저자 강명훈
■ 보안 사건사고 제보 하기

▷ 이메일 : mkgil@dailysecu.com

▷ 제보 내용 : 보안 관련 어떤 내용이든 제보를 기다립니다!

▷ 광고문의 : jywoo@dailysecu.com

★정보보안 대표 미디어 데일리시큐 / Dailysecu, Korea's leading security media!★