tcpdump介绍tcpdump 是一款开源的网络数据截取分析工具,具有强大的功能和灵活的截取策略,用在网络的分析、维护、统计、检测等方面,例如定位网络瓶颈、统计网络流量使用情况等。它支持针对网络层、协议、主机、网络或端口的过滤,正则表达式的灵活应用能帮你准确获取有用信息。 运行效果kongove@ubuntu:~$ sudo tcpdump -i eth0 host ubuntu.local 基本使用tcpdump [ -AdDeflLnNOpqRStuUvxX ] [ -c count ] [ -C file_size ] [ -F file ] 通过对 tcpdump 选项、参数、表达式的组合应用,从大流量的网络数据当中,过滤出真正有用的信息,从而缩小分析范围。 tcpdump选项
tcpdump的表达式介绍tcpdump利用正则表达式作为过滤报文的条件,如果数据包满足表达式的条件,则会被捕获。如果没有给出任何条件,则网络上所有的数据包将会被截获。表达式中常用关键字如下:
expression一个或多个原语 (primitive)组成。原语通常由一个标识(id,名称或数字),和标识前面的一个或多个修饰子(qualifier)组成。 修饰子 有三种不同的类型:
作为上述的补充, 有一些特殊的`原语'关键字, 它们不同于上面的模式: gateway, broadcast, less, greater和数学表达式. 这些在后面有叙述。 更复杂的过滤器表达式 可以通过and, or和not连接原语来组建。 例如,`host foo and notport ftp and not port ftp-data'。为了少敲点键, 可以忽略相同的修饰子。 例如, `tcp dst port ftp or ftp-data or domain'实际上就是`tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'。 允许的 原语 有:
原语可以用下述方法结合使用: 园括弧括起来的原语和操作符(园括弧在Shell中有专用,所以必须转义). 取反操作 (`!' or `not'). 连结操作 (`&&' or `and'). 或操作 (`||' or `or'). 取反操作有最高优先级.或操作和连结操作有相同的优先级,运算时从左到右结合.注意连结操作需要显式的and算符,而不是并列放置. 如果给出标识符,但没给关键字,那么暗指最近使用的关键字.例如, not host vs and ace作为not host vs and host ace的简写形式, 不应该和not( host vs or ace )混淆。 表达式参数可以作为单个参数传给tcpdump,也可以作为复合参数,后者更方便一些.一般说来,如果表达式包含Shell元字符(metacharacter),传递单个括起来的参数要容易一些.复合参数在被解析前用空格联接一起. tcpdump的输出信息tcpdump命令四种典型的输出信息: 数据链路层头信息使用命令:tcpdump -e host host1 ARP包的TCPDUMP输出信息使用命令:tcpdump arp TCP包的输出信息输出信息: src > dst: flags data-seqno ack window urgent options UDP包的输出信息输出信息: host.p1 > linux.p2: udp lenth 功能扩展tcpdump还可以结合tcpshow、管道、重定向使用,从而扩展其功能。 范例显示所有进出sundown的报文:tcpdump host sundown 显示helios和主机hot,ace之间的报文传送:tcpdump host helios and \( hot or ace \) 显示ace和除了helios以外的所有主机的IP报文tcpdump ip host ace and not helios 显示本地的主机和Berkeley的主机之间的网络数据tcpdump net ucb-ether 显示所有通过网关snup的ftp报文(注意这个表达式被单引号括起,防止shell解释园括弧)tcpdump 'gateway snup and (port ftp or ftp-data)' 显示既不是来自本地主机,也不是传往本地主机的网络数据(如果你把网关通往某个其他网络,这个做法将不会把数据发往你的本地网络).tcpdump ip and not net localnet 显示每个TCP会话的起始和结束报文(SYN和FIN报文),而且会话方中有一个远程主机.tcpdump 'tcp[13] & 3 != 0 and not src and dst net localnet' 显示经过网关snup中大于576字节的IP数据报tcpdump 'gateway snup and ip[2:2] > 576' 显示IP广播或多目传送的数据报,这些报文不是通过以太网的广播或多目传送形式传送的tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224' 显示所有不是回响请求/应答的ICMP报文(也就是说,不是ping报文)tcpdump 'icmp[0] != 8 and icmp[0] != 0' tcpdump的输出格式取决于协议.下面的描述给出大多数格式的简要说明和范例. 链路层报头 (Link Level Headers)如果给出'-e'选项就显示链路层报头.在以太网上,显示报文的源目地址,协议和报文长度. 在FDDI网络上,'-e'选项导致tcpdump显示出`帧控制(framecontrol)'域,源目地址和报文长度.(`帧控制'域负责解释 其余的报文.普通报文(比如说载有IP数据报)是`异步'报文,优先级介于0到7;例如,`async4'.这些被认为载有802.2逻辑链路控制 (LLC)报文;如果它们不是ISO数据报或者所谓的SNAP报文,就显示出LLC报头. (注意:以下描述中假设你熟悉RFC-1144中说明的SLIP压缩算法.) 在SLIP链路上,tcpdump显示出方向指示(``I''指inbound,``O''指outbound),报文类型和压缩信息.首先显示的 是报文类型.有三种类型ip,utcp和ctcp.对于ip报文不再显示更多的链路信息.对于TCP报文,在类型后面显示连接标识.如果报文是压缩过的, 就显示出编码的报头.特殊情形以*S+n和*SA+n的形式显示,这里的n是顺序号(或顺序号及其确认)发生的改变总和.如果不是特殊情形,就显示0或多 少个改变.改变由U(urgentpointer),W(window),A(ack),S(sequencenumber)和I(packetID)指 明,后跟一个变化量(+nor-n),或另一个值(=n).最后显示报文中的数据总和,以及压缩报头的长度. 例如,下面一行显示了一个传出的压缩的TCP报文,有一个隐含的连接标识;确认(ack)的变化量是6,顺序号是49,报文ID是6;有三个字节的数据和六个字节的压缩报头: O ctcp * A+6 S+49 I+6 3 (6) ARP/RARP 报文Arp/rarp报文的输出显示请求类型及其参数.输出格式倾向于能够自我解释.这里是一个简单的例子,来自主机rtsg到主机csam的'rlogin'开始部分: arp who-has csam tell rtsg arp reply csam is-at CSAM 第一行说明rtsg发出一个arp报文询问internet主机csam的以太网地址.Csam用它的以太地址作应答(这个例子中,以太地址是大写的,internet地址为小写). 如果 用 tcpdump -n 看上去 要 清楚一些: arp who-has 128.3.254.6 tell 128.3.254.68 arp reply 128.3.254.6 is-at 02:07:01:00:01:c4 如果用tcpdump-e,可以看到实际上第一个报文是广播,第二个报文是点到点的: RTSG Broadcast 0806 64: arp who-has csam tell rtsg CSAM RTSG 0806 64: arp reply csam is-at CSAM 这里第一个报文指出以太网源地址是RTSG,目的地址是以太网广播地址,类型域为16进制数0806(类型ETHER_ARP),报文全长64字节. TCP 报文(注意:以下的描述中假设你熟悉RFC-793中说明的TCP协议,如果你不了解这个协议,无论是本文还是tcpdump都对你用处不大) 一般说来tcp协议的输出格式是: src > dst: flags data-seqno ack window urgent options Src和dst是源目IP地址和端口.Flags是S(SYN),F(FIN),P(PUSH)或R(RST)或单独的`.'(无标志),或者是它 们的组合.Data-seqno说明了本报文中的数据在流序号中的位置(见下例).Ack是在这条连接上信源机希望下一个接收的字节的流序号 (sequencenumber).Window是在这条连接上信源机接收缓冲区的字节大小.Urg表明报文内是`紧急(urgent)'数 据.Options是tcp可选报头,用尖括号括起(例如,). Src, dst 和 flags肯定存在. 其他域依据报文的tcp报头内容, 只输出有必要的部分. 下面是从主机rtsgrlogin到主机csam的开始部分. rtsg.1023 > csam.login: S 768512:768512(0) win 4096 第一行是说从rtsg的tcp端口1023向csam的login端口发送报文.S标志表明设置了SYN标志.报文的流序号是768512,没有数 据.(这个写成`first:last(nbytes)',意思是`从流序号first到last,不包括last,有nbytes字节的用户数据'.) 此时没有捎带确认(piggy-backedack),有效的接收窗口是4096字节,有一个最大段大小(max-segment-size)的选项,请 求设置mss为1024字节. Csam用类似的形式应答,只是增加了一个对rtsgSYN的捎带确认.然后Rtsg确认csam的SYN.`.'意味着没有设置标志.这个报文不 包含数据,因此也就没有数据的流序号.注意这个确认流序号是一个小整数(1).当tcpdump第一次发现一个tcp会话时,它显示报文携带的流序号.在 随后收到的报文里,它显示当前报文和最初那个报文的流序号之差.这意味着从第一个报文开始,以后的流序号可以理解成数据流中的相对位移 asrelativebytepositionsintheconversation'sdatastream(withthefirstdatabyteeachdirectionbeing`1').`- S'选项能够改变这个特性,直接显示原始的流序号. 在第六行,rtsg传给csam19个字节的数据(字节2到20).报文中设置了PUSH标志.第七行csam表明它收到了rtsg的数据,字节序 号是21,但不包括第21个字节.显然大多数数据在socket的缓冲区内,因为csam的接收窗口收到的数据小于19个字节.同时csam向rtsg发 送了一个字节的数据.第八和第九行显示csam发送了两个字节的紧急数据到rtsg. 如果捕捉区设置的过小,以至于tcpdump不能捕捉到完整的TCP报头,tcpdump会尽可能的翻译已捕获的部分,然后显示 ``[|tcp]'',表明无法翻译其余部分.如果报头包含一个伪造的选项 (onewithalengththat'seithertoosmallorbeyondtheendoftheheader),tcpdump显示 ``[badopt]''并且不再翻译其他选项部分(因为它不可能判断出从哪儿开始).如果报头长度表明存在选项,但是IP数据报长度不够,不可能真的保 存选项,tcpdump就显示``[badhdrlength]''. UDP 报文UDP格式就象这个rwho报文显示的: actinide.who > broadcast.who: udp 84 就是说把一个udp数据报从主机actinide的who端口发送到broadcast,Internet广播地址的who端口.报文包含84字节的用户数据. 某些 UDP 服务 能够 识别出来(从 源目端口号 上), 因而 显示出 更高层的 协议信息. 特别是 域名服务请求(RFC-1034/1035) 和 NFS 的 RPC 调用(RFC-1050). UDP域名服务请求(NameServerRequests)(注意:以下的描述中假设你熟悉RFC-1035说明的域名服务协议.如果你不熟悉这个协议,下面的内容就象是天书.) 域名服务请求的格式是 src > dst: id op? flags qtype qclass name (len) h2opolo.1538 > helios.domain: 3+ A? ucbvax.berkeley.edu. (37) 主机h2opolo访问helios上的域名服务,询问和ucbvax.berkeley.edu.关联的地址记录(qtype=A).查询号是 `3'.`+'表明设置了递归请求标志.查询长度是37字节,不包括UDP和IP头.查询操作是普通的Query操作,因此op域可以忽略.如果op设置 成其他什么东西,它应该显示在`3'和`+'之间.类似的,qclass是普通的C_IN类型,也被忽略了.其他类型的qclass应该在`A'后面显 示. Tcpdump会检查一些不规则情况,相应的结果作为补充域放在方括号内:如果某个查询包含回答,名字服务或管理机构部分,就把 ancount,nscount,或arcount显示成`[na]',`[nn]'或`[nau]',这里的n代表相应的数量.如果在第二和第三字节 中,任何一个回答位(AA,RA或rcode)或任何一个`必须为零'的位被置位,就显示`[b2&3=x]',这里的x是报头第二和第三字节的 16进制数. UDP名字服务回答名字服务回答的格式是 src > dst: id op rcode flags a/n/au type class data (len) 第一个例子里,helios回答了h2opolo发出的标识为3的询问,一共是3个回答记录,3个名字服务记录和7个管理结构记录.第一个回答纪录 的类型是A(地址),数据是internet地址128.32.137.3.回答的全长为273字节,不包括UDP和IP报头.作为A记录的 class(C_IN)可以忽略op(询问)和rcode(NoError). 在第二个例子里,helios对标识为2的询问作出域名不存在(NXDomain)的回答,没有回答记录,一个名字服务记录,而且没有管理结构. `*'表明设置了权威回答(authoritativeanswer).由于没有回答记录,这里就不显示type,class和data. 其他标志字符可以显示为`-'(没有设置递归有效(RA))和`|'(设置消息截短(TC)).如果`问题'部分没有有效的内容,就显示`[nq]'. 注意名字服务的询问和回答一般说来比较大,68字节的snaplen可能无法捕捉到足够的报文内容.如果你的确在研究名字服务的情况,可以使用-s选项增大捕捉缓冲区.`-s128'应该效果不错了. NFS请求和响应SunNFS(网络文件系统)的请求和响应显示格式是: src.xid > dst.nfs: len op args 在第一行,主机sushi向wrl发送号码为6709的交易会话(注意源主机后面的数字是交易号,不是端口).这项请求长112字节,不包括UDP 和IP报头.在文件句柄(fh)21,24/10.731657119上执行readlink(读取符号连接)操作.(如果运气不错,就象这种情况,文件 句柄可以依次翻译成主次设备号,i节点号,和事件号(generationnumber).)Wrl回答`ok'和连接的内容. 在第三行,sushi请求wrl在目录文件9,74/4096.6878中查找`xcolors'.注意数据的打印格式取决于操作类型.格式应该是可以自我说明的. 给出-v(verbose)选项可以显示附加信息.例如: sushi.1372a > wrl.nfs: 148 read fh 21,11/12.195 8192 bytes @ 24576 wrl.nfs > sushi.1372a: reply ok 1472 read REG 100664 ids 417/0 sz 29388 (-v同时使它显示IP报头的TTL,ID,和分片域,在这个例子里把它们省略了.)在第一行,sushi请求wrl从文件 21,11/12.195的偏移位置24576开始,读取8192字节.Wrl回答`ok';第二行显示的报文是应答的第一个分片,因此只有1472字节 (其余数据在后续的分片中传过来,但由于这些分片里没有NFS甚至UDP报头,因此根据所使用的过滤器表达式,有可能不显示).-v选项还会显示一些文件 属性(它们作为文件数据的附带部分传回来):文件类型(普通文件``REG''),存取模式(八进制数),uid和gid,以及文件大小. 如果再给一个-v选项(-vv),还能显示更多的细节. 注意NFS请求的数据量非常大,除非增加snaplen,否则很多细节无法显示.试一试`-s192'选项. NFS应答报文没有明确标明RPC操作.因此tcpdump保留有``近来的''请求记录,根据交易号匹配应答报文.如果应答报文没有相应的请求报文,它就无法分析. KIPAppletalk(UDP上的DDP)AppletalkDDP报文封装在UDP数据报中,解包后按DDP报文转储(也就是说,忽略所有的UDP报头信息).文件/etc/atalk.names用来把appletalk网络和节点号翻译成名字.这个文件的行格式是 number name 前两行给出了appletalk的网络名称.第三行给出某个主机的名字(主机和网络依据第三组数字区分-网络号一定是两组数字,主机号一定是三组数 字.)号码和名字用空白符(空格或tab)隔开./etc/atalk.names文件可以包含空行或注释行(以`#'开始的行). Appletalk地址按这个格式显示 net.host.port 144.1.209.2 > icsd-net.112.220 office.2 > icsd-net.112.220 jssmag.149.235 > icsd-net.2 (如果不存在/etc/atalk.names,或者里面缺少有效项目,就以数字形式显示地址.)第一个例子里,网络144.1的209节点的 NBP(DDP端口2)向网络icsd的112节点的220端口发送数据.第二行和上面一样,只是知道了源节点的全称(`office').第三行是从网 络jssmag的149节点的235端口向icsd-net的NBP端口广播(注意广播地址(255)隐含在无主机号的网络名字中-所以在/etc /atalk.names中区分节点名和网络名是个好主意). Tcpdump可以翻译NBP(名字联结协议)和ATP(Appletalk交互协议)的报文内容.其他协议只转储协议名称(或号码,如果还没给这个协议注册名称)和报文大小. NBP报文的输出格式就象下面的例子: icsd-net.112.220 > jssmag.2: nbp-lkup 190: "=:LaserWriter@*" 第一行是网络icsd的112主机在网络jssmag上的广播,对名字laserwriter做名字查询请求.名字查询请求的nbp标识号是 190.第二行显示的是对这个请求的回答(注意它们有同样的标识号),主机jssmag.209表示在它的250端口注册了一个laserwriter的 资源,名字是"RM1140".第三行是这个请求的其他回答,主机techpit的186端口有laserwriter注册的"techpit". ATP报文格式如下例所示: jssmag.209.165 > helios.132: atp-req 12266<0-7> 0xae030001 Jssmag.209向主机helios发起12266号交易,请求8个报文(`<0-7>').行尾的十六进制数是请求中`userdata'域的值. 实例: 实践经验诊断arp风暴arp攻击包括arp扫描和arp欺骗两类。arp风暴属于前者,它是指由于病毒作用,导致主机向整个网络内广播大量arp请求,耗尽带宽资源,使网络瘫痪的现象,它往往是arp欺骗的前兆,用于破坏网络连接、盗取他人网络账号。 |
kongove@ubuntu:~$ sudo tcpdump -e arp
09:43:48.630521 00:15:c5:6d:0e:80 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: arp who-has 192.168.2.1 tell 192.168.8.237
09:43:48.734420 00:e0:4d:1a:c9:24 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: arp who-has 192.168.44.138 tell 192.168.44.156
09:43:48.842663 00:e0:e4:02:32:59 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: arp who-has 192.168.21.1 tell 192.168.21.251