2010년 2월 22일 월요일

PCAP 파일을 파헤쳐 보자 - 그 첫번째 이야기


패킷 분석을 하면서 가장 많이 듣는 단어중의 하나가 PCAP 이 아닐까 생각한다.
네트웍을 분석하다, 문제가 있다면 흔히 "그러면 PCAP 파일좀 전송해 달라고 한다"
PCAP 은 Packet Capture 의미로 네트워크 트래픽을 캡쳐하기 위한
API 로 구성이 되어 있다. 윈도우로 포팅되어 있는 것은 WinPcap 이며, 유닉스 환경에서는
libpcap 이다.

libpcap 과 winpcap 라이브러리를 이용하여 캡쳐된 패킷을 파일로 저장하거나,
저장된 패킷을 읽고 또는 다른 프로그램에서 라이브러리를 이용해 패킷파일을
분석/편집 등을 할 수 있다. 이를 이용한 대표적인 패킷 캡쳐 프로그램이 tcpdump 나
wireshark 이다.  

자 그럼, 여기서 자주 다루고 있는 패킷파일의 내부를 깊게 살펴 보자.

패킷파일은 크게 다음과 같은 포맷 형태로 구성이 되어 있다.

PCAP 파일헤더 | 패킷 헤더 | 패킷 데이터 | 패킷 헤더 | 패킷 데이터 | 패킷 헤더 | 패킷 데이터 | ... | ...

제일 처음에 PCAP 포맷을 뜻하는 헤더가 오고 이후 각 패킷의 헤더와 데이터 정보가
쌓이게 된다. 헤더 구조체는 아래와 같으며,

struct pcap_file_header {
        bpf_u_int32 magic;
        u_short version_major;
        u_short version_minor;
        bpf_int32 thiszone;     /* gmt to local correction */
        bpf_u_int32 sigfigs;    /* accuracy of timestamps */
        bpf_u_int32 snaplen;    /* max length saved portion of each pkt */
        bpf_u_int32 linktype;   /* data link type (LINKTYPE_*) */
};

매직넘버는 고정된 값으로 0xa1b2c3d4 이다. 버전 Major, Minor 는 패킷 파일 포맷 버전을
뜻하며,  thiszone, sigfigs 는 시간과 관련한 것이고 snaplen 은 캡쳐된 패킷의 길이 network 은
데이터 링크 타입이다.  패킷 헤더 레코드는 아래와 같다.

typedef struct pcaprec_hdr_s {
        guint32 ts_sec;         /* timestamp seconds */
        guint32 ts_usec;        /* timestamp microseconds */
        guint32 incl_len;       /* number of octets of packet saved in file */
        guint32 orig_len;       /* actual length of packet */
} pcaprec_hdr_t;

좀더 쉽게 설명하기 위해 아래 예제 화면을 보자. 제일 처음에 패킷파일 헤더인 매직넘버가 나오고, 패킷 헤더 시작부분과 실제 패킷 데이터 시작 부분을 볼 수 있다. 캡쳐된 패킷의 길이가 66 bytes 나오는데 패킷 데이터 시작 전 4바이트는 실제 패킷의 길이다. 0x00000042 를 계산해보면 66 값을 얻을 수 있다. 단지 위 구조체에 값을 맞춰보기만 하면 된다.

[그림] PCAP 파일 포맷 형태 예제

이 헤더가 끝난 다음 에 또 패킷 헤더와 데이터가 붙으며 계속 이런 구조로 저장이 되는 것이다. 알고보면 구조는 상당히 간단한 형태로 구성이 되어 있다. 파일의 첫 4 바이트만 보아도 아 ~ 패킷 파일인가 보다 하고 추측해 볼 수 있을 것이다. 더불어 외우기도 쉽지 않은가요. 1234 와 ABCD :-)

댓글 6개:

  1. 글 잘보고있습니다.전 이부분이 왜 이해가 안될까요?ㅠㅠ

    답글삭제
  2. @sylar - 2010/08/13 17:35
    생각보다 어렵지는 않습니다. 패킷파일 작은거 하나를 HEX 에디터로 열어 놓으시고, 와이어샤크를 통해서도 함께 보세요. 맨 처음의 매직넘버부터 해서 차례로 보신다면 충분히 이해가 되실것입니다. 값을 하나씩 매칭해서 보면 어렵지 않답니다. 화이팅 하세요 ! ^^

    답글삭제
  3. 안녕하세요 좋은 정보 잘 보고있습니다. 제가 리눅스와 C언어 초보인데 과제가 생겼습니다. Wireshark로 Packet을 capture해서 이 pcap화일을 분석하기 위해서 C++을 이용하여 프로그래밍을 해야합니다. 특히 link-layer가 무엇인지 확인하라는데 제가 정말 초보라 잘 모르겠어요. 어떻게 코딩을 해야하는지 설명이 가능하시면 부탁드립니다. 제 메일은 carlos.ta1980@gmail.com 입니다.

    답글삭제
    답글
    1. 메일로 보냈더니 메일이 리턴이 되네요. 다음 내용 참고하세요:

      제가 댓글을 늦게 확인하고 이제서야 메일을 드립니다.
      일단 프로그램 하신다고 하면 libpcap 라이브러리를 이용하시면 됩니다.

      그리고 문의주신 링크레이어는 이렇게 이해하시면 됩니다. 크게 레이어가 4단계 정도로 구성됩니다.

      데이터링크, 네트워크, 트랜스포트, 애플리케이션

      데이터링크는 맥주소 정보가 들어갑니다. 목적지, 출발지 의 각 맥 주소 6바이트씩 그리고 IP Type 정보가 포함됩니다. 네트워크는 IP 정보가 들어가고 트랜스포트는 TCP,UDP 마지막으로 애플리케이션은 HTTP, DNS 와 같은 응용프로그램 프로토콜이 포함됩니다.

      문의하신 링크레이어는 맥 주소쪽 부분을 의미합니다. 막상 해 보시면 패킷 구조 자체도 어렵지는 않습니다. 이미 설명해 놓은 Scapy 같은 도구를 이용하시면 더욱 편하실텐데 아직 libpcap 으로 아직 포스팅 해 놓은것이 없네요. 일단 다음 문서를 참고하세요.

      http://recursos.aldabaknocking.com/libpcapHakin9LuisMartinGarcia.pdf

      좋은 하루 되세요.

      삭제
    2. 정말 감사드립니다. 항상 좋은 정보 보고 갑니다. 네트워크 보안은 처음 듣는 수업인데 많은 도움이 되고 있습니다.

      삭제
    3. 좋은 답변 감사드립니다. 좋은 정보 잘 보고 있습니다.

      삭제