欢迎光临!请记住我的域名:http://wish123.cnblogs.com
代码改变世界

Wireshark网络分析就这么简单

2018-06-06 16:06  wish123  阅读(32180)  评论(0编辑  收藏  举报

tcpdump抓包命令:

root#tcpdump -I eth0 -s 80 -w /tmp/tcpdump.cap

注:其中80表示,只抓每个包的前80个字节。

 

抓包时就筛选自己需要的包:

Wireshark抓包前Capture→Options,在Capture Filter中输入“host 10.10.100.10”,然后再抓。

tcpdump抓包对应的命令:

root#tcpdump -I eth0 host 10.10.100.10 -w /tmp/tcpdump.cap

 

小技巧:

ping<IP> -n 1 -l 1

这样抓包看到的,Data位为1,当请求方出口IP为PAT地址时,便于定位测试ping包是否可达。

 

 

过滤表达式:

  1. 根据IP和端口:过滤“IP为10.10.100.10且TCP端口为445”,则输入“ip.addr eq 10.10.100.10 && tcp.port eq 445”
  2. 根据协议过滤:NFS共享挂在失败,查看portmap和mount两个协议,则输入“portmap || mount”
  3. 数据包跟踪:选中感兴趣的包,选择Follow TCP/UDP Stream。
  4. 鼠标帮助过滤:选中感兴趣的包,右键Prepare a Filter→Selected可以自动生成过滤表达式。如果选择Apply as Filter→Selected则此表达式还会自动执行。

 

Wireshark自动分析:

    1. 单击Analyze→Expert Information可以看到不同级别的提示,如重传统计,连接建立和重置统计

       

    2. 单击Statistics→Service Response Time选定协议名称,可以得到响应时间统计。

       

    3. 单击Statistics→TCP Stream Graph

       

    4. 单击Statistics→TCP Stream Graph可以生成统计图

       

    5. 单击Statistics→I/O Graphs可以看到统计信息,如平均流量等等:

       

    6. 通过“Ctrl+F”搜索关键字:选string按钮,然后输入error搜索:

       




       

      NFS协议的抓包分析:

       

      客户端访问NFS服务器的portmap端口(tcp111),询问NFS进程的端口号,默认NFS的端口号时2049,客户端再访问TCP2049,mount挂载动作时file handle动作。

       

      另外NFS创建文件时,是认UID的,同一个UID号再另一台机器上看到的用户就会不一样了。

       

       

       

      NFS协议的细节动作:

       

      NFS时多个READ-CALL连续发出,和window的CIFS不同,CIFS时一个一个来的。

       

      NFS进入文件夹的动作时ACCESS-CALL,查找是LOOKUP-CALL,创建是CREATE-CALL,写入是WRITE-CALL,写完了提交时COMMIT-CALL(COMMIT确认了才算数据真正写好),看看文件属性是GETATTR-CALL

       

      async和sync的写方式,async时多个WRITE-Call同时发出,sync时一个一个WRITE-Call执行(commit对sync无意义),分辨方法时看WRITE-CALL上的UNSTABLE和FILE_SYNC标志,前者是async,后者表示sync。

       

      有人mount时跟上noac参数,读写性能很差,是因为noac会强制写操作为sync参数,读操作时频繁GETATTR,导致性能受影响。

       

       

       

      MTU的交互:

       

      TCP在三次握手过程中就会告知对方自己的MSS(Maximum Segment Size),MSS加上TCP头(20)和IP头(20)的长度就是MTU。


       

      强制nslookup使用tcp协议:

      root#nslookup

      >set vc

       

      TCP三次握手:

      第一个数据段的Seq为1,长度1448,所以数据段2的Seq号就是1449,数据段2长度为1448,数据段3的Seq号为2897。接收方发送的ACK号其实就等于发送方的Seq加上长度,接收方以此来判断少了哪些包,要求重传。

      我们之所以在Wireshark上看到Seq=0,是因为Wireshark启用了Relative Sequence Number,可以在“Edit→Preferences→protocals→TCP”里设置。

       

      Windows滑动窗口:

      ACK的数据包中有win=1460或者win=2920之类的,表示接收方一次可以接收一个或两个MSS,两个就是发送方可以一次发两个包来等对方确认。

      如果接收方处理速度跟不上接收数据的速度,缓存就会满了,从而导致接收窗口为0,发送方就会将自己的发送窗口限制为0,如下图。

       

      发送窗口决定一次能发多少字节,而MSS决定这些字节分几个包发完。

      发送方一次发N个包,接收方有时候收到很多包时,只要回复最后一个就能确认它收到了所有N个包。

      历史插曲:

      TCP刚发明,接收窗口被定义为65535字节,TCP包头只给接收窗口值留了16bit,无法突破65535的,RFC1323中三次握手时,把自己的Window Scale信息告知对方,由于Window Scale放在TCP头之外的Option中,不用改TCP头设计,Window Scale作用向对方声明一个Shift count,我们把它做成2的指数,乘以TCP包头中定义的接收窗口,得到真正的TCP接收窗口。

      如下图,5856就是183乘以32。

       

      TCP慢速启动:

      刚开始是连续翻倍增加每一次发送MSS的数量,到一定数量后开始逐渐+1递增。

       

      RTO是收不到确认,等待一段时间后再发,从发原始包到重发的时间。

       

      遇到拥塞重传后,从1开始重新慢启动,临界值设定为上次拥塞时的一半。

       

      快速重传:

      接收方收到的Seq比期望的大时,所以它没收到一个包就Ack一次期望的Seq号,发送方收到3个或以上重复ACK时,就意识到相应的包已经丢了,从而重传。为什么要规定3个Dup Ack呢,为了在很大程度上避免因乱序而触发重传。

       

      拥塞避免阶段收到快速重传,临界窗口应该设为发生拥塞时还没被确认的数据量的一半,然后将拥塞窗口设置为临界窗口值加3个MSS,继续保留在拥塞避免阶段,这个过程被称为快速恢复。如下:

       

      TCP延迟确认:

      如果收到一个包之后暂时没有什么数据需要发送对方,那就延迟一段时间(在windows默认为200ms),假如这段时间恰好有数据要发送,那确认信息就随数据一同发出。

      微软KB328890提供关闭延迟确认的步骤。

      Nagle算法:

      在发出的数据没有被确认之前,假如又有小数据生成,那就把小数据收集起来,凑满一个MSS或者等收到确认后再发送。

      UDP协议的优势:

      1. UDP净荷高。
      2. 没有Seq和Ack,不建立连接,效率高

      UDP协议的劣势:

      1. 没有MTU的概念,网络层分片导致性能占用。
      2. 没有重传机制,应用层决定丢包处理。
      3. 分片机制容易遭受攻击。


      CIFS:

      CIFS使用TCP的445端口。支持SMB,SMB2,SMB3(其中SMB2普遍)

      客户端把自己所有支持版本告知服务器端,服务器端挑出回复自己支持的最高版本。

      CIFS的session身份验证方式有Kerberos和NTLM。

      Session Setup后客户端打开共享路径,操作称为Tree Connect,服务器返回的Tree ID,客户端利用这个ID去访问目录和文件。Tree Connect不检查权限,即使无权限客户也能得到,检查权限的工作由Create操作完成。Create操作是涉及新建,打开,读取等动作。

      常见问题:

      1. 如果对文件夹禁止用户访问,但是下面一个文件允许访问,则用户无法打开对应目录,但是能直接打开那个文件。
      2. Windows的备份是Create请求中“Backup Intent”设1,读取为0,服务器可以根据这个字段来根据备份和读取权限来决定是否准许访问。
      3. Access Mask是“读写”,Share Access Mask是“读”,如果有人读写,另一个人请求读写就会收到“Sharing Violation”错误。
      4. CIFS来解决缓存数据一致性,采用Oplock(机会锁),有Exclusive(允许读写缓存),Batch(允许所有操作缓存)和Level2(允许读缓存)三种形式。

      (1)windows xp的SMB是一去一回,windows 7是多发多收,所以在网络质量不好的地方,差距挺大。

      (2)Windows Explorer从CIFS上复制文件比Robcopy和EMCopy慢,是因为它是单线程的。

      (3)CIFS共享中,复制一个文件粘贴到同一个目录是把内容复制到客户端内存,再从客户端内存写到服务器上,,而粘贴到客户端本地硬盘当然会比它快。SMB3才改进了这点,实现服务器端本地复制。

      (4)剪切粘贴非常快是因为只是一个“rename”操作。

      (5)SMB2没有SMB协议这么啰嗦,所以读性能提高很多。

       

      SMB3(Win8和10和2012)改进了复制粘贴在网络上跑两次的问题,是运用给客户端一个Token,客户端利用Token给服务器发写请求实现的。

      SMB3还实现了双网卡在CIFS层的负载均衡,一个SMB3 Session的诸多TCP分摊在两块网卡上,即使网卡瘫了一块,SMB3连接还能存在。

      SMB3还把文件锁之类的信息存在硬盘上,当双机头的架构中,主机头挂了,备机头起来便能获得此信息,从而提供无缝服务。

       

      DNS相关:

      A记录:域名解析到IP

      PTR记录:IP地址解析到域名(nslookup 跟上IP)

      SRV记录:查找域控

       

      CNAME记录:别名

       

      DNS的放大攻击:伪造DNS请求包的源IP,大量发送请求包,那个IP就会收到完全不对称般大量的DNS响应包。

       

      FTP主动模式:客户端通过21端口连接服务器,但是数据传输是由服务器从20端口主动连接客户端协商好的随机高端口。

      FTP被动模式:数据传输时,也是由客户端发起连接的。

       

      根据密钥解密https流量:

      Edit→Preferences→Protocols→SSL→RSA keys list,然后按照IP,Port,Protocol,Private Key格式填写RSA keys list一行

       

      Kerberos认证原理:

      原始版本:

      A用hash把密码转成一把密钥Kclt,用kclt把当前时间戳加密生成一个字符串“时间戳Kclt”,把“时间戳kclt”和帐号A的信息,以及一段随机字符串发给KDC组成身份认证请求AS_REQ。KDC收到AS_REQ后,读到帐号A的信息,调出密码,在用hash转换成Kclt解开“时间戳Kclt”,能解开就表明请求是帐号A生成的。

      选用时间戳是为了防范黑客的重放攻击,用时间戳,只要NTP是同步的,时间间隔相差太大就认为是重放攻击。

      KDC在用Kclt加密随机字符串,帐号A拿到回复后能否解出就能判断KDC的真假。

      以上过程中双方都没有向对方发送密码,即便一方是假的也不会泄密。

      但是有问题就是每次认证都要调出密码执行hash解密,对KDC的性能要求太大。

       

      改进版本:

      KDC生成两把一样的密钥Kclt-Kdc,把密码hash成Kkdc,然后用它加密那把委托给A的密钥,委托密钥称为TGT,KDC只需记住自己的Kkdc,就能解开委托给帐号的TGT,从而获得与该帐号之间的密钥,KDC的负担大大降低。KDC回复给A的AS_REP需要包含TGT,“(Kclt-kdc,时间戳,随机字符串)Kclt”

      A收到AS-REP后利用Kclt机密“(Kclt-kdc,时间戳,随机字符串)Kclt”,判断KDC真实性,把Kclt-kdc和TGT保存备用。

       

      账号A请KDC帮忙认证资源B:

      A将TGT,帐号A信息,时间戳,要访问的B的资源发给KDC,这个请求叫TGS-REQ。

      TGS_REQ=TGT,{帐号A信息,时间戳}Kclt-kdc,资源B相关信息

      KDC收到TGS-REQ后,用Kkdc解密TGT得到Kclt-kdc,再用Kclt-kdc解密A的信息和时间戳验证身份,确认A为真。

      KDC生成两把相同的密钥给A和B使用,称为Kclt-srv,其中一把密钥给A,另一把委托A给B,Kerberos把B的密码hash成Ksrv,然后用它加密委托给A转交B的Kclt-srv,只能B能解开这条Ticket。

      Ticket={帐号A的信息,Kclt-srv}Ksrv

      TGS_REP={Kclt-srv}Kclt-kdc,Ticket

      账号A收到TGS_REP后,用Kclt-kdc解开{Kclt-srv}Kclt-kdc,得到Kclt-srv,Ticket发给B,以后多次访问B都可用这个Ticket,不用每次向KDC申请,降低KDC负担。

       

      帐号A和帐号B互相认证:

      帐号A给B发送“{帐号A的信息,时间戳}”Kclt-srv,以及上一步收到的Ticket,请求称为AP_REQ。

      AP_REQ=“{帐号A的信息,时间戳}Kclt-srv”,Ticket

      B能用Ksrv解开Ticket得到Kclt-srv,用Kclt-srv解开“{帐号A的信息,时间戳}Kclt-srv”,B就能确认A为真,回复AP_REP来证明自己也是真的。

      AP_REP={时间戳}Kclt-srv

      帐号A利用Kclt-srv解密AP-REP,通过得到时间戳来判断对方是否为真。

       

      Wireshark解密查看必须Edit→Preferences→Protocols→KRB5,keytab file输入key的路径才能解密。

       

      客户可以用\\IP地址 访问,但是用域名就不行:

      用IP是NTLM身份认证的,用域名则是Kerberos认证的,机制不一样,注意时钟,NTLM不会因为怀疑重放攻击拒绝访问。

       

      SACK机制(Selective Ack):

      如果一个包丢了,接收方发现了,那这个包后续的包也要重传,因为无法确定是否也丢失,但是接收方虽然知道丢了哪些包没法告知发送发,RFC2018中给出了方案,SACK启用的情况下,接收方能告诉发送方,它只需要重发的那个包,可以减少大量不必要的重传。