그런데 중복을 제거해도 만 개가 넘는 HEX 데이터를 디코딩했더니 이 모양이다. 정상적인 웹 요청 트래픽은 일부에 불과하고 나머지 대부분의 로그는 분석은 커녕 아예 읽을 수가 없는 상황.
왜 이런 현상이 발생할까? 두가지 원인이 결합된 결과인데, 첫 번째 원인은 트래픽의 종류와 관계가 있다.
트래픽은 크게 이미지 등의 파일 전송과 문자열 전송으로 나눌 수 있으며, 더 고급진 표현을 쓰자면 Byte Stream과 Character Stream으로 나눌 수 있는데, 이렇게 전송된 데이터는 전송을 주도한 애플리케이션에 의해 적절하게 변환되어 의미 있는 데이터가 된다.
이 때 Character Stream은 문자 인코딩 방식만 맞으면 애플리케이션에 구애받지 않고 해석할 수 있지만 Byte Stream은 그렇지 않다.
'노트패드'에서 'MS 워드 파일'을 열었을 때의 상황과 같다. 해석이 안되는 것. (문자 인코딩 방식이 맞지 않아 '한글'같은 비 영어권 문자열이 해석이 안된 채 깨져 보이는 경우도 있음)
두 번째 원인은
두 번째 원인은
TCP의 패킷 흐름 제어 방식이다. TCP의 Window 사이즈(수신 버퍼 크기)에 따라 데이터를 분할 전송하는 'Sliding Window' 방식에 의해, 다음처럼 'Request-Line(URI) + Header + Body' 구조를 갖추지 못한 패킷이 발생한다.
결국 해석이 안되는 로그는 대부분 분할된 'Body' 영역의 Byte Stream이 패턴 일치에 의해 탐지된 것으로 보인다.
'Request-Line(URI) + Header + Body' 구조를 갖추지 못한 로그는 몇 개나 될까? 'Header'와 'Body'의 구분자인 '0D0A0D0A' 또는 '0A0A' 패턴이 없는 로그는 모두 분할된 'Body' 영역을 전송하는 TCP Segment일 것이다.
물론 예외는 있다. 다음 그림을 보면 분할된 'Body' 영역에서도 '0D0A0D0A' 패턴이 사용되고 있다.
다음은 분할된 해당 트래픽을 'Follow TCP Stream' 기능을 이용해서 조합한 결과.
'0D0A0D0A' 패턴이 'Header'와 'Body' 구분 및 'Body' 영역의 데이터 시작 지점 구분을 위해 두 번 사용됐다. ('------WebkitForm...'으로 시작하는 문자열을 이용해서 전송하는 파일 데이터를 구분하는 듯)
결국 해석이 안되는 로그는 대부분 분할된 'Body' 영역의 Byte Stream이 패턴 일치에 의해 탐지된 것으로 보인다.
분할된 'Body' 영역을 전송하는 TCP Segment |
'Request-Line(URI) + Header + Body' 구조를 갖추지 못한 로그는 몇 개나 될까? 'Header'와 'Body'의 구분자인 '0D0A0D0A' 또는 '0A0A' 패턴이 없는 로그는 모두 분할된 'Body' 영역을 전송하는 TCP Segment일 것이다.
물론 예외는 있다. 다음 그림을 보면 분할된 'Body' 영역에서도 '0D0A0D0A' 패턴이 사용되고 있다.
다음은 분할된 해당 트래픽을 'Follow TCP Stream' 기능을 이용해서 조합한 결과.
'0D0A0D0A' 패턴이 'Header'와 'Body' 구분 및 'Body' 영역의 데이터 시작 지점 구분을 위해 두 번 사용됐다. ('------WebkitForm...'으로 시작하는 문자열을 이용해서 전송하는 파일 데이터를 구분하는 듯)
일단 '0D0A0D0A' 또는 '0A0A' 패턴이 없다는 얘기는 분할 전송 과정에서 발생한, 'Body' 영역만으로 이루어진 TCP Segment라는 뜻. 해당하는 로그는 10,435(85%)개이며, 헤더 영역을 검사하고자 하는 해당 룰의 목적에 부합하지 않는다. 즉 모두 오탐이다.
'0D0A0D0A' 또는 '0A0A' 패턴을 포함한 페이로드는 1,842(15%)개인데, 그 중 '485454502f312e(HTTP/1.)' 패턴이 없는, 즉 'Body' 영역으로만 이루어진 페이로드는 514개.
물론 '485454502f312e(HTTP/1.)' 패턴 이후에 분할될 가능성도 있으나, 변수나 Cookie 등의 값이 아주 크지 않은 이상 'Request-Line(URI) + Header' 영역이 분할 전송되는 경우는 드물기 때문에 해당 패턴이 없으면 'Body' 영역으로 판단했다. (웹 요청은 기본적으로 사이즈 제한이 없기 때문에 길이가 길 경우 어느 지점에서 분할될지는 사실상 알 수 없음)
결국 헤더 영역을 포함한 페이로드는 1,328개이며, 중복을 제거하면 387개.
관련 글
'0D0A0D0A' 또는 '0A0A' 패턴을 포함한 페이로드는 1,842(15%)개인데, 그 중 '485454502f312e(HTTP/1.)' 패턴이 없는, 즉 'Body' 영역으로만 이루어진 페이로드는 514개.
물론 '485454502f312e(HTTP/1.)' 패턴 이후에 분할될 가능성도 있으나, 변수나 Cookie 등의 값이 아주 크지 않은 이상 'Request-Line(URI) + Header' 영역이 분할 전송되는 경우는 드물기 때문에 해당 패턴이 없으면 'Body' 영역으로 판단했다. (웹 요청은 기본적으로 사이즈 제한이 없기 때문에 길이가 길 경우 어느 지점에서 분할될지는 사실상 알 수 없음)
결국 헤더 영역을 포함한 페이로드는 1,328개이며, 중복을 제거하면 387개.
해당 페이로드를 추출한 후, 'Request-Line(URI)'과 'Body' 영역을 삭제한 다음, 남아있는 'Header' 영역에서 '00' 패턴을 검사해봤는데 하나도 없다. 샘플 분석과 일치하는 결과.
첫 회에서 얘기했었지만 해당 룰은 문자열 패턴이 아닌 트래픽의 구조를 검사하는 관계로 문자열 맥락 분석이 필요없으며, 샘플링만으로도 전수검사와 같은 결과를 얻을 수 있다. (물론 넓은 의미에서 트래픽 구조 패턴의 맥락 분석이었지만)
하지만 항상 이런 결과가 나오리라는 장담은 할 수 없으며, 애석하게도 대부분의 룰은 문자열 패턴 위주로 동작하기 때문에, 신속함이 생명인 실시간 대응 측면의 샘플링과 후선 지원 측면의 전수검사를 병행할 수 있는 보안관제 체계 수립은 필수가 아닐까 한다. 문제는 그럴려면 사람이 많이 필요해서(..)
관련 글
댓글 없음:
댓글 쓰기