四层发现
title: 四层发现
date: 2016-05-11 09:45
tags: kali渗透测试 主动信息收集
0x00 碎语
首先我们要明确的是,发现的目的是扫描出可能存活的IP地址,四层发现虽然涉及端口扫描,但是并不对端口的状态进行识别,其本质是利用四层协议的一些通信来识别主机ip是否存在,至于端口的问题,以后在谈。
四层发现的优点是可路由且结果可靠;不太可能被防火墙过滤,甚至可以发现所有端口都被过滤的主机。缺点是基于状态过滤的防火墙可能过滤扫描;全端口(十几万个端口)扫描的速度慢。
0x01 四层发现如何探测目标
TCP探测
正确tcp连接是通过三次握手建立通信过程,然后可以向目标发送资源申请的请求,本机再发送ack进行确认,这是一种基于连接的可靠的通信协议,当然这是正确的时候。如果我们之前没有建立tcp连接,而是直接向目标发送tcp资源请求,这时目标服务器回想本机发送一个RST包(意思是,你是谁,我不认识你啊,你不能连我哦),因此,当目标服务器委婉且礼貌的拒绝我们时,便可以基于次探测目标主机是否存在了!这是已中国基于tcp协议的特征进行的一种判断。当然我们也可以通过正确的,即是通过三次握手建立通信连接,通过发送的SYN包来确定目标主机是否在线。
UDP探测
UDP不同于TCP,UDP没有通过握手建立连接的过程,UDP只是尽力而为而已,它是一种非连接的不可靠传输协议,因此基于UDP来探测主机,难度和发现的准确率都高于TCP。同样是基于UDP的一些特征信息来探测。
如果目标ip不在线,那我们对其发送的UDP包不会有任何的回应,但假如目标Ip在线,而且发送到UDP的目标端口处于开放状态,一般说来,这时目标主机接受到我的UDP包时也不会有任何回应,但有一种列外,即是目标端口没有开放时,会向我们发送一个ICMP不可达的包(但是到这里我们并不对其端口进行扫描)。
0x02 TCP发现
原理:通过非正常TCP连接,探测目标主机(防火墙,交换机,服务器)是否存在
ACK-->TCP Port-->RST
将TCP包头的flag位设定为ACK,然后发送给一个目标/端口,最后判断是否收到RST响应包,以此确定目标是否存在!
无论是基于几层的探测扫描,得到结果也只不过是一种极大可能的参考,一切都可能不是真实的
Scapy构造四层TCP探测数据包
先构造三层ip包,再构成四层tcp,然后将三层/四层组合起来构成一个TCP包
root@jack:~/scripts# scapy
WARNING: No route found for IPv6 destination :: (no default route?)
Welcome to Scapy (2.2.0)
>>> ip=IP()
>>> tcp=TCP()
>>> r=(ip/tcp)
>>> r[IP].dst="192.168.0.1" #设置目标Ip地址
>>>r[TCP].flags="A" #设置TCPflags为”ACK“
>>>r.display()
###[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= tcp
chksum= None
src= 192.168.0.109 #本机ip已经自动识别
dst= 192.168.0.1 #目标ip也已设置好
\options\
###[ TCP ]###
sport= ftp_data
dport= http #默认的tcp的端口是80端口
seq= 0
ack= 0
dataofs= None
reserved= 0
flags= A
window= 8192
chksum= None
urgptr= 0
options= {}
开始发包
>>> a=sr1(r)
Begin emission:
.Finished to send 1 packets.
*
Received 2 packets, got 1 answers, remaining 0 packets
>>> a.display()
###[ IP ]###
version= 4L
ihl= 5L
tos= 0x0
len= 40
id= 14705
flags=
frag= 0L
ttl= 64
proto= tcp
chksum= 0xbfa0
src= 192.168.0.1
dst= 192.168.0.109
\options\
###[ TCP ]###
sport= http
dport= ftp_data
seq= 0
ack= 0
dataofs= 5L
reserved= 0L
flags= R <---flags位由A变成了R
window= 0
chksum= 0x2dbe
urgptr= 0
options= {}
###[ Padding ]###
load= '\x00\x00\x13(\x82\x9e'
一条命令搞定
>>> a=sr1(IP(dst="192.168.0.1")/TCP(dport=80,flags='A'),timeout=1,verbose=0)
>>> a
<IP version=4L ihl=5L tos=0x0 len=40 id=50048 flags= frag=0L ttl=64 proto=tcp chksum=0x3591 src=192.168.0.1 dst=192.168.0.109 options=[] |<TCP sport=http dport=ftp_data seq=0 ack=0 dataofs=5L reserved=0L flags=R window=0 chksum=0x2dbe urgptr=0 |<Padding load='\x00\x00\x80+\x86\xfe' |>>>
Python脚本实现TCP四层扫描
#!/usr/bin/python
import logging
import subprocess
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
if len(sys.argv)!= 2:
print "Usage - ./ping1.py [/24 network address]"
print "Example - ./ping1.py 128.38.28.3"
sys.exit()
address = str(sys.argv[1])
prefix = address.split(".")[0]+'.'+address.split(".")[1]+'.'+address.split(".")[2]+'.'
for addr in range(1, 254):
response = sr1(IP(dst=prefix+str(addr))/TCP(dport=2222,flags='A'),timeout=0.1,verbose=0)
try:
if int(response[TCP].flags)==4: #tcp中Reset对应的flags是倒数第三位,2^2=4
print(prefix+str(addr))
except:
pass
0x03 UDP发现
一条命令搞定
>>> a=sr1(IP(dst="192.168.0.1")/UDP(dport=7643),timeout=0.1,verbose=0)
>>> a
<IP version=4L ihl=5L tos=0x0 len=56 id=63680 flags= frag=0L ttl=64 proto=icmp chksum=0x46 src=192.168.0.1 dst=192.168.0.109 options=[] |<ICMP type=dest-unreach code=port-unreachable chksum=0xdee4 unused=0 |<IPerror version=4L ihl=5L tos=0x0 len=28 id=1 flags= frag=0L ttl=64 proto=udp chksum=0xf911 src=192.168.0.109 dst=192.168.0.1 options=[] |<UDPerror sport=domain dport=7643 len=8 chksum=0x0 |>>>>
Python脚本实现UDP四层扫描
#!/usr/bin/python
import logging
import subprocess
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
if len(sys.argv)!= 2:
print "Usage - ./ping1.py [/24 network address]"
print "Example - ./ping1.py 128.38.28.3"
sys.exit()
address = str(sys.argv[1])
prefix = address.split(".")[0]+'.'+address.split(".")[1]+'.'+address.split(".")[2]+'.'
for addr in range(1, 254):
response = sr1(IP(dst=prefix+str(addr))/UDP(dport=7634),timeout=0.1,verbose=0)
try:
if int(response[IP].proto)==1: #为何是protoco=1,
#通过wireshark抓包可以发现
#ip层有protocol字段,指向它的上层协议,TCP为6,ICMP为1,IJMP
#为2,UDP为17,
#由此我们可以知道ip上层协议不一定除了tcp,就是udp,
#还可以是其它的很多类型的协议,在这里我们发送了一个udp包给
#目标,我们由是否接受到来自目标的icmp包来判断ip是否存活
print(prefix+str(addr))
except:
pass
0x04 nmap-四层发现
nmap很强大,它除了可以实现三层扫描,第四层也是信手拈来,如探囊取物一般,当然他的强大远不止于此。
- { Usage $: nmap [ip段] -PU[port] -sn }
只对ip段进行四层发现而不进行端口扫描,类似于UDP扫描
root@jack:~/MyBlog/hexo/source/_posts# nmap 221.22.0.1-50 -PU80 -sn
Starting Nmap 7.01 ( https://nmap.org ) at 2016-05-11 09:07 CST
Nmap scan report for softbank221022000006.bbtec.net (221.22.0.6)
Host is up (0.25s latency).
Nmap scan report for softbank221022000025.bbtec.net (221.22.0.25)
Host is up (0.18s latency).
Nmap done: 50 IP addresses (2 hosts up) scanned in 11.75 seconds
可以看到基于udp的扫描结果并不理想
- __ { Usage $: nmap [ip段] -PA[port] -sn }__
只对ip段进行四层发现而不进行端口扫描,类似于Scapy扫描
-
{ Usage $: nmap -iL iplist.txt -PA[port] -sn}
对已有ip地址进行存活检测
无论如何,以上方法并不是适用于所有互联网设备,但是对大部分还是有所收获的
0x05 hping3 四层发现
- { Usage $: hping3 -udp ip -c 1 }
hping3基于udp的四层发现
udp_hping3.sh核心代码
for addr in $(seq 1 254); do hping3 -udp $prefix.$addr -c 1 >> r.txt.done
grep Unreachable r.txt | cut -d" " -f 5 | cut -d"=" -f 2
- {Usage $: hping3 ip -c 1}
hping3基于tcp的四层发现,不加参数,默认就是
tcp_hping3.sh核心代码
prefix=$(echo $1 | cut -d"." -f 1-3)
for addr in $(seq 1 254);do
hping3 $prefix.$addr -c 1 >> r.txt
done
grep ^len r.txt | cut -d" " -f 2 | cut -d"=" -f 2 >> output.txt
rm r.txt
凡是hping发送的tcp所有的flags位都是not set的,即都是0的状态,它不同于udp的扫描,它通过返回的ack+rst包来判断主机存活!
hping3对四层扫描结果最不理想,当然这个就是智者见智!