四層發現


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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容