题记
- hacker
A hacker is any highly skilled computer expert. - script kiddie
A script kiddie is an unskilled individual who uses scripts or programs developed by others to attach computer systems and networks and deface websites
ping命令
ping 这个名字来源于航海的声纳定位操作。其操作类似于声纳定位。只不过在网络里发送的是ICMP
数据包而不是声波。该命令的目的是用于确定 某个主机 是否可达,距离 当前主机 多远。
其实,我们2台网络设备互ping
,是有两种case
的。
- 同一网段
如上图,主机A,来ping
主机B,那么主机A,就要封装 二层报文 ,他会先查自己的MAC
地址表,如果没有B的MAC
地址,就会向外发送一个ARP广播包【在之前的网络篇已经讲的很清楚了,这里不再啰嗦】。
交换机会收到这个报文后,交换机有学习MAC
地址的功能,所以他会检索自己有没有保存主机B
的MAC
。
如果有,就返回给主机A
,如果没有,就会向所有端口发送ARP
广播,其它主机收到后,发现不是在找自己,就纷纷丢弃了该报文,不去理会。
直到主机B
收到了报文后,就立即相应,我的MAC
地址是多少,同时学到主机A
的MAC
地址,并按同样的ARP
报文格式返回给主机A
,如图:
这时候主机A
学到了主机B
的MAC
,就把这个MAC
封装到ICMP
协议的二层报文中向主机B
发送,报文格式如下:
目的地址 | 源地址 | 源IP | 目的IP | ICMP报文 |
---|---|---|---|---|
00-50-56-C0-00-03 | 00-50-56-C0-00-01 | 1.1.1.1 | 1.1.1.3 | Echo request |
当主机B
收到了这个报文后,发现是主机A
的ICPM
回显请求,就按 同样 的格式,返回一个值给主机A
,这样就完成了 同一网段内 的ping
过程~~
目的地址 | 源地址 | 源IP | 目的IP | ICMP报文 |
---|---|---|---|---|
00-50-56-C0-00-01 | 00-50-56-C0-00-03 | 1.1.1.3 | 1.1.1.1 | Echo answer |
而实际上,我啰嗦了这么久的的局域网内的PING
,实际过程的发生不到 1毫秒~~
- 不同网段
主机A
要ping
主机C
,那么主机A
发现主机C
的IP
和自己 不是 同一网段。
主机A
就去找 网关 转发,但是他也不知道网关的MAC
情况下呢?
他就会向之前那个步骤一样先发送一个ARP
广播,学到网关的MAC
,再发封装ICMP
报文给 网关路由器 。
报文格式如下:
目的地址 | 源地址 | 源IP | 目的IP | ICMP报文 |
---|---|---|---|---|
00-50-56-C0-00-02 | 00-50-56-C0-00-01 | 1.1.1.1 | 2.1.1.3 | Echo request |
当 路由器 收到主机A
发过来的ICMP
报文。
发现自己的目的地址是其本身MAC
地址,根据目的的IP2.1.1.1
,查 路由表,发现2.1.1.1/24
的路由表项。
得到一个 出口指针,去掉原来的MAC
头部.加上自己的MAC
地址向主机C
转发…
如果网关也没有主机C
的MAC
地址,还是要向前面一个步骤一样,ARP
广播一下即可相互学到….
路由器2
端口能学到主机C
的MAC
,主机C
也能学到路由器2
端口的MAC
..
报文格式如下:
目的地址 | 源地址 | 源IP | 目的IP | ICMP报文 |
---|---|---|---|---|
00-50-56-C0-00-05 | 00-50-56-C0-00-04 | 1.1.1.1 | 2.1.1.1 | Echo request |
最后,在主机C
已学到路由器2
端口MAC
,路由器2
端口转发给路由器1
端口。
路由1
端口学到主机A
的MAC
的情况下,他们就不需要再做ARP
解析,就将ICMP
的回显请求回复过来..
目的地址 | 源地址 | 源IP | 目的IP | ICMP报文 |
---|---|---|---|---|
00-50-56-C0-00-04 | 00-50-56-C0-00-05 | 2.1.1.1 | 1.1.1.1 | Echo Answer |
代码篇
既然已经明白了ping
命令和ICMP
的原理,那么我们就可以用代码来实现 自动化 工具~~~
赵四.尼古拉斯基 曾经说过:不要重复造轮子 。
那么,我们来介绍一下Python
处理网络协议
的 网络层、传输层、链路层 的能手 scapy
,和 爬虫框架 scrapy
表兄弟关系,开个玩笑~~
- Scapy 介绍
Scapy 是一个可以让用户 发送、侦听 和 解析 并伪装网络报文的
Python
程序。这些功能可以用于制作 侦测、扫描 和 攻击网络 的工具。
- 安装
pip3 install scapy
复制代码
- API
- 建立一个数据包
>>> a=IP(ttl=10) >>> a < IP ttl=10 |> >>> a.src ’127.0.0.1’ >>> a.dst="192.168.1.1" >>> a < IP ttl=10 dst=192.168.1.1 |> >>> a.src ’192.168.8.14’ >>> del(a.ttl) >>> a < IP dst=192.168.1.1 |> >>> a.ttl 64 复制代码
- 堆加层次(网络5层模型)
**/**操作符在两层之间起到一个 组合 的作用。
当使用该操作符时,下层 可以根据其 上层,使它的 一个 或 多个 默认字段被重载。 (您仍可以赋予您想要的值)一个字符串也可以被用作原料层(raw layer
)。
>>> IP() <IP |> >>> IP()/TCP() <IP frag=0 proto=TCP |<TCP |>> >>> Ether()/IP()/TCP() <Ether type=0x800 |<IP frag=0 proto=TCP |<TCP |>>> >>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n" <IP frag=0 proto=TCP |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>> >>> Ether()/IP()/IP()/UDP() <Ether type=0x800 |<IP frag=0 proto=IP |<IP frag=0 proto=UDP |<UDP |>>>> >>> IP(proto=55)/TCP() <IP frag=0 proto=55 |<TCP |>> 复制代码
- 发送
>>> a=Ether()/IP(dst="www.slashdot.org")/TCP()/"GET /index.html HTTP/1.0 \n\n" >>> hexdump(a) 00 02 15 37 A2 44 00 AE F3 52 AA D1 08 00 45 00 ...7.D...R....E. 00 43 00 01 00 00 40 06 78 3C C0 A8 05 15 42 23 [email protected]<....B# FA 97 00 14 00 50 00 00 00 00 00 00 00 00 50 02 .....P........P. 20 00 BB 39 00 00 47 45 54 20 2F 69 6E 64 65 78 ..9..GET /index 2E 68 74 6D 6C 20 48 54 54 50 2F 31 2E 30 20 0A .html HTTP/1.0 . 0A . >>> b=str(a) >>> b '\x00\x02\x157\xa2D\x00\xae\xf3R\xaa\xd1\x08\x00E\x00\x00C\x00\x01\x00\x00@\x06x<\xc0 \xa8\x05\x15B#\xfa\x97\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00 \xbb9\x00\x00GET /index.html HTTP/1.0 \n\n' 复制代码
原理 和API
都明白啦,是时候表演我们 真正的技术 啦
1. 构建一个ICMP包
2. 发送并且接受目的主机的回应
3. 如果目的主机可达,已3
为结束码并退出进程
Python
构建了一个探测工具,判断目的主机的网络连通性。
但仅仅如此还不够智能,我们需要加入多进程扫描整个网络中的活动主机,所以:
- 通过要扫描的I
P
,计算出当前区域网
的所有主机 - 多线程调用之前我们的探测工具,循环探测网络中的每个主机
- 讲能够连通的主机保存下来
- 为后面我们要做的事情做铺垫
关注微信公众账号【mindev】,回复【ping】可以获取单进程
ping
的源代码,加入群主星球即可获取所有源代码。
愿意与大家分享交流各种技术,个人公众账号[mindev],以及 知识星球[极客世界]