2015년 8월 26일 수요일

Snort 분석(DELETED WEB-IIS header field buffer overflow attempt)

지난 글에서 Snort가 버린 룰들을 재활용하는 과정을 소개했었는데, 특정 로그가 얼씨구나 발생하기 시작했다. 해당 로그를 발생시킨 룰의 상세 내역은 다음과 같다.

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS 
(msg:"DELETED WEB-IIS header field buffer overflow attempt"; 
flow:to_server,established; 
content:"|3A|"; 
content:"|0A|"; 
content:"|00|"; 
reference:bugtraq,4476; reference:cve,2002-0150; classtype:web-application-attack; sid:1768; rev:8;)

관련 취약점 정보들이 있지만 공격의 특징을 알기에는 좀 부실한 듯하다. 예전엔 snort.org에서 룰 추가 정보를 검색할 수 있었는데, cisco 인수 이후로 mysql 직접 연동도 안되고 이래저래 불편.

그나마 해당 룰 패턴으로 추정을 해보자면 HTTP 헤더 필드의 구분자 조작을 통해 IIS 웹서버의 헤더 필드 검증 절차를 우회함으로써 예상보다 더 많은 데이터를 처리하게 하여 오동작을 유도하는 공격인 듯 하며, 추가로 헤더 필드에 쓰레기값을 집어넣어서 대량의 데이터를 전송하는 공격인 듯 하다.

해당 룰은 '3A(:)', '0A(Line Feed, \n)', '00(NOP)' 이 3개의 HEX 패턴을 검사 위치나 순서 등의 제한없이 그저 존재 여부만을 검사한다. 저 3개의 패턴이 없는 트래픽을 찾기도 힘들겠다. 이래서 룰 만들 때 개발자 이름을 집어넣도록 해야 함. 잡아다 족쳐야(..)

일단 발생량이 만 개가 넘는데 다 분석할 필요는 없다. 왜 그럴까? 순수 문자열로 이루어진 로그를 텍스트 정규화를 통해 분석을 시도하는 이유는 단순히 대량 로그를 쉽게 분석하기 위해서가 아니라, 텍스트의 맥락에 대한 통계 분석을 실시하기 위해서이다.

로그가 많을수록 맥락 분석의 정확도는 높아지고, 덤으로 샘플링과 비교할 수 없는 전수검사 차원의 신뢰성까지 얻게 되기 때문. (빅데이터가 각광 받는 이유는 별 거 없다. 표본이 클수록 통계가 정확할 거라는 믿음 때문)

그러나 해당 룰은 HEX 패턴을 이용해서 헤더 필드와 연관된 특수문자, 즉 트래픽의 구조를 검사한다. 순수 문자열을 검사하는 룰이 아니며, 그렇기 때문에 패턴에 대한 맥락 분석이 필수는 아니라는 뜻.


샘플링을 해보자. 해당 룰에 의해 발생한 로그의 IP 발생 구조를 살펴보니 1:23의 출발지와 목적지 구조를 가지고 있다. 목적지 기준의 샘플링을 하면 되겠다.


23개의 목적지별 샘플 (패킷 페이로드) 로그를 조회해보자. 목적지별 하나의 로그만을 가져와야 한다. 어떻게 하면 될까? Snort는 발생 순서대로 로그에 일련번호(cid)가 붙는다. 목적지별로 최초 또는 가장 최근 일련번호를 가진 로그만 가져오면 되겠다.

Snort 데이터베이스 스키마

다음은 목적지 및 sid(모니터링 NIC 일련번호)별로 가장 최근 cid값을 가져오는 내부 쿼리문을 실행한 결과. 모니터링하는 NIC가 항상 같다면 sid는 별 의미 없지만, 자주 바뀐다면 구분해야 한다. (그냥 항상 구분해주는 버릇을 들이는 게 편함)


다음은 내부 쿼리문의 결과값인 cid, sid와 같은 cid, sid를 가진 로그를 data테이블에서 불러온 결과.


사용한 쿼리문은 다음과 같으며, 내부 쿼리문의 결과값을 가상 테이블(d)로 지정한 후, data 테이블(e)과 sid, cid 조건으로 조인하는 구조이다.

select e.data_payload
from ( 
  select max(c.cid) as cid, c.sid as sid, inet_ntoa(c.ip_dst) as ip_dst
from event a, signature b, iphdr c
where b.sig_name = 'DELETED WEB-IIS header field buffer overflow attempt'
and a.signature = b.sig_id
and a.sid = c.sid and a.cid = c.cid
group by c.sid, c.ip_dst ) d, data e
where d.sid = e.sid and d.cid = e.cid

총 23개의 로그를 불러왔다. 그리고 해당 로그는 모두 3A, 0A, 00 패턴을 모두 가지고 있었다. 그러니까 탐지했겠지


사용한 검색 명령어는 다음과 같다.
  • VIM 정규표현식 : \(^\(..\)*\)\@<=\(3a\|0a\|00\)
  • 후방탐색을 이용해서 (하나 이상의) 2개의 임의 문자로 시작하거나 아예 없는 3A, 0A, 00 패턴을 찾는다.
  • '^\(..\)*'는 시작하는 문자가 (없거나 하나 이상의) 2개의 임의 문자
  • 이런 조건을 준 이유는 2개의 문자 조합으로 1byte를 이루는 HEX 구조상 정확한 검색을 위해서는 짝수 단위로 검사해야 하기 때문
  • PCRE 정규표현식 : (3a|0a|00)(?=(..)*$)
  • '(..)*$'는 끝나는 문자가 (없거나 하나 이상의) 2개의 임의 문자
  • PCRE는 전방탐색만 수량자 사용 가능

1byte 단위 검사 성공($ 사용)
1byte 단위 검사 실패($ 미사용)

to be continued..

관련 글

댓글 없음:

댓글 쓰기

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