ICMP基础知识及扫描和MAC泛洪

协议简介

ICMP(Internet Control Message Protocol)Internet控制报文协议,是TCP/IP协议族的一个子协议,一般不被直接使用传输数据,而是用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。由RFC792定义

TCP/IP协议栈核心协议之一
负责TCP/IP网络上、设备、服务协议、路由器的可用性信息
大部分网络检修都是依靠ICMP
数据包最大限制 64k

数据包详细

使用wireshark抓取ICMP数据包

ping数据包

请求包特征

Frame 25: 74 bytes on wire (592 bits), 74 bytes captured (592 bits) on interface 0
Ethernet II, Src: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26), Dst: IttimTec_77:20:50 (b0:41:1d:77:20:50) 数据链路层
Internet Protocol Version 4, Src: 192.168.100.104, Dst: 192.168.100.101 网络层
Internet Control Message Protocol ICMP协议
    Type: 8 (Echo (ping) request) 协议类型 表示请求数据包
    Code: 0 协议代码
    Checksum: 0x4d2e [correct] 校验和 
    [Checksum Status: Good]
    Identifier (BE): 1 (0x0001) 识别号
    Identifier (LE): 256 (0x0100)
    Sequence number (BE): 45 (0x002d) 序列号
    Sequence number (LE): 11520 (0x2d00)
    [Response frame: 26]
    Data (32 bytes) 随机字符串
        Data: 6162636465666768696a6b6c6d6e6f707172737475767761...
        [Length: 32]

响应包特征

Frame 26: 74 bytes on wire (592 bits), 74 bytes captured (592 bits) on interface 0
Ethernet II, Src: IttimTec_77:20:50 (b0:41:1d:77:20:50), Dst: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26) 数据链路层
Internet Protocol Version 4, Src: 192.168.100.101, Dst: 192.168.100.104 网络层
Internet Control Message Protocol ICMP协议
    Type: 0 (Echo (ping) reply) 协议类型 表示响应数据包
    Code: 0 协议代码
    Checksum: 0x552e [correct] 校验和
    [Checksum Status: Good]
    Identifier (BE): 1 (0x0001) 识别号
    Identifier (LE): 256 (0x0100)
    Sequence number (BE): 45 (0x002d) 序列号
    Sequence number (LE): 11520 (0x2d00)
    [Request frame: 25]
    [Response time: 9.284 ms]
    Data (32 bytes) 随机字符串
        Data: 6162636465666768696a6b6c6d6e6f707172737475767761...
        [Length: 32]

可以看到请求包和响应包的关系

  • 序列号对应
  • 随机字符串一致

由于ICMP请求数据包使用随机字符串进行验证,可以利用随机字符串进行操作系统识别或者放置一些数据位进行反向连接

tracert数据包

第一次请求包

Frame 20: 106 bytes on wire (848 bits), 106 bytes captured (848 bits) on interface 0
Ethernet II, Src: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26), Dst: Shenzhen_e6:2f:e2 (8c:f2:28:e6:2f:e2) 数据链路层
Internet Protocol Version 4, Src: 192.168.100.104, Dst: 183.232.231.173 网络层 
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
    Total Length: 92
    Identification: 0x65be (26046)
    Flags: 0x00
    Fragment offset: 0
    Time to live: 1
    Protocol: ICMP (1)
    Header checksum: 0x8f3c [validation disabled]
    [Header checksum status: Unverified]
    Source: 192.168.100.104
    Destination: 183.232.231.173
    [Source GeoIP: Unknown]
    [Destination GeoIP: Unknown]
Internet Control Message Protocol ICMP协议
    Type: 8 (Echo (ping) request) 协议类型 ICMP请求包
    Code: 0 协议代码
    Checksum: 0xf7be [correct] 校验和
    [Checksum Status: Good]
    Identifier (BE): 1 (0x0001) 识别号
    Identifier (LE): 256 (0x0100)
    Sequence number (BE): 64 (0x0040) 序列号
    Sequence number (LE): 16384 (0x4000)
    [No response seen]
    Data (64 bytes)
  • tracert请求和ping请求中的相差无几
  • 数据包网络层中TTL值为1,表示该数据包在遇到第一台路由器时会被丢弃

第一次响应包

Frame 21: 126 bytes on wire (1008 bits), 126 bytes captured (1008 bits) on interface 0
Ethernet II, Src: Shenzhen_e6:2f:e2 (8c:f2:28:e6:2f:e2), Dst: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26) 数据链路层
Internet Protocol Version 4, Src: 192.168.100.1, Dst: 192.168.100.104 网络层
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
    Total Length: 112
    Identification: 0x1a15 (6677)
    Flags: 0x00
    Fragment offset: 0
    Time to live: 64
    Protocol: ICMP (1)
    Header checksum: 0x16be [validation disabled]
    [Header checksum status: Unverified]
    Source: 192.168.100.1
    Destination: 192.168.100.104
    [Source GeoIP: Unknown]
    [Destination GeoIP: Unknown]
Internet Control Message Protocol ICMP协议
    Type: 11 (Time-to-live exceeded) 协议类型 表示TTL值超时,目标不可达
    Code: 0 (Time to live exceeded in transit)
    Checksum: 0xf4ff [correct]
    [Checksum Status: Good]
    Internet Protocol Version 4, Src: 192.168.100.104, Dst: 183.232.231.173 这是第一个请求包的头部信息
        0100 .... = Version: 4
        .... 0101 = Header Length: 20 bytes (5)
        Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        Total Length: 92
        Identification: 0x65be (26046)
        Flags: 0x00
        Fragment offset: 0
        Time to live: 1
        Protocol: ICMP (1)
        Header checksum: 0x8f3c [validation disabled]
        [Header checksum status: Unverified]
        Source: 192.168.100.104
        Destination: 183.232.231.173
        [Source GeoIP: Unknown]
        [Destination GeoIP: Unknown]
    Internet Control Message Protocol
        Type: 8 (Echo (ping) request)
        Code: 0
        Checksum: 0xf7be [unverified] [in ICMP error packet]
        [Checksum Status: Unverified]
        Identifier (BE): 1 (0x0001)
        Identifier (LE): 256 (0x0100)
        Sequence number (BE): 64 (0x0040)
        Sequence number (LE): 16384 (0x4000)
        Data (56 bytes)
  • 当路由器接收到TTL值为1的数据包时会回复一个数据包,告诉请求方TTL值超时,目标不可达
  • 回复数据包中包括了第一个请求包的头部信息,这叫双头包,在网络检修的时候非常有用

由于Windows操作系统的tracert功能默认发三次,所以下一次请求的数据包应该是第七个数据包

第二次请求包

Frame 95: 106 bytes on wire (848 bits), 106 bytes captured (848 bits) on interface 0
Ethernet II, Src: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26), Dst: Shenzhen_e6:2f:e2 (8c:f2:28:e6:2f:e2)
Internet Protocol Version 4, Src: 192.168.100.104, Dst: 183.232.231.173
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
    Total Length: 92
    Identification: 0x65c1 (26049)
    Flags: 0x00
    Fragment offset: 0
    Time to live: 2
    Protocol: ICMP (1)
    Header checksum: 0x8e39 [validation disabled]
    [Header checksum status: Unverified]
    Source: 192.168.100.104
    Destination: 183.232.231.173
    [Source GeoIP: Unknown]
    [Destination GeoIP: Unknown]
Internet Control Message Protocol
    Type: 8 (Echo (ping) request)
    Code: 0
    Checksum: 0xf7bb [correct]
    [Checksum Status: Good]
    Identifier (BE): 1 (0x0001)
    Identifier (LE): 256 (0x0100)
    Sequence number (BE): 67 (0x0043)
    Sequence number (LE): 17152 (0x4300)
    [No response seen]
    Data (64 bytes)
  • 第二次请求包的TTL值为2,表示数据包在遇到第二台路由器时会被丢弃
  • 同理,第二次回复包也是由于TTL值超时而返回的双头包。
  • 在没到达目标之前, 会一直叠加TTL值,直到达到目标

最后一次请求包

Frame 704: 106 bytes on wire (848 bits), 106 bytes captured (848 bits) on interface 0
Ethernet II, Src: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26), Dst: Shenzhen_e6:2f:e2 (8c:f2:28:e6:2f:e2)
Internet Protocol Version 4, Src: 192.168.100.104, Dst: 183.232.231.173
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
    Total Length: 92
    Identification: 0x65d9 (26073)
    Flags: 0x00
    Fragment offset: 0
    Time to live: 10
    Protocol: ICMP (1)
    Header checksum: 0x8621 [validation disabled]
    [Header checksum status: Unverified]
    Source: 192.168.100.104
    Destination: 183.232.231.173
    [Source GeoIP: Unknown]
    [Destination GeoIP: Unknown]
Internet Control Message Protocol
    Type: 8 (Echo (ping) request)
    Code: 0
    Checksum: 0xf7a3 [correct]
    [Checksum Status: Good]
    Identifier (BE): 1 (0x0001)
    Identifier (LE): 256 (0x0100)
    Sequence number (BE): 91 (0x005b)
    Sequence number (LE): 23296 (0x5b00)
    [Response frame: 705]
    Data (64 bytes)

最后一次响应包

Frame 705: 106 bytes on wire (848 bits), 106 bytes captured (848 bits) on interface 0
Ethernet II, Src: Shenzhen_e6:2f:e2 (8c:f2:28:e6:2f:e2), Dst: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26)
Internet Protocol Version 4, Src: 183.232.231.173, Dst: 192.168.100.104
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x04 (DSCP: Unknown, ECN: Not-ECT)
    Total Length: 92
    Identification: 0x65d9 (26073)
    Flags: 0x00
    Fragment offset: 0
    Time to live: 54
    Protocol: ICMP (1)
    Header checksum: 0x5a1d [validation disabled]
    [Header checksum status: Unverified]
    Source: 183.232.231.173
    Destination: 192.168.100.104
    [Source GeoIP: Unknown]
    [Destination GeoIP: Unknown]
Internet Control Message Protocol
    Type: 0 (Echo (ping) reply)
    Code: 0
    Checksum: 0xffa3 [correct]
    [Checksum Status: Good]
    Identifier (BE): 1 (0x0001)
    Identifier (LE): 256 (0x0100)
    Sequence number (BE): 91 (0x005b)
    Sequence number (LE): 23296 (0x5b00)
    [Request frame: 704]
    [Response time: 14.452 ms]
    Data (64 bytes)

以上就是tracert的过程

Python实现

这里实现的Python版本为3.6.4

Scapy

Scapy是一个强大的嗅探库,支持Python2和Python3。
Scapy有1.2和2.x两种版本,前者由于依赖unix系统的libpcap、libdnet等库已经弃用了。后者在Linux、BSD、Mac上使用 pip install scapy 就能安装Scapy。Windows系统较麻烦,要安装最新版的Npcap或Winpcap再使用 pip install scapy 安装。

安装完成后载入库不报错就证明安装成功

  • v1.2版本使用 from scapy import *
  • v2.x版本使用 from scapy.all import *

参考文档

代码实现

按照ARP扫描的最终代码,使用Scapy自带的队列扫描

Scapy检测网段是否存活
1
2
3
4
5
6
7
from scapy.all import *

pkt=Ether()/IP(proto="icmp",dst='192.168.100.1/24')/ICMP()
res,unans = srp(pkt,timeout=2,verbose=False)

for sned,rcv in res:
print(rcv.sprintf("%IP.src%--%Ether.src%"))

执行结果

192.168.100.1--8c:f2:28:e6:2f:e2
192.168.100.101--b0:41:1d:77:20:50
[Finished in 515.3s]

用这种方法扫描了八分钟,但是在ARP扫描确实能够减少扫描时间
这是因为在ARP扫描中,ARP的单次扫描速度比线程加载快。
而在ICMP扫描中,开始和结束单次扫描较慢,所以尝试用多线程进行优化

多线程检测网段存活
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import threading
from scapy.all import *

def scan(dip):
pkt=Ether()/IP(proto="icmp",dst=dip)/ICMP()
res = srp1(pkt,timeout=2,verbose=False)
if res:
print(res[1].src,res[0].dst)

if __name__ == '__main__':
for i in range(1,255):
dip = '192.168.100.'+str(i)
t = threading.Thread(target=scan,args=(dip,))
t.start()

执行结果

192.168.100.1 60:f6:77:a7:1e:26
192.168.100.101 60:f6:77:a7:1e:26
[Finished in 34.8s]

使用多线程速度比之前快多了

MAC泛洪

原理

一般在交换机中除了ARP缓存表之外,还有一个MAC地址表,两者都是通过往来的数据包构造对应的表。

两者的区别在于,ARP缓存表是记录IP地址(网络层)和MAC地址(数据链路层)的对应关系。而MAC地址表更加底层一些,记录MAC地址(数据链路层)和物理接口(物理层)的对应关系。

当交换机接收到数据包时,会记录数据帧中的源MAC地址和对应的接口到MAC地址表中。然后检查自身的MAC地址表是否存在目标MAC地址的信息,如果存在就单播发送,如果不存在就广播发送。

攻击的关键就在这里,正常情况下,主机之间通信是单播进行的,攻击者是看不到流量的。但是MAC地址表是有上限的,如果满了就写不下新的MAC地址条目。此时如果有新的主机进行通信,而交换机写不下也找不到该主机的MAC地址条目,就会进行广播发送,攻击者就能够看到交互数据了。

而发送攻击就是占满MAC地址表,让交换机进行广播。再结合MAC地址表的构造原理,可以通过发送大量的未知MAC地址通信数据包,交换机就会不断学习,很快就能占满MAC地址表。

使用scapy中的RandMAC()可以随机产生MAC地址,轻松达到这个目的。

Python代码

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python
#-*- coding:utf-8 -*-

import threading
from scapy.all import *
def send():
res = srp1(Ether(src=RandMAC(),dst=RandMAC())/IP(src=RandIP(),dst=RandIP())/ICMP(),timeout=2,verbose=False,iface='eth0')
return res

if __name__ == '__main__':
while True:
t = threading.Thread(target=send,args=())
t.start()

使用说明

python setup.py