2015년 5월 26일 화요일

VIM 정규표현식과 PCRE

이전 글에서 정규표현식을 이용하여 텍스트 데이터로 이루어진 Snort 룰 구조를 분석 후 필요한 영역만을 분리해낼 수 있었다. 그런데 이 정규표현식이란 게 애플리케이션마다 다르게 구현되어 있어서 (사소한) 애로사항이  발생할  때가  많다.

VIM과 PCRE는 어떻게 다를까? 일단 VIM은 자체 정규표현식 엔진을, Snort는 PCRE(Perl Compatible Regular Expressions)를 사용하는데, 이런 차이가 동작 원리의 차이로 이어지지는 않는다.

다만 몇몇 메타문자의 표현 방식에서 매우 사소한, 하지만 (특히 괄호 및 OR 연산자를 표현할  때 '\'를 이용한 예외 처리가 필요하다는) 매우 귀찮은 차이로 이어진다.

이런  차이가  발생하는 이유는 한마디로 PCRE는 정규표현식 자체이기 때문에 정규표현식이 우선하지만, VIM은 텍스트 편집기라는 태생적 특성상 텍스트가 우선하기 때문이다. 문제는 항상 그렇지는 않다는 점. 그래서 더 헷갈림(..)

PCRE는 캡처그룹으로 사용되는 '()'나 수량자 '+', '?' 등 다양한 순수 문자를 (물론 메타문자 기능을 가지고 있을 때만) 메타 문자로 우선 인식하지만, VIM 은 메타 문자 기능을 가지고 있더라도 순수 문자로 우선 인식하는 것이다.

그래서 (텍스트 데이터인 로그를 분석하고, 텍스트 패턴매칭 룰도 개발해야 하는) 우리는 VIM과 PCRE 정규표현식의 차이를 잘 알 필요가 있다.

이전 글에서 사용된 VIM 정규표현식을 동일한 의미의 PCRE 정규표현식과 비교해 보자. 검은색은 순수 문자열, 나머지 색은 정규표현식 메타문자이며, 정규표현식의 이해를 돕기 위해 'www.regexper.com' 의 PCRE 구조 설명을 첨부했다.

  • '공백('로 시작하는 모든 패턴

vim  : \s(.*
특징 : VI는 '('를 문자열로 인식하며, 메타문자로 인식시키기 위해서는 예외처리(\)가 필요

pcre : \s\(.*
특징 : pcre는 '('를 메타문자로 인식하며, 문자열로 인식시키기 위해서는 예외처리(\)가 필요

pcre 구조 : '공백(white space)'과 '(' 문자열 이후, 종단점(검색할 문자열이 없는 지점)까지 임의의 문자열(any character)이 반복되는 구조



  • 'alert'으로 시작해서 '('로 끝나는 패턴을 찾되, '('는 제외된 패턴

vim  : ^alert.\{-}\((\)\@=
특징 : VI는 탐욕을 제한하는 수량자 '?'가 없으나, PCRE의 '*?'와 같은 의미인 '\{-}' 사용 가능

pcre : ^alert.*?(?=\()
특징 : VI(\((\)\@=)와 다른 PCRE((?=\()) '긍정형 전방탐색(positive lookahead)' 문법

pcre 구조 : 행(line)의 시작(^) 문자열이 'alert'이며, '(' 문자열이 나타나기 전까지, 임의의 문자열이 반복되는 구조




  • 'flow:'와 ';' 사이의 패턴

vim  : \(flow:\)\@<=.\{-}\(;\)\@=
pcre : (?<=flow:).*?(?=;)
특징 : VI(\(flow:\)\@<=)와 다른 PCRE((?<=flow:)) '긍정형 후방탐색(positive lookbehind)' 문법

pcre 구조 : 'flow:' 와 ';' 사이의 문자열만 검색하는 구조('www.regexper.com' 의 자바스크립트 정규표현식은 '후방탐색'을 지원하지 않음ㅡㅡ;)


  • 연속된, 또는 단일 flowbits 옵션 패턴

vim  : flowbits:.*flowbits:.\{-};\|flowbits:.\{-};
특징 : VI는 '|'를 문자열로 인식하며, 메타문자로 인식시키기 위해서는 예외처리(\)가 필요

pcre : flowbits:.*flowbits:.*?;|flowbits:.*?;
특징 : pcre는 '|'를 메타문자로 인식하며, 문자열로 인식시키기 위해서는 예외처리(\)가 필요

pcre 구조 : 2개의 표현식을 OR조건으로 검색
표현식1 : 반복되는 임의의 문자열을 포함한 2개 이상의 'flowbits:' 문자열 이후, ';' 문자열로 끝나는 구조
표현식2 : 'flowbits:' 문자열 이후, ';' 문자열이 나올 때까지 임의의 문자열이 반복되는 구조



  • 'metadata:, reference:, classtype:, sid:, rev:' 로 시작해서 ';'으로 끝나는 패턴

vim  : metadata:.\{-};\|reference:.\{-};\|classtype:.\{-};\|sid:.\{-};\|rev:.\{-};
pcre1 : metadata:.*?;|reference:.*?;|classtype:.*?;|sid:.*?;|rev:.*?;

pcre1 구조 : 5개의 표현식을 OR조건으로 검색


pcre2 : (metadata|reference|classtype|sid|rev):.*?;

pcre2 구조 : 그룹 메타문자 '()'를 이용해서 'PCRE1'을 축약한 구조



  • 하나 이상의 content 또는 pcre 옵션 패턴

vim  : \(\(content:\|pcre:\).\{-};\)\+
특징 : VI는 '+'를 문자열로 인식하며, 메타문자로 인식시키기 위해서는 예외처리(\)가 필요

pcre1 : ((content:|pcre:).*?;)+
특징 : pcre는 '+'를 메타문자로 인식하며, 문자열로 인식시키기 위해서는 예외처리(\)가 필요(수량자 '*'은 VI, pcre 모두 동일하게 인식)

pcre1 구조 : 'content:' 또는 'pcre:' 으로 시작, ';'이 나올 때까지 '임의의 문자'가 반복되는 구조가 다시 반복되는 구조(수량자 + 있음)


pcre2 : (content:|pcre:).*?;

pcre2 구조 : 'content:' 또는 'pcre:' 으로 시작, ';'이 나올 때까지 '임의의 문자'가 반복되는 구조(수량자 + 없음)



댓글 없음:

댓글 쓰기

크리에이티브 커먼즈 라이선스