오래전 이야기/Network

TCPDUMP 깔끔 정리

리눅스 엔지니어였던 2011. 1. 11. 10:45

 Tcpdump

 tcpdump_output.jpg


l        S: SYN (Synchronize sequence numbers – 연결 요청)

l        F: FIN (보낸 쪽에서 연결을 종료 – 정상적인 연결 종료)

l        R: RST (비정상적으로 즉시 연결 종료)

l        P: PSH (데이터를 즉시 어플리케이션으로 전달)

l        Urg: (긴급한 데이터에 우선순위를 높게 줌)

l        ‘.’: (SYN, FIN, RESET, PUSH가 아닌 경우로 flag가 설정되지 않았다)

 

 명령어 분석

       tcpdump [ -adeflLnNOpqRStuUvxX ] [ -c count ]
               [ -C file_size ] [ -F file ]
               [ -i interface ] [ -m module ] [ -M secret ]
               [ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]
               [ -W filecount ]
               [ -E spi@ipaddr algo:secret,...  ]
               [ -y datalinktype ] [ -Z user ]
               [ expression ]

옵션
  • -h: 버전 및 기본 사용법을 보여준다.
  • -a : Network & Broadcast 주소들을 이름들로 바꾼다.
  • -c Number : 제시된 수의 패킷을 받은 후 종료한다.
  • -d : compile된 packet-matching code를 사람이 읽을 수 있도록 바꾸어 표준 출력으로 출력하고, 종료한다.
  • -dd : packet-matching code를 C program의 일부로 출력한다.
  • -ddd : packet-matching code를 숫자로 출력한다.
  • -e : 출력되는 각각의 행에 대해서 link-level 헤더를 출력한다.
  • -f : 외부의 internet address를 가급적 심볼이 아닌 숫자로 출력한다.(Sun의 yp server와의 사용은 가급적 피한다.)
  • -F file : filter 표현의 입력으로 파일을 받아들인다. 커맨드라인에 주어진 추가의 표현들은 모두무시된다.
  • -i device : 어느 인터페이스를 경유하는 패킷들을 잡을지 지정한다. 지정되지 않으면인터페이스 리스트를 검색하여 가장 낮은 번호를 가진 인터페이스를 선택
  • -l : 표준 출력으로 나가는 데이터들을 line buffering한다. 다른 프로그램에서 tcpdump로부터 데이 터를 받고자 할 때 유용하다.
    • 보통 'tcpdump -l | tee dat' 나 'tcpdump -l < dat & tail -f dat' 명령으로 연계해서 사용하면 편리하다.
  • -n : 모든 주소들을 번역하지 않는다(port,host address 등등)
  • -N : 호스트 이름을 출력할 때, 도메인을 찍지 않는다.
  • -O : packet-matching code optimizer를 실행하지 않는다. 이 옵션은 optimizer에 있는 버그를 찾을때나 쓰인다.
  • -p : 인터페이스를 promiscuous mode로 두지 않는다.
  • -q : 프로토콜에 대한 정보를 덜 출력한다. 따라서 출력되는 라인이 좀 더 짧아진다.
  • -r file : 패킷들을 '-w'옵션으로 만들어진 파일로 부터 읽어 들인다. 파일에 "-" 가 사용되면 표준입력을 통해서 받아들인다.
  • -s length: 패킷들로부터 추출하는 샘플을 default값인 68Byte외의 값으로 설정할 때 사용한다.
  • -T type : 조건식에 의해 선택된 패킷들을 명시된 형식으로 표시한다.
    • type에는 다음과 같은 것들이 올 수 있다.
      • rpc(Remote Procedure Call), rtp(Real-Time Applications protocol), rtcp(Real-Time Application control protocal), vat(Visual Audio Tool), wb(distributed  White Board)
  •  -S : TCP sequence번호를 상대적인 번호가 아닌 절대적인 번호로 출력한다.
  •  -t : 출력되는 각각의 라인에 시간을 출력하지 않는다.
  •  -tt : 출력되는 각각의 라인에 형식이 없는 시간들을 출력한다.
  •  -v : 좀 더 많은 정보들을 출력한다.
  •  -vv : '-v'보다 좀 더 많은 정보들을 출력한다.
  •  -vvv : 16진수값 형태로 정보를 보여준다. 보통 -X옵션과 사용되어
  •  -w : 캡춰한 패킷들을 분석해서 출력하는 대신에 그대로 파일에 저장한다.
  •  -x : 각각의 패킷을 헥사코드로 출력한다.
  •  -X : 헥사코드와 ascii형태 모두 출력해준다. 보통 -x 옵션과 같이 사용된다.
조건식(expression)

  옵션의 제일 마지막인 조건식은 어떤 패킷들을 출력할 지를 선택하는 데 쓰인다. 조건식이 주어지지 않는다면 모든 패킷들이 대상이 된다. 조건식들은 하나 또는 여러 개의 primitive들로 구성되어 있고 primitive들은 다시 하나 또는 여러 개의 qualifier들 다음에 오는 하나의 값으로 이루어진다.

 

qualifier
  • type : 주어진 값의 종류가 무엇인지를 나타낸다.
    • 가능한 type들은 'host', 'net', 'port'가 있다.type이 없는 값들은 type을 host라 가정한다.
  • dir : id로 부터의 어떤 특정한 전송 방향을 나타낸다.
    • 가능한 방향은 'src', 'dst', 'src or  dst', 'src and dst'이다. 만약 방향이 정해지지 않았다면, src or dst라 가정한다. "For `null' link layers (i.e. point to point protocols such as slip) the inb ound and out  bound qualifiers can be used to specify a desired direction."
  • proto : 매칭을 특정 프로토콜에 한해서 수행한다. 가능한 프로토콜들은 ether, fddi, ip, arp, rarp, decnet, lat, sca, moprc, mopdl, tcp, udp이다. 만약 프로토콜이 명시되지 않았다면, 해당하는 값의 type에 관련된 모든 프로토콜들이 그 대상이 된다
  • 위의 패턴을 따르지 않는 primitive : gateway, broadcast, less, greater, 산술식이 있으며 참고로 더 정교한 조건식을 사용하려면 'and(&&)','or(||)','not(!)'을 사용할 수 있다.

 

사용가능한 primitive들
  • dst host HOST    => packet의 IP destination 항목이 HOST일때 참이 된다.
  • src host HOST    => packet의 IP source 항목이 HOST일때 참이 된다.
  • host HOST    => IP source, IP destination 항목 중 어느 하나라도 HOST이면 참이다.
  • ether dst ehost    => ethernet destination 주소가 ehost일 때 참이다.
  • ether src ehost    => ethernet source 주소가 ehost일 때 참이다.
  • ether host ehost    => ethernet source, destination 항목들 중 어느 하나라도 ehost이면 참이다.
  • gateway host    => 패킷이 host를 게이트웨이로 사용하면 참이다.
    • 이 말의 의미는 ethernet sour ce나 destination 항목은 host이지만, IP source와 destination은 host가 아닐 때를 말한다.
  • dst net NET    => 패킷의 IP destination 주소가 NET의 network number를 가지고 있을 때 참이다.
  • src net NET    => 패킷의 IP source 주소가 NET의 network number를 가지고 있을 때 참이다.
  • net NET    => 패킷의 IP source 주소 혹은 destination 주소가 NET의 network number를 가 지고 있을 때 참이다.
  • net netmask mask    => IP 어드레스가 지정된 netmask를 통해서 net과 매칭되면 참이다.
  • net net/len    => IP 어드레스가 netmask와 len 비트만큼 매치되면 참이다.
  • dst port PORT    => 패킷이 ip/tcp, ip/udp 프로토콜의 패킷이고 destination port의 값이 PORT일 때 참이다.
  • src port PORT    => 패킷의 source port의 값으로 PORT를 가지면 참이다.
  • port PORT    => 패킷의 source, destination port 중에 하나라도 PORT이면 참이다.
  • less length => 패킷이 length보다 짧거나 같으면 참이다.(len <= length)
  • greater length => 패킷이 length보다 짧거나 같으면 참이다.(len >= length)
  • ip proto protocol => 패킷이 지정된 종류의 프로토콜의 ip패킷이면 참이다.
    • Protocol은 icmp, igrp, udp, nd, tcp 중의 하나 혹은 몇 개가 될 수 있다. 주의할 점은 tcp, udp, icmp들은 '\'로 escape되어야 한다.
  • ehter broadcast => 패킷이 ethernet broadcast 패킷이라면 참이다. ehter는 생략 가능하다.
  • ip broadcast => 패킷이 IP broadcast 패킷이라면 참이다.
  • ether multicast => 패킷이 IP multicast 패킷이라면 참이다.
  • ether proto protocol => 패킷 이 ether type의 protocol이라면 참이다.
    • protocol은 ip, arp, rarp 중에 하나 혹은 몇개가 될 수 있다. ip proto protocol에서와 마찬가지로 ip, arp, rarp는 escape 되어야 한다.
  • decnet src host => 만약 DECNET의 source address가 host이면 참이다.
  • 이 어드레스는 '10.123'이 나 DECNET의 host name일 수 있다. DECNET host name은 DECNET에서 돌아가도록 설정된 Ultrix 시스템에서만 사용 가능하다.
  • decnet dst host => DECNET destination address가 host이면 참이다.
  • decnet host HOST => DECNET source, destination address중의 하나라도 HOST이면 참이다.
  • ip, arp, rarp, decnet => ether proto [ip|arp|rarp|decnet]의 약어
  • lat, moprc, mopdl => ether proto [lat|moprc|mopdl]의 약어
  • tcp, udp, icmp => ip proto [tcp|udp|icmp]의 약어
  • expr relop expr
    • EXPR
    • proto [expr:size]의 형식을 띤다. proto, expr, size에 올 수 있는 것들은 다음과 같다.
      •   proto : ether, fddi, ip, arp, rarp, tcp, udp, icmp
      •   expr : indicate Byte offset of packet of proto
      •   size : optional. indicate the size of bytes in field of interest
      •   default is one, and can be two or four
    •   RELOP
      • !=, =, <=, >=, etc.

 

이 조건식을 사용하기 위해서는 먼저 해당하는 Protocol(proto)의 헤더에 관련된 것들을 자세히 알아야만 한다. proto에는 대상이 될 프로토콜을 지정한다. expr에는 프로토콜 헤더의 처음부터의 Byte Offset을 지정하는 식이 들어가게 된다. Size는 Option이며 지정이 안 되어 있을 경우에는 자동으로 1byte를 지칭한다. 따라서 이 조건식을 사용하게 되면 헤더에 포함된 정보를 Bitmask를 사용하여 직 접 원하는 패킷인지를 가려낼 수 있기 때문에, 보다 정밀한 사용이 가능하게 된다.

 

TCPDUMP 사용 예제

  • security라는 호스트로부터 날아오고, 날아가는 패킷들을 출력      # tcpdump host security
  • security와 mazinga, getarobo 사이에 날아다니고 있는 패킷들을 출력      # tcpdump host security and \( mazinga or getarobo \)
  • security에서 elgaim을 제외한 모든 호스트로 날아다니는 IP 패킷들을 출력      # tcpdump ip host security and not elgaim
  • gateway amurorei를 거치는 ftp에 관련된 패킷들을 출력      # tcpdump 'gateway amurorei and ( port ftp or ftp-data )'
  • local호스트가 아닌 호스트와 로컬호스트가 맺는 TCP 커넥션의 시작과 마지막 패 킷들을 출력한다(SYN, FIN 패킷).      # tcpdump 'tcp[13] & 3 != 0 and not src and dst net non-local'
  • gateway amurorei를 지나는 576Byte보다 큰 패킷들을 출력한다      # tcpdump 'gateway amurorei and ip[2:2] > 576'
  • Ethernet boradcast 혹은 multicast를 통해서 보내진 것이 아닌, IP broadcast 혹 은 multicast 패킷들을 출력한다.      # tcpdump 'ehter[0] & 1 = 0 and ip[16] >= 224'
  • Echo request/reply가 아닌 ICMP 패킷들을 모두 출력한다.      # tcpdump 'icmp[0] != 8 and icmp[0] != 0'

 

mytcpdump 예제

출처 : http://www.awarenetwork.org/home/iqlord/exploits/collection/knu.c  [mytcpdump]

 

Pcap 라이브러리

pacp_open_live() : 네트워크 디바이스 열기

pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)

  • device : 디바이스 이름 (eth0, hme0)
  • snplen : 한번에 캡쳐할 크기 지정
  • promisc : 캡쳐할 대상
    • 0 : 목적지가 자신, 브로드 캐스트, 자신포함한 멀티 캐스트
    • 1 : 모든 패킷
  • to_ms : 버퍼링 시간, 패킷 도착후 OS가 처리 대기 시간
    • 0 : 충분히 패킷 도착 할떄 까지 대기
  • ebuf : 에러 발생시 원인 저장

성공시 pcap_t 타입의 디바이스 디스크립터, 실패시 null

 

pcap_lookupdev() : 패킷 캡쳐 할수 있는 디바이스 찾기

char *pcap_lookupdev (char *ebuf);

  • ebuf : 에러 발생시 원인 저장

성공시 디바이스 이름 반환

 

 

pcap_loop() : 패킷 캡쳐 함수   (pcap_dispatch와 비슷)

int pcap_loop(pcap_t *p, int maxcnt, pcap_handler callback, u_char *args);

  • *p : pcap 디스크립터
  • maxcnt : 캡쳐할 최대 수
  • callback : 패킷 읽어 드린후 처리 하기 위해 내부적으로 호출하는 콜백 함수
  • args : callback 함수의 인자

 

 callback 함수의 사용 문법

void (*pcap_handler)(u_char *args, const struct pcap_pkthdr *, const u_char *packet);

  • args : pcap_loop()에서 넘겨 받은 인자
  • pcap_pkthdr : 캡쳐한 패킷의 길이나 시간 관련 정보

    struct pcap_pkthdr {
         struct timeval ts;      /* time stamp */
         bpf_u_int32 caplen;     /* length of portion present */
         bpf_u_int32 len;        /* length this packet (off wire) */
 };

  • packet : 캡쳐된 데이터의 첫 부분을 가르키는 포인터

 

 관련 사이트


참고 : 옵션 처리 함수 getopt 

The getopt and getopt_long functions automate some of the chore involved in parsing typical unix command line options.

한글 설명 : http://man.kldp.org/wiki/ManPage/getopt.3


==================
<출처 : http://adioshun.springnote.com/pages/271475 >