2014年10月31日 星期五

Tcpdump Tutorial

原文轉載:A tcpdump Primer

tcpdump能夠分析網路行為,效能和應用產生或接收網路流量。它支援針對網路層、協定、主機、網路或埠的過濾,並提供and、or、not等邏輯語句來幫助你去掉無用的資訊,從而使用戶能夠進一步找出問題的根源。

也可以使用 tcpdump 的實現特定目的,例如在路由器和閘道器之間攔截並顯示其他用戶或電腦通訊。透過 tcpdump 分析非加密的流量,如Telnet或HTTP的封包,檢視登入的使用者名稱、密碼、網址、正在瀏覽的網站內容,或任何其他資訊。因此系統中存在網路分析工具主要不是對本機安全的威脅,而是對網路上的其他電腦的安全存在威脅。

參數介紹

當你使用 tcpdump 時,它提供許多的參數,下面列舉一些常用的參數。這些參數非常容易忘記,而且常常會跟其他的 filters 搞混。當你忘記 tcpdump 怎麼用的時候,可以回來看看這篇文章,幫助你快速回憶。

首先,我有幾個非常喜愛的參數。第一個是 -n,這個參數是設定 host name 不要被主動解析,因此就會以 ip 直接顯示出來。第二個是 -X,這個參數會將 packet 用 hex 和 ascii 的方式同時顯示出來。最後一個是 -S,這個參數會顯示 sequence numbers 的絕對值,而不是採用預設的相對值。如果 sequence numbers 採用相對值,當它發生問題的時候,我們卻沒辦法察覺,在 debug 上會變得很麻煩。

還有一個重要的事情,我們必須要注意一下,就是 tcpdump 預設只會顯示 packet 中前面的 96 bytes。假如你想要看多一點,記得要加上 -s number 參數,number 就是你像要多少 packet 中的 bytes 數量。我的建議是設定成 0 (snaplength),這樣你就可以看到 packet 的全部內容了。下面是一些我常用的參數列表:
  • -i any : Listen on all interfaces just to see if you’re seeing any traffic.
  • -n : Don’t resolve hostnames.
  • -nn : Don’t resolve hostnames or port names.
  • -X : Show the packet’s contents in both hex and ASCII.
  • -XX : Same as -X, but also shows the ethernet header.
  • -v, -vv, -vvv : Increase the amount of packet information you get back.
  • -c : Only get x number of packets and then stop.
  • -s : Define the snaplength (size) of the capture in bytes. Use -s0 to get everything, unless you are intentionally capturing less.
  • -S : Print absolute sequence numbers.
  • -e : Get the ethernet header as well.
  • -q : Show less protocol information.
  • -E : Decrypt IPSEC traffic by providing an encryption key.
[ tcpdump 4.0 把預設的 snaplength 從 68 bytes 調整成 96 bytes。這個改變會讓你看到看多 packet 的內容,但是仍然不是全部的內容。使用 -s 1514 來取得所有的 packet 內容。]

基本用法

根據實際想要觀察的 packet 狀況,我會將不同的參數組合在一起,下面是一些簡單的使用例子:

● Basic communication // see the basics without many options
tcpdump -nS

● Basic communication (very verbose) // see a good amount of traffic
tcpdump -nnvvS

● A deeper look at the traffic // adds -X for payload but doesn’t grab any more of the packet
tcpdump -nnvvXS

● Heavy packet viewing // the final “s” increases the snaplength, grabbing the whole packet
tcpdump -nnvvXSs 1514

下面是一個從 ICMP (a ping and a pong) 中擷取兩個 packet (-c2) 的內容,使用一些上面介紹過的參數。

hermes root # tcpdump -nnvXSs 0 -c2 icmp
tcpdump: listening on eth0, link-type EN10MB (Ethernet), 23:11:10.370321 IP 
(tos 0x20, ttl  48, id 34859, offset 0, flags [none], length: 84) 
69.254.213.43 > 72.21.34.42: icmp 64: echo request seq 0
        0x0000:  4520 0054 882b 0000 3001 7cf5 45fe d52b  E..T.+..0.|.E..+
        0x0010:  4815 222a 0800 3530 272a 0000 25ff d744  H."..50'..%..D
        0x0020:  ae5e 0500 0809 0a0b 0c0d 0e0f 1011 1213  .^..............
        0x0030:  1415 1617 1819 1a1b 1c1d 1e1f 2021 2223  .............!"#
        0x0040:  2425 2627 2829 2a2b 2c2d 2e2f 3031 3233  $%&'()+,-./0123
        0x0050:  3435 3637                                4567
23:11:10.370344 IP (tos 0x20, ttl  64, id 35612, offset 0, flags [none], 
length: 84) 72.21.34.42 > 69.254.213.43: icmp 64: echo reply seq 0
        0x0000:  4520 0054 8b1c 0000 4001 6a04 4815 222a  E..T....@.j.H."
        0x0010:  45fe d52b 0000 3d30 272a 0000 25ff d744  E..+..=0'..%..D
        0x0020:  ae5e 0500 0809 0a0b 0c0d 0e0f 1011 1213  .^..............
        0x0030:  1415 1617 1819 1a1b 1c1d 1e1f 2021 2223  .............!"#
        0x0040:  2425 2627 2829 2a2b 2c2d 2e2f 3031 3233  $%&'()+,-./0123
        0x0050:  3435 3637                                4567
2 packets captured
2 packets received by filter
0 packets dropped by kernel
hermes root # 

常見語法

host // look for traffic based on IP address (also works with hostname if you’re not using -n)
tcpdump host 1.2.3.4

src, dst // find traffic from only a source or destination (eliminates one side of a host conversation)
tcpdump src 2.3.4.5
tcpdump dst 3.4.5.6

net // capture an entire network using CIDR notation
tcpdump net 1.2.3.0/24

proto // works for tcp, udp, and icmp. Note that you don’t have to type proto
tcpdump icmp

port // see only traffic to or from a certain port
tcpdump port 3389

src, dst port // filter based on the source or destination port
tcpdump src port 1025
tcpdump dst port 389

● src/dst, port, protocol // combine all three
tcpdump src port 1025 and tcp
tcpdump udp and src port 53

你也可以指定一段 port 的區間做篩選,或是只想看見大於或小於指定 size 的 packet。

● Port Ranges // see traffic to any port in a range
tcpdump portrange 21-23

Packet Size Filter // only see packets below or above a certain size (in bytes)
tcpdump less 32
tcpdump greater 128

[ 你也可以透過 symbol 的方式來指定 packet size ]

// filtering for size using symbols
tcpdump > 32
tcpdump <= 128

寫入檔案

tcpdump 可以透過 -w 參數,把抓取到的 packet 儲存在檔案中,然後透過 -r 參數把 packet 資訊讀取回來。這是一個非常好的方式把 packet traffic 儲存起來,之後在透過其他的工具做更進階的分析,譬如 WiresharkSnort 等。

● Capture all Port 80 Traffic to a File
tcpdump -s 1514 port 80 -w capture_file

Read Captured Traffic back into tcpdump
tcpdump -r capture_file

更有創意的用法

除了基本的表示法以外,最特別的是 tcpdump 可以將多個參數結合在一起,來達到你所想要監控的 packet。總共有三種方式可以做結合,如果你對於程式嫻熟的話,對於你來說應該是很直覺的東西。

1. AND
and or &&

2. OR
or or ||

3. EXCEPT
not or !

更多例子

● TCP traffic from 10.5.2.3 destined for port 3389
tcpdump -nnvvS src 10.5.2.3 and dst port 3389

● Traffic originating from the 192.168 network headed for the 10 or 172.16 networks
tcpdump -nvX src net 192.168.0.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16

● Non-ICMP traffic destined for 192.168.0.2 from the 172.16 network
tcpdump -nvvXSs 1514 dst 192.168.0.2 and src net 192.168.0.2/32 and not icmp

● Traffic originating from Mars or Pluto that isn’t to the SSH port
 tcpdump -nvvXSs 1514 dst 192.168.0.2 and src 192.168.0.2 and not icmp

● Traffic originating from Mars or Pluto that isn’t to the SSH port
tcpdump -vv src mars and not dst port 22

上面看見了這麼多的範例以後,你可以根據需求建立 tcpdump 的查詢。關鍵在於你必須要知道你想要找哪一類型的 packet,然後建立查詢來篩選出你想要觀察的 packet。

括號的結合作用

當你建立複雜的查詢指令時,可以透過 single quote 把參數結合在一起,避免 shell 執行上產生錯誤,特別是你用到 “( )” 的時候,“( )” 可以用在 host, port, net 等等。我們看下面這一個會產生解析錯誤的例子。

● Traffic that’s from 10.0.2.4 AND destined for ports 3389 or 22 (incorrect)
tcpdump src 10.0.2.4 and (dst port 3389 or 22)
假如你嘗試執行上面這一行指令,你的 shell 會噴出錯誤訊息,因為 “( )” 的關係。你可以透過跳脫自元的方式,幫 “( )” 做跳脫。但是最直接有效的方式是直接用 single quote 把參數包起來,例如下面的範例。

● Traffic that’s from 10.0.2.4 AND destined for ports 3389 or 22 (correct)
tcpdump src 10.0.2.4 and '(dst port 3389 or 22)'

進階用法

你可以把 packet 中的一部分當做篩選的條件,也可以再加上上面提到的參數當做篩選條件。當你想要觀察 SYNs 或是 RST 封包時,這種方式是最適合的方法了。

● Show me all URGENT (URG) packets…
tcpdump 'tcp[13] & 32!=0'

● Show me all ACKNOWLEDGE (ACK) packets…
tcpdump 'tcp[13] & 16!=0'

● Show me all PUSH (PSH) packets…
tcpdump 'tcp[13] & 8!=0'

● Show me all RESET (RST) packets…
tcpdump 'tcp[13] & 4!=0'

● Show me all SYNCHRONIZE (SYN) packets…
tcpdump 'tcp[13] & 2!=0'

● Show me all FINISH (FIN) packets…
tcpdump 'tcp[13] & 1!=0'

● Show me all SYNCHRONIZE/ACKNOWLEDGE (SYNACK) packets…
tcpdump 'tcp[13]=18'

[ Note: Only the PSH, RST, SYN, and FIN flags are displayed in tcpdump's flag field output. URGs and ACKs are displayed, but they are shown elsewhere in the output rather than in the flags field ]

上面的指令為什麼可以這樣運作呢?因為 tcp[13] 是指 TCP Header 中 offset 13 byte 的位置,數字代表著位移,!=0 可以用來區分特定的 flag。

除了這種用法以外,tcpdump 也提供更強大的用法可以達到相同的效果,下面這個例子就是示範怎麼透過 tcpflag 來捕捉到特定的 packet。

● Capture TCP Flags Using the tcpflags Option…
tcpdump 'tcp[tcpflags] & tcp-syn != 0'

特殊的訊息流

最後提供一些小技巧來捕捉特定的封包流,譬如 IPv6 和 malformed/likely-malicious packets。

IPv6 traffic
tcpdump ip6

Packets with both the RST and SYN flags set (why?)
tcpdump 'tcp[13] = 6'

Traffic with the ‘Evil Bit’ Set
tcpdump 'ip[6] & 128 != 0'

可能的問題

No output

檢查是否有提供正確的 network interface,我的建議是盡可能加上 -i 參數。假如遇到 DNS 問題的話,tcpdump 會卡在在解析名字的步驟,為了避免這個問題,請近可能加上 -n 參數,關閉 DNS 解析。

Dropped packets

在結束 tcpdump 時,在結尾處會有一個統計資料,告訴你抓取到多少個封包,多少個封包掉了。如果遇到封包掉了的狀況,可能是因為封包流量太大,無法同時 capture 和 decode。試著透過 -w 參數,把封包寫進一個檔案後,在透過 -r 參數,讀取檔案回來做觀察。如果還是有問題的話,試著調整 -s (snapshot size) 參數,減少抓取封包的大小。

Messages that end like [|rip] and [|domain]

如果發現訊息的結尾是類似 [|proto],這個表示抓取的 packet size 太小,tcpdump 無法正確 decode,試著透過 -s 參數,增加 snapshot size。

結論

這篇文章可以讓你的 tcpdump 使用技巧上增加不少,但是最重要的還是 man page,裡頭涵蓋更多更進階的技巧。我真心的希望這篇文章可以幫助到你。

沒有留言:

張貼留言