一般主动信息收集分为:二层扫描,三层扫描,四层扫描,端口扫描
开放系统互联参考模型将网络分为七层(物理层,数据链路层,网络层,传输层,会话层,表示层,应用层)
一,基于数据链路层的发现(二层发现)
数据链路层的数据单位为帧,主要分为 逻辑链路控制(LLC)和介质访问控制(MAC)
其中主要的协议是ARP协议
ARP协议即地址解析协议,它将32位ip地址解析为48位以太网地址
需要注意的是arp协议对应二层广播包,而广播包是无法通过路由或网关访问外部地址的
具体抓包分析
利用scapy构造一个对网关的ARP请求
[scapy]
>>>a=sr1(ARP(pdst="192.168.1.1"))
Begin emission:
*Finished sending 1 packets.
Received 1 packets, got 1 answers, remaining 0 packets
返回了一个回应,可以看到地址已经被解析返回
>>> a.display()
###[ ARP ]###
hwtype= 0x1
ptype= 0x800
hwlen= 6
plen= 4
op= is-at
hwsrc= e4:f3:aa:30:a8:de
psrc= 192.168.1.1
hwdst= 28:56:4a:07:02:23
pdst= 192.168.1.104
具体抓包查看,下面是抓到的完整的ARP请求包,可以看到目标地址ip为192.168.1.1(网关路由器) ,本机ip 192.168.1.104
获取到的返回ARP包,此时的源地址为192.168.1.1 代表路由器返回一个ARP响应给我们,同时发送了自身的MAC地址,解析完成
那么我们可以使用这种方式来对任意的ip地址进行请求,从而判断主机的状态
当我发送的arp请求没有回应时,说明主机不存在或者未开机
如下可以看出:
>>> t.pdst="192.168.1.12"
>>> t.display()
###[ ARP ]###
hwtype= 0x1
ptype= 0x800
hwlen= 6
plen= 4
op= who-has
hwsrc= 28:56:5a:07:02:23
psrc= 192.168.1.104
hwdst= 00:00:00:00:00:00
pdst= 192.168.1.12
>>> a=sr1(t)
Begin emission:
WARNING: Mac address to reach destination not found. Using broadcast.
Finished sending 1 packets.
.....................................
192.168.1.12在本局域网中是没有被分配的,故而长久得不到响应
这种利用arp包的方式探测会在网络中留下大量痕迹,因此隐蔽性较差,通常我们可以上网络中发送大量噪声干扰,隐藏真实意图
在kali linux 中具体的实现工具有arping nmap的sn参数
arping -c 1 192.168.1.1
root@BlackFace:~# arping -c 1 192.168.1.1
ARPING 192.168.1.1
58 bytes from e4:f3:f5:30:a8:de (192.168.1.1): index=0 time=4.246 msec
--- 192.168.1.1 statistics ---
1 packets transmitted, 1 packets received, 0% unanswered (0 extra)
rtt min/avg/max/std-dev = 4.246/4.246/4.246/0.000 ms
nmap -sn 192.168.1.1
root@BlackFace:~# nmap -sn 192.168.1.1
Starting Nmap 7.70 ( https://nmap.org ) at 2018-10-10 12:44 CST
Nmap scan report for 192.168.1.1
Host is up (0.0020s latency).
MAC Address: E4:F3:F5:30:A8:DE (Shenzhen Mercury Communication Technologies)
Nmap done: 1 IP address (1 host up) scanned in 6.64 seconds
两种工具的实现的底层协议包都是arp协议
批量访问网段内存活主机
可以利用scapy 构造一个arp 批量发现脚本
#!/usr/bin/python3
import sys
from scapy.all import *
if len(sys.argv) != 2:
print("Usage: ./scapy_arp.py 192.168.1.0")
print("scan 192.168.1.0/24 find surviving host")
sys.exit()
sgement_ip=sys.argv[1]
prefix_ip=sgement_ip.split(".")[0]+'.'+sgement_ip.split(".")[1]+'.'+sgement_ip.split(".")[2]+'.'
for addr in range(1,254):
response=sr1(ARP(pdst=prefix_ip+str(addr)),timeout=0.1,verbose=0)
try:
if response != None:
print(prefix_ip+str(addr))
except:
pass
结果(这种方法比较慢,但可以深刻理解arp发现的原理)
root@BlackFace:~# ./scapy_arp.py 192.168.1.0
192.168.1.1
192.168.1.100
192.168.1.102
192.168.1.103
192.168.1.105
192.168.1.109
可以看到可以发现一些存活的主机