前面介绍过了二层、三层发现,今天就来分享一些四层发现的工具。
二三四层网络发现扫描目的是为了发现网络中存活的IP地址,虽然第四层是基于TCP和UDP进行扫描,但不对目标端口的状态进行识别。
四层网络的扫描发现只是使用了四层的网络通信来识别目标IP的存活状态。
四层发现有这些优点:
当然也有一些缺点:
前面说了四层发现使用了TCP和UDP,简单来说,大概是下面这样。
TCP:
直接发送ACK数据包,一般来说状态为up的目标主机会返回一个RST数据包以终止这个不正常的TCP链接;也可以发送正常的SYN数据包,如果目标主机返回SYN/ACK或者SRT数据包,都可以证明目标主机为up状态。
UDP:
如果目标ip为up状态且UDP目标端口为关闭状态,目标主机就会返回一个目标端口不可达的数据包,这就可以证明目标端口是up状态。
TCP和UDP的具体定义和交互逻辑就不在这里展开了,没有概念的可以网上查一下,有比较详细的讲解帖子。
需要注意的是,随着对于网络安全意识的提升,有些服务器对于扫描其实做了一定的防护,比如收到直接收到一个ACK的包就不返回数据包,避免被扫描到。所以现在扫描到的结果,都只是作为参考,不要完全相信。
用scapy演示一下使用TCP做四层扫描:
scapy使用tcp做四层扫描
收到的响应包:
a.display()
可以看出来返回的数据包flags=R,表示是一个RST。
用一行代码请求:
a = sr1(IP(dst='192.168.31.97')/TCP(dport=80,flags='A'), timeout=1)
根据上面的这些讲解,就可以做一个使用tcp做四层发现的脚本了:
#!/usr/bin/python
import logging
logging.getLogger('scapy.runtime').setLevel(logging.ERROR)
from scapy.all import *
if len(sys.argv) != 2:
print('Usage ./ack_ping_script.py [/24 network address]')
print('Example ./ack_ping_script.py 172.18.14.0')
print('Example will perform an TCP ACK ping scan of the 172.18.14.0/24 range')
sys.exit()
address = str(sys.argv[1])
ip_num_list = address.split('.')
prefix = ip_num_list[0] + '.' + ip_num_list[1] + '.' + ip_num_list[2] + '.'
for addr in range(1, 254):
a = sr1(IP(dst=prefix+str(addr))/TCP(dport=333,flags='A'), timeout=0.1, verbose=0)
try:
if int(a[TCP].flags) == 4:
print(prefix+str(addr))
except:
pass
解释一下脚本中20行为什么用4作为判断:
收到的响应包里面flags
从图片中可以看到RST转换成十进制后就是4,所以脚本中用来这样的判断。
执行前还是要改权限,执行过程就是这样:
python3 ack_ping_script.py 192.168.31.0
使用udp做四层扫描的时候,要设置那些几乎不会被使用的端口,因为我们就是在通过目标端口不可达来探测ip是否有效。
具体使用:
scapy使用udp做四层扫描
如果遇到ip不存在或者端口正常开放就不会收到返回的数据包:
目标ip不存在
也写一个使用udp做四层发现的脚本:
#!/usr/bin/python
import logging
logging.getLogger('scapy.runtime').setLevel(logging.ERROR)
from scapy.all import *
if len(sys.argv) != 2:
print('Usage ./udp_ping_script.py [/24 network address]')
print('Example ./udp_ping_script.py 172.18.14.0')
print('Example will perform an UDP ping scan of the 172.18.14.0/24 range')
sys.exit()
address = str(sys.argv[1])
ip_num_list = address.split('.')
prefix = ip_num_list[0] + '.' + ip_num_list[1] + '.' + ip_num_list[2] + '.'
for addr in range(1, 254):
a = sr1(IP(dst=prefix+str(addr))/UDP(dport=23687), timeout=0.1, verbose=0)
try:
if int(a[IP].proto) == 1:
print(prefix+str(addr))
except:
pass
解释一下第20行的判定依据:
1代表了ICMP
执行结果:
python3 udp_pinger.py 192.168.31.0
我在scapy使用tcp和udp做四层发现的时候,获取到的结果是有点差异的,所以再次提醒各位同学,对于扫描结果,只能作为参考。
nmap在三层、四层发现中的作用,应该算主流,当然也有可能是我接触的工具还比较少,如果更好用的工具,也请推荐给我一下。接下来介绍一下nmap在四层发现中的使用。
nmap使用udp做四层发现:
nmap 192.168.31.1-254 -PU12345 -sn
nmap使用tcp做四层发现:
nmap 192.168.1.1-254 -PA12345 -sn
其实nmap还提供了一些其他参数用来做四层发现:
四层发现的参数
实际使用中如果时间充裕,最好多换几种参数进行四层发现,也许会得到不一样的结果,综合比较后的结果会更有参考性。
前面的文章里也说过nmap也可以传ip文档作为入参,对文档中指定的ip进行扫描:
nmap -iL ip.txt -PA123 -sn
hping3也可以用来做四层发现,使用udp的话,就是这样:
hping3 --udp 192.168.31.97 -p 12345 -c 1
如果是用udp做四层发现,在传参中的端口也要使用一个没有被开启的端口。
写个用hping3做四层发现的脚本:
#!/bin/bash
if ["$#" -ne 1];then
echo 'Usage ./udp_hping3.sh [/24 network address]'
echo 'Example ./udp_hping3.sh 192.168.31.0'
echo 'Example will perform a UDP ping sweep of the 192.168.31.0/24 network and output to an output.txt file'
exit
fi
prefix=$(echo $1 cut -d '.' -f 1-3)
for addr in $(seq 1 254);do
hping3 $prefix.$addr --udp -p 13215 -c 1 >> r.txt
done
grep Unreachable r.txt cut -d ' ' -f 5 cut -d '=' -f 2 >> output.txt
rm r.txt
hping3在使用的时候不加--udp,就是默认使用tcp方式进行扫描:
hping3 192.168.31.168 -c 1
也可以写一个使用tcp的hping3脚本:
#!/bin/bash
if ["$#" -ne 1];then
echo 'Usage ./udp_hping3.sh [/24 network address]'
echo 'Example ./udp_hping3.sh 192.168.31.0'
echo 'Example will perform a UDP ping sweep of the 192.168.31.0/24 network and output to an output.txt file'
exit
fi
prefix=$(echo $1 cut -d '.' -f 1-3)
for addr in $(seq 1 254);do
hping3 $prefix.$addr -c 1 >> r.txt
done
grep Unreachable r.txt cut -d ' ' -f 5 cut -d '=' -f 2 >> output.txt
rm r.txt
执行结果就是这样:
./tcp_hping3.sh 36.152.44.0
这里提一下,如果你用hping3来扫描同网段的话,会自动降级使用arp协议,变成二层扫描,通过抓包可以看到,感兴趣可以试试。
……