2015년 9월 15일 화요일

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

소시적 50만원 넘는 주차위반 과태료를 내본 적은 있지만 비교적 착하게 살고 있다고 자부하는 나를 Snort는 왜 웹서버 공격자로 판단했을까?

그때 생각하니까 또 빡치네

내가 뭘 했길래? 트래픽의 성격을 파악해보자. 어디에서(Referer), 어디로(Host), 어떤 도구(User-Agent)를 이용해서, 어떤 정보(URI)를 전송했는지 알 수 있는 로그는 웹 요청 형식을 갖춘, 즉 '485454502f312e' 패턴을 포함하고 있는 387개.

해당 로그에서 URI, Referer, Host, User-Agent 정보를 순서대로 추출해보자. 순서대로 VIM에서 '검색 > 치환 > 복사'를 반복하면 된다.

URI를 제외한 영역 검색

URI를 제외한 영역 삭제

엑셀로 붙여넣기

URI 영역 추출은 간단했지만 나머지는 좀 복잡하다. 추출하고자 하는 영역을 제외한 (좌우에 위치하는) 나머지 영역을 삭제하려면 두 번 작업을 해야하기 때문인데, 구분기호를 추가한 후 엑셀의 '데이터 > 텍스트 나누기' 기능을 이용하면 훨씬 수월하게 원하는 작업할 수 있다.

Referer 영역에 구분기호 'ㅋ' 추가

Referer는 '과거 URI'를 의미하며, 값으로 사용되는 정보에 공백이 들어가지 않는다. 이런 특성때문에 비교적 간단한 정규표현식으로 검색이 가능하며, 이 특성은 Host에도 똑같이 적용된다.
  • VIM 정규표현식 : \(referer:\s\)\@<=\S\
  • PCRE 정규표현식 : (?<=referer:\s)\S+
  • 'referer:공백공백이 아닌 문자1개 이상' 문자열을 검색하되, 후방탐색을 이용해서 'referer:공백'은 검색 결과에서 제외
  • '\+'는 '\S'를 최대한 검색하며, '\S'가 안나오면, 즉 '\s'가 나오면 검색 중단



엑셀로 추출값을 붙여넣은 결과를 보면 구분기호(ㅋ)에 의해 데이터가 B, C, D 3개의 열로 분리되었는데, 그냥 봐서는 뭐가 뭔지 잘 모르겠다.


그러나 다음 그림처럼 '홈 > 필터' 기능을 이용하면 Referer 영역의 분리 현황을 정확하게 알 수 있다. B와 D열은 필요없으니 삭제.

참고로 Referer 정보가 23개 뿐인데, Referer와 같은 지시자 정보를 표시하지 않는다고 해서 잡혀가지도 않을 뿐더러, 최초 웹 요청이라 '과거 URI'를 의미하는 Referer 정보가 없을 수도 있기 때문이다.


다음은 Host 정보 추출까지 끝난 결과.


이제 User-Agent 정보만 추출하면 되는데, 이건 좀 더 까다롭다. 일단 값에 공백이 들어가며, 모든 문자 표현이 가능하기 때문에 User-Agent 정보 문자열과 나머지 문자열의 구분이 안된다.

다음은 정규표현식 'User-Agent:.'에 의해 'User-Agent:공백' 문자열까지 검색된 결과. ('.'은 '공백을 포함한 임의 문자'를 의미하는 정규표현식 메타문자)


'공백을 포함한 임의 문자'가 하나 이상이기 때문에 이를 검색하기 위해서 '\+'를 추가했더니 User-Agent 정보를 지나쳐서 끝까지, '공백을 포함한 임의 문자'가 더는 안나올 때까지 검색이 된다. '+, *' 등의 수량자는 기본적으로 최대한 검사하려는 특성이 있기 때문.


어떻게 하면 User-Agent 정보만을 검색할 수 있을까? User-Agent와 같은 지시자는 다음처럼 공백으로 지시자 간의 구분이 이루어진다. 그렇다면 User-Agent의 다음 지시자 앞에서, 즉 '공백제목:' 앞에서 검색을 멈추면 되지 않을까?


전방탐색 정규표현식 '\(\s\S\+:\)\@='을 사용해서 '공백하나 이상의 공백이 아닌 문자:'를 제외, 즉 해당 문자열 앞에서 검색을 멈추게 했더니 '공백Sec-WebSocket-Extensions:' 문자열 앞에서 멈췄다. 

제대로 된 건가 싶었는데 자세히 보니, 제외하고자 했던 형식인 '공백Accept-Encoding:', '공백Accept-Language:', '공백Sec-WebSocket-Key:' 문자열이 3개나 더 있다. 


의도하는 검색은 '공백Accept-Encoding:' 앞에서, 즉 해당 문자열이 나오기 전에 멈추는 것이다. 뭐가 문제일까? 수량자는 최대한 검사하려는 특성이 있다고 했다. 

사용된 전체 표현식 'user-agent:.\+\(\s\S\+:\)\@='에서 첫번째 '\+'가 '공백을 포함한 임의 문자' 다음에 '공백하나 이상의 공백이 아닌 문자:' 문자열이 더는 안나올 때까지 검사를 하는 것. 그렇다면 수량자의 검사 범위를 최소로 제한하면 되겠네?


PCRE의 수량자 '?'는 단독으로 사용하면 '없거나 한 개'의 의미지만 다른 수량자 뒤에 사용하면 먼저 사용된 수량자의 검사 범위를 최소로 제한한다.

VIM에서는 '\{-}'가 PCRE의 '*?'와 같은 의미이며, '공백을 포함한 임의 문자' 다음에 '공백하나 이상의 공백이 아닌 문자:' 문자열이 나오자마자 검색이 중지된다는 사실을 알 수 있다. 검사 범위가 최소로 제한된 것.

User-Agent 정보 추출 과정은 다음과 같으며, 후방탐색을 추가해서 User-Agent 지시자의 순수한 값만을 추출한 최종 결과는 다음과 같다.



'MICROSOFT_DEVICE_METADATA_RETRIEVAL_CLIENT'란 User-Agent에 의해 발생한 로그가 358개(93%)나 된다. 음 Microsoft가 날 감시하나? (물론 아닐테고 장치 관련 정보를 주고 받는 듯)



나머지 29개는 크롬 웹브라우저에 의해 발생한 트래픽인데 버전이 다 다르다. 자동 업데이트 설정 때문인 듯.


웹브라우저에 의해 접속한 Host 정보를 살펴보면, 네이버나 다음을 빼면 모두 광고 링크에 의해 자동으로 발생한 트래픽인 듯하다. 악성 링크는 없는 듯?


로그를 발생시킨 트래픽의 성격을 살펴봤다. 물론 이전 글에서 확인했듯이 가장 많은 로그를 발생시킨 건 첨부파일 트래픽이었지만, 웹 요청 트래픽의 구성 요소를 적절히 분류하면 트래픽 성격을 파악하는데 많은 도움이 된다는 사실을 알려주는 사례가 아닐까 한다.

관련 글

댓글 없음:

댓글 쓰기

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