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對四層掃描結果最不理想,當然這個就是智者見智!