2015년 5월 24일 일요일

Snort 룰을 관리해보자.

IDS 등 보안장비를 운영하다 보면 룰(Rule) 관리 자체가 골치덩이가 되는 경우가 종종 있다. 특히 운영 초기부터 누가, 언제, 왜 만들었는지에 대한 이력 관리와, 룰 간 유사성이나 중복 여부 관리, 룰이 목적에 맞게 운영되고 있는지에 대한 사후 관리를 시작하지 않으면 나중에는 쉽게 손을 댈 수 없는 지경에 이르게 된다.

이력 관리
결국 룰 운영을 통해 보안장비 운영이 이루어지기 때문에 룰 이력 관리는 매우 중요하다. 어떤 필요에 의해 생성, 수정, 삭제가 이루어지고 있는지에 대한 현황이 관리되지 않으면, 조직이나 네트워크의 목적 및 특성과 어울리지 않는 룰이 운영될 가능성이 높아지며, 이로 인해 룰 관리가 점점 더 복잡해질 가능성 역시 높아진다.

중복성 관리
중복성 관리가 안되면 룰 개발 체계의 비효율성이 높아진다. 중복 패턴매칭의 증가에 의해 유사 룰 개수가 늘어나게 되고, 그 결과 운영비용이 증가하며, 장비의 가용성은 떨어지고, 최악의 경우 장비 장애로 발전할 수도 있다.

사후 관리
만들어진 룰은 정확도 측면에서 지속적으로 관리할 필요가 있다. 공격을 걸러내려고 만든 룰이 과연 제대로 동작하고 있는지, 의미없는 오탐을 양산하고 있지는 않은지에 대한 관리가 필요한 것이다. 정확도 측면의 사후 관리가 이루어지지 않으면 관제업무량 증가로 인해 처리비용이 낭비되고 업무처리가 부실해질 수 밖에 없으며, 결국 전체 보안관제 체계의 수준 저하로 이어진다.

장비를 도입하면 보통 업체는 2~3,000개 정도의 룰을 제공하는데, 기본 룰만으로 운영한다면 사실 문제는 간단할 수도 있다. 룰 관련된 모든 책임을 업체에게 지우면 된다.ㅡㅡ; 그런데 일정 수준 이상의 규모를 갖춘 조직일수록 자체적인 룰 개발을 시도하는 게 트렌드다 보니 그리 간단하지가 않다. 결자해지(結者解之)가 필요한 셈.

장비에 적재된 기본 룰 파악을 먼저 끝낸 후, 그 결과를 기반으로 신규 룰 개발이 이루어지는 체계의 정착을 바라면서, Snort를 기준으로 룰 관리 사례를 살펴 보자. 보통 대부분의 룰 관리는 이력관리 위주로 이루어진다. (사실 이렇게라도 지속적인 관리가 이루어지고 있다면 그것만으로도 보안관제 체계의 수준이 상당하다고 볼 수 있다.)

룰 이력관리 예시

이력 위주의 룰 관리는 중복성 및 사후관리 차원에서 큰 도움이 되지 않는다. 룰 관리체계를 중복성 및 사후관리 차원까지 확대하려면 수천 개 이상의 룰에 대해서 다양한 옵션 및 패턴 비교가 가능한 체계를 만들어야 한다. 시작해 보자. 일단 56개의 유형별 Snort 룰 파일을 하나로 취합해야 한다.

Snort 룰 파일 취합

취합된 Snort 룰

Snort 룰은 헤더와 옵션의 구조로 이루어져 있는데, 체계적인 관리를 위해 헤더와 옵션을 분리해 보자. 다음 과정을 통해 헤더와 옵션 분리가 가능하다.
① 룰 헤더를 제외한 나머지는 '%s/\s(.*//' 명령어를 이용해서, '공백('로 시작하는 모든 문자열 삭제
② 룰 옵션을 제외한 나머지는 '%s/^alert.\{-}\((\)\@=//' 명령어를 이용해서 삭제
-> 'alert'으로 시작해서 '('로 끝나는 문자열 삭제(마지막 '('는 제외)

참고로 '%s/패턴1/패턴2/' 명령어는 '패턴1'을 '패턴2'로 변환해주는데, '패턴2'가 공백이면 '패턴1'을 삭제한다는 뜻이며, '\{-}' 는 '*?' 와 같은 의미의, VIM에서 사용하는 정규표현식 최소 범위 수량자이다.

Snort 룰 헤더 추출

Snort 룰 옵션 추출

룰 간 주요 옵션 비교를 위해 패턴매칭과는 무관한 flow(TCP 세션 상태 및 방향), dsize(패킷 데이터 길이) 옵션 및 패턴매칭에는 관여하나 동작방식 파악에 유리한 flowbits(세션 추적), byte_(byte 값 매칭), threshold(발생량) 옵션도 분리할 것이다.

참고로 룰 옵션 분리는 취합된 룰 파일에서 정규표현식을 이용하여 검사 옵션별로 추출한 후, 엑셀의 '텍스트 나누기' 기능을 이용할 것이다.

[ flow 옵션 추출 ]
① '%s/\(flow:\)\@<=.\{-}\(;\)\@=/ㅋ&ㅋ/' 명령어를 이용해서 flow 옵션값만 추출.
-> 'flow:'와 ';' 사이의 문자열 추출
② '\(패턴1\)\@<=패턴2' 명령어는 '패턴1'로 시작하는 '패턴2'를 찾아주는 '긍정형 후방탐색'
③ '패턴1\(패턴2\)\@=' 명령어는 '패턴2'로 끝나는 '패턴1'을 찾아주는 '긍정형 전방탐색'

[ '패턴1'로 시작, '패턴3'으로 끝나는 '패턴2' 검색(전후방탐색 혼용) ]
vim 사례 : \(패턴1\)\@<=패턴2\(패턴3\)\@=
pcre 사례 : (?<=패턴1)패턴2(?=패턴3)


[ dsize 옵션 추출 ] 
① '%s/\(dsize:\)\@<=.\{-}\(;\)\@=/ㅋ&ㅋ/' 명령어를 이용해서 dsize 옵션값만 추출


[ flowbits 옵션 추출 ]
① '%s/flowbits:.*flowbits:.\{-};\|flowbits:.\{-};/ㅋ&ㅋ/' 명령어를 이용해서 연속되는
flowbits 옵션 추출
-> 2개 이상의 'flowbits' 로 시작, ';' 으로 끝나는 문자열
② 또는(\|) 단일 flowbits 옵션 추출
-> 'flowbits' 로 시작, ';' 으로 끝나는 문자열


[ byte_ 옵션 추출 ]
① '%s/byte_.*byte_.\{-};\|byte_.\{-};/ㅋ&ㅋ/' 명령어를 이용해서 연속되는 byte_ 옵션 추출
-> 2개 이상의 'byte_' 로 시작, ';' 으로 끝나는 문자열
② 또는(\|) 단일 byte_ 옵션추출
-> 'byte_' 로 시작, ';' 으로 끝나는 문자열


[ threshold 옵션 추출 ]
① '%s/\(threshold:\)\@<=.\{-}\(;\)\@=/ㅋ&ㅋ/' 명령어를 이용해서 threshold 옵션값만 추출
-> 'threshold:'와 ';' 사이의 문자열


이제 제일 중요한 '문자열 패턴' 검사 옵션을 추출해야 하는데, 추출이 쉽도록 룰 동작과는 무관한 metadata(관련 정보), reference(관련 취약점 정보), classtype(룰 유형), sid(룰 일련번호), rev(룰 버전) 옵션을 삭제할 필요가 있다.

[ 룰 동작과 무관한 옵션 삭제 ]
① '%s/metadata:.\{-};\|reference:.\{-};\|classtype:.\{-};\|sid:.\{-};\|rev:.\{-};//g' 명령어
-> metadata, reference, classtype, sid, rev 옵션을 OR 조건(\|)으로 검색 후 전체(g) 삭제


본격적으로 '문자열 패턴' 검사 옵션을 추출해 보자. 특이하게도 URI 영역을 검사하는 룰 옵션인 'uricontent' 가 없다. 룰 배포 시 'http_uri' 수정자 사용을 권장하나 보다. (사실 Snort 룰은 옵션이 너무 많아서 좀 헷갈린다.ㅡㅡ;)

[ '문자열 패턴' 검사 옵션 추출 ]
① '%s/\(\(content:\|pcre:\).*\)\+/ㅋ&ㅋ/' 명령어
-> 하나 이상(\+)의 content 또는(\|) pcre 검사 옵션 추출


'문자열 패턴' 검사 옵션을 추출하는 이유는 룰 간 '문자열 패턴'의 유사도 및 중복성을 검증하기 위해서인데 다양하게 나열된 옵션 및 수정자들 때문에 비교하기가 쉽지 않다. (한 눈에 잘 안 들어 온다.) 순수하게 '문자열 패턴'만을 추출한다면 좀더 쉽게 유사도 및 중복성을 검증할 수 있지 않을까?

섞여 있는 '비(非)문자열' 검사 옵션 및 다양한 수정자를 먼저 제거한 후, '문자열' 검사 옵션('content:', 'pcre:') 패턴을 제거하는 두번의 과정을 거치면 순수한 '문자열 패턴'만을 추출할 수 있다.

[ '비문자열' 검사 옵션 및 수정자 삭제 ] 
① '%s/\(flow:\|dsize:\|flowbits:\|byte_\|threshold:\|fast_pattern:\{-}\|offset:\|depth:\|distance:\|within:\|isdataat:\|nocase\|http_\).\{-};//g' 명령어
-> '비문자열' 검사 옵션 및 수정자를 OR 조건으로(\|) 검색 후 전체(g) 삭제


[ '문자열 패턴'만 추출 ]
① '%s/\(content\|pcre\)://g' 명령어
-> 순수 '문자열 패턴'을 제외한 검사 옵션 'content: 또는(\|) pcre:' 패턴 검색 후 전체(g) 삭제


최종 결과물은 아래와 같다. 장비 도입 초기부터 룰 관리를 해왔다면 간단했을 작업을 미루고 미루면 텍스트 데이터를 수없이 뗐다 붙이는 개고생을 하게 된다. (정규표현식 공부한 걸로 퉁 쳐도 됨^^;)

상용 보안장비의 룰 옵션은 Snort 보다는 덜 복잡하기 때문에 작업이 한결 수월할 것이다. 참고로 정규표현식은 같은 결과를 가져오는 다양한 표현이 가능하며, 작업 순서에 따라서도 얼마든지 달라질 수 있다.

같은 옵션이 산재해 있는 경우 때문에 중복을 완전히 제거하지는 못했지만 그런 부분은 엑셀에서 비교적 쉽게 정리할 수 있다. 이제 룰 간 유사 또는 중복 패턴 사용 여부를 나머지 옵션과 함께 비교할 수 있게 되었으니 패턴매칭 룰의 운영 효율을 조금은 더 높일 수 있지 않을까? (룰 공부에도 좋음)


출발지 범주
출발지 포트 범주
flow 옵션 범주
dsize 옵션 범주
flowbits 옵션 범주
byte_ 옵션 범주
threshold 옵션 범주
기타 옵션(프로토콜 및 패킷 특징 검사) 범주
'문자열 패턴' 검사 옵션 범주






























순수 '문자열 패턴' 범주

댓글 없음:

댓글 쓰기

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