2015년 11월 30일 월요일

Snort 분석(WEB-MISC Checkpoint Firewall-1 HTTP parsing format string vulnerability attempt - 3rd)

지난 글에 이어서 룰 개선을 시도해보자.

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS 
(msg:"WEB-MISC Checkpoint Firewall-1 HTTP parsing format string vulnerability attempt"; 
flow:to_server,established; 
content:"|3A|/"; offset:11; http_uri; 
pcre:"/^[^\x3a\x3f]{11,}(?<!resource|http|https)\x3a\x2f/Usmi";
  • 부정형 후방탐색을 이용해서 'resource, http, https'로 시작하지 않는 '3A2F' 패턴만 탐지
  • 부정형 전/후방탐색을 혼용해서 'resource'로 시작하지 않고, '2F(/)'로 끝나지 않는 '3A2F' 패턴만 탐지하는 '(?<!resource)\x3a\x2f(?!\x2f)' 표현식도 가능
metadata:service http; reference:bugtraq,9581; reference:cve,2004-0039; reference:nessus,12084; classtype:attempted-admin; sid:2381; rev:14;)

PCRE 옵션에서 'resource, http, https'로 시작하는 '3A2F' 패턴을 탐지하지 않고, 회피하도록 했다. 룰을 내 PC에서 발생하는 트래픽에 최적화한 것.

이러면 뭐가 좋을까?

오탐 분석하느라 낭비했던 시간을 줄일 수 있고, 줄인만큼의 시간을 공격 분석하는 데 쓸 수 있다. 보안 장비가 있음에도 공격을 놓치는 상황을 줄일 수 있고, 더 빠른 대응이 가능해지는 것이다.

비싼 보안장비를 도입해놓고 공격 패턴만을 특징화한 룰을 그대로 사용하는 것은 수선하지 않은 기성복을 입는 것과 같다. 불편하고 보기에도 별로. 몸에 맞지 않는 옷이 거추장스러운 것처럼, 트래픽에 최적화되지 않은 룰은 보안관제 업무를 방해하는 골칫덩이가 될 뿐이다.

패션의 완성은 핏

룰 개선이 식은 죽 먹기처럼 끝나버렸다. 왜 이렇게 쉬울까? 로그 발생 현황, 공격 및 오탐 패턴의 발생 현황이 파악됐기 때문이다.

패턴 발생 현황이란 명확한 근거가 마련된 것. 근거가 생겼으니 그 근거를 그대로 룰에 반영해주면 된다. 공격은 더 정확하게 탐지하고, 오탐은 더 정확하게 회피하도록 수정만 해주면 되는 것이다.

그러나 기존 탐지로그 패턴의 발생 양상을 고작 한 번 반영했다고 해서 룰이 완벽해진다는 보장은 없으며, 그런 걸 바라서도 안된다.

향후 공격의 변화, 또는 트래픽의 변화에 따라 공격 및 오탐 패턴의 발생 양상은 얼마든지 달라질 수 있기 때문. 그래서 룰 개선은 절대 한 번으로 끝나서는 안되며, 한 번으로 끝나지도 않는다. 지속적인 사후관리가 필요하며, 지속적 관리를 위한 전담 조직 역시 필수인 것.

'패턴 매칭'을 능가하는 방식이 나타나지 않는 한, 수많은 데이터 속에서 원하는 데이터, 원하는 패턴만을 찾는 작업은 지속될 것이며, 그 작업의 성패는 결국 불필요한 '노이즈'를 얼마나 효과적으로 제거하느냐에 달려 있다.

물론 그 작업이 쉽지는 않다. 하지만 세상만사가 다 그렇듯 처음 한 번이 어렵지, 두 번째부터는 꽤 쉬워진다.


룰 사후관리의 중요성을 강조하면서 훈훈하게 끝낼까 하는데 뭔가 좀 아쉽다. (친구 결혼식 갔다가 신부 친구들 못보고 오는 기분?) 

로그 발생 양상이 좀 이상하다

룰의 핵심 탐지패턴은 '3A2F(:/)'였다. 즉 16진수에 대응하는 문자로 디코딩했을 때 ':/' 패턴 하나만을 탐지한다. 그런데 발생한 로그에서 확인된 탐지패턴은 여섯 개. 무슨 조화일까?


URL 인코딩 수준이 가장 복잡한 '%25253A%25252F' 패턴의 16진수는 '25:32:35:32:35:33:41:25:32:35:32:35:32:46'이다. '3A2F' 패턴이 없는데 어떻게 탐지했을까?

HEX 디코딩 전

HEX 디코딩 후

Snort는 아스키코드 체계에서 16진수에 대응하는 문자가, 읽을 수 있는 문자일 때는 룰 패턴에 16진수를 사용하더라도 내부적으로 문자로 저장한다고 한다. '3A2F'를 룰 패턴으로 등록해도 ':/'로 동작한다는 것.

하지만 여전히 ':/' 패턴은 '%25253A%25252F' 패턴과 전혀 일치하지 않는다. 어떻게 탐지했을까? Snort는 인코딩된 HTTP 트래픽을 다시 디코딩해주는 'http_inspect'라는 전처리 기능을 가지고 있다.

결국 '%25253A%25252F'를 포함한 다섯 개의 인코딩된 패턴은 'http_inspect' 전처리기에 의해 ':/' 패턴으로 디코딩된 후, 룰 패턴과 대조 작업을 거쳐서 탐지가 이루어진 것이다. 이런 걸 다 고려하다니, 무서운 개발자들 -_-

중복 인코딩이 발생한 URL

그나저나 전부 내가 웹서핑하는 과정에서 발생한 트래픽이니, 여태 두 번 이상의 URL 인코딩은 악의적인 조작이거나 최소 정상은 아닌 줄 알았는데 그것도 아닌가 보다. 두 번 이상의 URL 인코딩 패턴을 포함한 트래픽은 어느 웹사이트에 접속하다 발생했을까?


목적지 IP를 포함한 정보를 추출한 후, 텍스트 정규화 및 엑셀의 '피벗 테이블' 기능을 이용하면 탐지패턴과 목적지 IP, Host 등의 정보를 조합한 다양한 관계 분석을 해볼 수 있다.


확인 결과 ':/, %3A/, %3A%2F' 패턴은 51개의 목적지 IP와 최소 22개의 URL 접속 과정에서, '%253A%2F, %253A%252F, %25253A%25252F' 패턴은 7개의 목적지 IP와 최소 4개의 URL 접속 과정에서 발생했으며, 중복되는 IP나 URL은 하나도 없었다.

목적지 URL 분포를 보면 이미지 링크나 광고 등 직접 접속보다는 직접 접속한 웹사이트에 링크된 URL 때문에 발생한 간접 접속이 대부분이다.

웹서버를 어떻게 구현하면 URL 인코딩을 두 번 이상 하는지 궁금하긴 하지만, 이번에도 결론은 난 잘못한 거 없음(..)


나가며

평소 사고 분석이 아닌, 데이터 분석 관점의 접근이 필요함을 강조하는 이유는 데이터만 잘 정리하면 그 데이터의 통계나 관계에서 많은 의미를 발견할 수 있기 때문이다. 

하둡같은 걸 쓰니까 빅데이터가 아니라 분석을 통해 의사 결정에 도움이 되어야 빅데이터라는 얘기. 이런 빅데이터 성공하려면 분석 대상 데이터가 왜 생기는지, 어떻게 생기는지에 대한 충분한 이해가 필수.

'신호와 소음' 중

빅데이터가 유행하기 전에도 관심을 안 줘서 그렇지, 데이터베이스에 데이터는 많았다. 그래서 빅데이터가 거품도 있지만, 덕분에 데이터에 대한 관심이 높아진 것만은 사실이며, 정말 다행스러운 일이라 생각한다. 이제 남은 건 데이터랑 친해지는 일뿐.

관련 글

댓글 없음:

댓글 쓰기

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