본문 바로가기

공부/리눅스

tcpdump - packet capture / 분석

반응형
tcpdump - dump traffic on a network http://www.tcpdump.org/

tcpdump 는 네트워크 인터페이스상의 패킷 헤더를 출력한다.
그리고 파일로 출력하여 분석해 볼수도 있다. 파일로 출력할 경우에는 -w 옵션을 사용하며
저장된 파일내용을 볼때는 -r 옵션을 사용한다.

tcpdump 는 패킷을 캡쳐할 카운터를 지정하지 않는 경우에는 SIGINT 또는 SIGTERM signal 을 받을때까지
계속 실행된다.

tcpdump 사용법

tcpdump --help
tcpdump version 3.9.4
libpcap version 0.9.4
Usage: tcpdump [-aAdDeflLnNOpqRStuUvxX] [-c count] [ -C file_size ]
[ -E algo:secret ] [ -F file ] [ -i interface ] [ -M secret ]
[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]
[ -W filecount ] [ -y datalinktype ] [ -Z user ]
[ expression ]
[root@centos1 ~]#

ex)
tcpdump -i eth0 -w /tmp/tcpdump.pkt ; eth0 으로 패킷캡처하여 파일로저장
tcpdump -r /tmp/tcpdump.pkt ; 저장된 파일 모니터로 출력.
tcpdump -i eth0 -c 10 ; 10개만 캡처.
tcpdump -w /tmp/tcpdump.pkt -s 1500 tcp port 21 and host client
-s 1500 ; 캡처할 패킷길이(1500 byte 는 전체길이를 뜻한다)
tcpdump host client
tcpdump -nn host client and port 21
tcpdump -nne host client and port 21

[root@centos1 ~]# tcpdump -n host 192.168.100.100 and port 23 -w /tmp/tcpdump.pkt
[root@centos1 ~]# tcpdump -r /tmp/tcpdump.pkt | head -4
reading from file /tmp/tcpdump.pkt, link-type EN10MB (Ethernet)
20:09:51.200931 IP 192.168.100.100.59708 > 192.168.100.1.telnet: S 3013182863:3013182863(0) win 5840
20:09:51.205507 IP 192.168.100.1.telnet > 192.168.100.100.59708: S 3185271194:3185271194(0) ack 3013182864 win 5792
20:09:51.211135 IP 192.168.100.100.59708 > 192.168.100.1.telnet: . ack 1 win 92

20:09:52.719159 IP 192.168.100.1.telnet > 192.168.100.100.59708: P 1:13(12) ack 1 win 91

옵션설명
-n : Don’t convert host addresses to names. This can be used to avoid DNS lookups.
호스트 이름을 도메인 또는 호스트이름으로 풀이하지 않고 ip 주소로 출력해준다.
DNS 를 찾지 않으면 그만큼의 트래픽을 줄일 수 있다.

20:09:51.200931 : 패킷수집시간
192.168.100.100.59708 > 192.168.100.1.telnet : source ip.포트번호 > destination ip.포트번호(또는 서비스이름)
*. 포트번호가 /etc/services 파일에 등록이 되어 있는경우라면 서비스이름으로 표시된다.
S : 패킷 Sequence number
win 5840 mss 1460 : max-segment-size
sackOK :
nop:

패킷 flag
S : SYN - 연결요청
F : FIN - 연결종료요청
R : RST - 즉시연결종료
P : PSH - 프로세스로 데이터전송
U : URG - 긴급한 데이터에 데이터전송 우선순위를 할당.
. : flag 가 설정되지 않았음.

*. 패킷출력내용중 세번째 라인까지가 3way hand-shaking 이다.
* 네번째 라인부터는 데이터 전송.

[root@centos1 ~]# tcpdump -r /tmp/tcpdump.pkt | tail -5
reading from file /tmp/tcpdump.pkt, link-type EN10MB (Ethernet)
20:10:12.538184 IP 192.168.100.1.telnet > 192.168.100.100.59708: P 1075:1082(7) ack 106 win 91
20:10:12.543157 IP 192.168.100.100.59708 > 192.168.100.1.telnet: . ack 1082 win 159
20:10:12.674086 IP 192.168.100.1.telnet > 192.168.100.100.59708: F 1082:1082(0) ack 106 win 91
20:10:12.686700 IP 192.168.100.100.59708 > 192.168.100.1.telnet: F 106:106(0) ack 1083 win 159
20:10:12.688650 IP 192.168.100.1.telnet > 192.168.100.100.59708: . ack 107 win 91

[root@centos1 ~]#

* 패킷 출력 결과중 끝에서 3번째 라인부터가 접속종료 과정이다.

비활성화 되어 있는 서비스로 접속할 경우

[root@centos1 ~]# tcpdump -n host 192.168.100.100 and port 23 -w /tmp/tcpdump2.pkt
[root@centos100 ~]# telnet 192.168.100.1
Trying 192.168.100.1...
telnet: connect to address 192.168.100.1: Connection refused
telnet: Unable to connect to remote host: Connection refused
[root@centos100 ~]#
[root@centos1 ~]# tcpdump -r /tmp/tcpdump20.pkt
reading from file /tmp/tcpdump20.pkt, link-type EN10MB (Ethernet)
20:44:35.063400 IP 192.168.100.100.56378 > 192.168.100.1.telnet: S 787328461:787328461(0) win 5840
20:44:35.067331 IP 192.168.100.1.telnet > 192.168.100.100.56378: R 0:0(0) ack 787328462 win 0
[root@centos1 ~]#

*. 서버측에서 Sequence number 로 응답하는대신 R flag 를 세팅하여 보내고 클라이언트측에서 그 패킷을 받는 즉시 연결종료된다.

방화벽에 막혀있는경우
[root@centos1 ~]# iptables -F
[root@centos1 ~]# iptables -A INPUT -s 192.168.100.100 -p tcp --dport telnet -j DROP
[root@centos1 ~]# tcpdump -n host 192.168.100.100 and port 23 -w /tmp/tcpdump3.pkt
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

[root@centos100 ~]# telnet 192.168.100.1
Trying 192.168.100.1...
telnet: connect to address 192.168.100.1: Connection timed out
telnet: Unable to connect to remote host: Connection timed out
[root@centos100 ~]#

[root@centos1 ~]# tcpdump -r /tmp/tcpdump4.pkt
reading from file /tmp/tcpdump4.pkt, link-type EN10MB (Ethernet)
20:58:16.099647 IP 192.168.100.100.43630 > 192.168.100.1.telnet: S 1498268765:1498268765(0) win 5840
20:58:20.900736 IP 192.168.100.100.43630 > 192.168.100.1.telnet: S 1498268765:1498268765(0) win 5840
20:58:27.744399 IP 192.168.100.100.43630 > 192.168.100.1.telnet: S 1498268765:1498268765(0) win 5840
20:58:40.580851 IP 192.168.100.100.43630 > 192.168.100.1.telnet: S 1498268765:1498268765(0) win 5840
20:59:08.779405 IP 192.168.100.100.43630 > 192.168.100.1.telnet: S 1498268765:1498268765(0) win 5840
21:00:05.366996 IP 192.168.100.100.43630 > 192.168.100.1.telnet: S 1498268765:1498268765(0) win 5840
[root@centos1 ~]#

*. 클라이언트가 같은 패킷을 계속 보내지만 서버가 응답하지 않는다.

[root@centos1 ~]# iptables -F
[root@centos1 ~]# iptables -A INPUT -s 192.168.100.100 -p tcp --dport telnet -j REJECT ; REJECT 로 거부할 경우.

[root@centos1 ~]# tcpdump -n host 192.168.100.100 and port 23 -w /tmp/tcpdump5.pkt
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

root@centos100 ~]# telnet 192.168.100.1
Trying 192.168.100.1...
telnet: connect to address 192.168.100.1: Connection refused
telnet: Unable to connect to remote host: Connection refused
[root@centos100 ~]#

[root@centos1 ~]# tcpdump -r /tmp/tcpdump5.pkt
reading from file /tmp/tcpdump5.pkt, link-type EN10MB (Ethernet)
21:05:06.955754 IP 192.168.100.100.51055 > 192.168.100.1.telnet: S 1879397660:1879397660(0) win 5840
[root@centos1 ~]#

*. DROP 과 다른점이 없어보인다. 차이가 있다면 클라이언트가 패킷을 하나만 보내고 끝난다.

udp를 기반으로 하는 서비스인경우
[root@centos1 tftpboot]# tcpdump -n host 192.168.100.100 and port 69 -w /tmp/tcpdump9.pkt

[root@centos100 temp2]# tftp 192.168.100.1 -c get a.txt
[root@centos1 tftpboot]# tcpdump -r /tmp/tcpdump9.pkt
reading from file /tmp/tcpdump9.pkt, link-type EN10MB (Ethernet)
22:27:08.416478 IP 192.168.100.100.33136 > 192.168.100.1.tftp: 13 RRQ "1" netascii
22:27:08.734306 IP 192.168.100.100.33136 > 192.168.100.1.tftp: 13 RRQ "2" netascii
22:27:09.029195 IP 192.168.100.100.33136 > 192.168.100.1.tftp: 13 RRQ "3" netascii

* udp 는 3way - hand-shaking 이 없다.

*. udp 서비스가 방화벽에 막혀 있는 경우
[root@centos1 tftpboot]# iptables -F
[root@centos1 tftpboot]# iptables -A INPUT -p udp --dport 69 -j DROP
[root@centos1 tftpboot]# tcpdump -n host 192.168.100.100 and port 69 -w /tmp/tcpdump10.pkt
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

[root@centos100 temp2]# tftp 192.168.100.1 -c get a.txt b.txt c.txt
Transfer timed out.
[root@centos100 temp2]#

[root@centos1 tftpboot]# tcpdump -r /tmp/tcpdump10.pkt
reading from file /tmp/tcpdump10.pkt, link-type EN10MB (Ethernet)
22:34:29.379785 IP 192.168.100.100.49576 > 192.168.100.1.tftp: 17 RRQ "a.txt" netascii
22:34:34.796127 IP 192.168.100.100.49576 > 192.168.100.1.tftp: 17 RRQ "a.txt" netascii
22:34:40.635185 IP 192.168.100.100.49576 > 192.168.100.1.tftp: 17 RRQ "a.txt" netascii
22:34:45.510690 IP 192.168.100.100.49576 > 192.168.100.1.tftp: 17 RRQ "a.txt" netascii
22:34:51.942627 IP 192.168.100.100.49576 > 192.168.100.1.tftp: 17 RRQ "a.txt" netascii
[root@centos1 tftpboot]#

*. 패킷에서 패스워드 찾기

[root@centos1 tftpboot]# tcpdump -X -r /tmp/telnet.pkt > /tmp/telnet.txt

[root@centos100 temp2]# telnet 192.168.100.1
Trying 192.168.100.1...
Connected to 192.168.100.1 (192.168.100.1).
Escape character is '^]'.
CentOS release 5.3 (Final)
Kernel 2.6.18-128.el5 on an i686
login: user1
Password:
Last login: Wed Jun 2 20:24:36 from 192.168.100.100
[user1@centos1 ~]$ logout
Connection closed by foreign hos

[root@centos1 tftpboot]# tcpdump -X -r /tmp/telnet.pkt > /tmp/telnet.txt

-X : Print each packet (minus its link level header) in hex and ASCII. This is very handy for analysing new protocols.

-X 옵션을 사용하면 hexa 코드와 아스키코드로 출력해주므로 그냥 보기에는 출력결과가 많아서 어렵다.
그러므로 파일로 저장해서 특정문자열을 검색하는 방법으로 보는것이 패스워드를 쉽게
찾을수 있는 방법이다.
vi 편집기로 열어서 Password 라는 문자열을 검색한 후 아래쪽을 보면 캡쳐된 암호가
보일것이다.

패스워드는 apple 이다. 내용이 많아서 편의상 app 까지만 출력하였다.
각 패킷에서의 마지막 문자가 암호인데 한 패킷씩 건너뛰고 저장되어 있다.
당연히 그렇게 저장된다.

0x0030: 06b2 00d3 5061 7373 776f 7264 3a20 ....Password:.
22:50:28.490812 IP 192.168.100.100.55824 > 192.168.100.1.telnet: . ack 146 win 92
0x0000: 4510 0034 1460 4000 4006 dc9d c0a8 6464 E..4.`@.@.....dd
0x0010: c0a8 6401 da10 0017 e1f1 fd47 1bf1 13c1 ..d........G....
0x0020: 8010 005c fad9 0000 0101 080a 06b2 0140 ...\...........@
0x0030: 1114 2fb7 ../.
22:50:29.198462 IP 192.168.100.100.55824 > 192.168.100.1.telnet: P 90:91(1) ack 146 win 92
0x0000: 4510 0035 1461 4000 4006 dc9b c0a8 6464 E..5.a@.@.....dd
0x0010: c0a8 6401 da10 0017 e1f1 fd47 1bf1 13c1 ..d........G....
0x0020: 8018 005c 9716 0000 0101 080a 06b2 03fa ...\............
0x0030: 1114 2fb7 61 ../.a
22:50:29.242685 IP 192.168.100.1.telnet > 192.168.100.100.55824: . ack 91 win 91
0x0000: 4510 0034 050c 4000 4006 ebf1 c0a8 6401 E..4..@.@.....d.
0x0010: c0a8 6464 0017 da10 1bf1 13c1 e1f1 fd48 ..dd...........H
0x0020: 8010 005b f52a 0000 0101 080a 1114 32ac ...[.*........2.
0x0030: 06b2 03fa ....
22:50:29.494741 IP 192.168.100.100.55824 > 192.168.100.1.telnet: P 91:92(1) ack 146 win 92
0x0000: 4510 0035 1462 4000 4006 dc9a c0a8 6464 E..5.b@.@.....dd
0x0010: c0a8 6401 da10 0017 e1f1 fd48 1bf1 13c1 ..d........H....
0x0020: 8018 005c 8420 0000 0101 080a 06b2 04fa ...\............
0x0030: 1114 32ac 70 ..2.p
22:50:29.497150 IP 192.168.100.1.telnet > 192.168.100.100.55824: . ack 92 win 91
0x0000: 4510 0034 050d 4000 4006 ebf0 c0a8 6401 E..4..@.@.....d.
0x0010: c0a8 6464 0017 da10 1bf1 13c1 e1f1 fd49 ..dd...........I
0x0020: 8010 005b f32a 0000 0101 080a 1114 33ab ...[.*........3.
0x0030: 06b2 04fa ....
22:50:29.615998 IP 192.168.100.100.55824 > 192.168.100.1.telnet: P 92:93(1) ack 146 win 92
0x0000: 4510 0035 1463 4000 4006 dc99 c0a8 6464 E..5.c@.@.....dd
0x0010: c0a8 6401 da10 0017 e1f1 fd49 1bf1 13c1 ..d........I....
0x0020: 8018 005c 82a4 0000 0101 080a 06b2 0576 ...\...........v
0x0030: 1114 33ab 70 ..3.p

이하 생략...

Let’s assume that we want to watch packets used in establishing a TCP connection. Recall that TCP uses a 3-way handshake protocol
when it initializes a new connection; the connection sequence with regard to the TCP control bits is

1) Caller sends SYN
2) Recipient responds with SYN, ACK
3) Caller sends ACK



URG | ACK | PSH | RST | SYN | FIN

URG : Urgent pointer is valid RST: Reset the connection
ACK : Acknowlegement is valid SYN : Syncronize sequence numbers
PSH : Request for push FIN : Terminate the connection


TCP 연결 (3way hand shaking)

Client Server
Segment 1: SYN
| ---------------- seq : 1000, ack : - --------------> |
| |
| Segment 2: SYN ACK |
|<---------------- seq : 4000, ack : 1001 ---------|
| |
| Segment 3: ACK |
| ----------------- seq : 1201, ack 4001 ----------->|
| |
v v
Time Time

TCP data 전송

Client Server
Segment 1:
| ---------------- seq : 2000, 200bytes : - -------------->|
|| |
| <-------------------- ACK :2200 ------------------------- |
| | | Segment 2: |
|<---------------- seq : 2200, 200 bytes ----------------- |
| |
| -------------------- ACK : 2400 -------------------------> |
| |
| Segment 3: |
| -------------------- seq : 2400, 200 bytes -----------> |

time out 까지 응답없음.
| |
| Segment 3: (다시 전송) |
| ----------------- seq : 2400, 200bytes ---------------> |
| |
v v
Time Time

TCP 연결 종료 과정

Client Server
Segment 1: FIN
| ---------------- seq : 2000, ack : - --------------> |
| |
| Segment 2: ACK |
|<---------------- seq : 5000, ack : 2001 ---------|
| |
| Segment 3: FIN |
| <-------------------- seq : 5001, ack 2001 -------- |
| |
| Segment 4: ACK |
| ----------------- seq : 2001, ack 5002 ----------->|
| |
v v
Time Time

TCP 상태
state Description
--------------------------------------------------------------------------------
closed : There is no connection. (연결되지 않았다)
listen : The server is waiting for calls from the client (클라이언트의 접속을 기다리고 있다)
syn-sent : A connection request is sent; waiting for acknowlegement. (접속 요청을 보내고 응답을 기다리고 있다)
syn-recvd : A connection request is received (접속요청에 대한 응답을 받았다)
established : Connection is established (접속완료)

fin-wait-1 : The application has requested the closing of the connection. (연결 끊기를 요청)
fin-wait-2 : The other side has accepted the closing of the connection. (요청에 대한 응답을 받았다)
time-wait : Waiting for retransmitted segments to die.(연결 끊기에 대한 응답을 다시 기다림)
close-wait : The server is waiting for the application to close.(서버가 클라이언트로부터 연결종료를 기다림)
last-ack : The server is waiting for the last acknowlegement. (서버가 클라이언트로부터 연결종료에 대한 마지막 응답을 기다림)

반응형