Kali Linux 網絡掃描秘籍 第二章 探索掃描(二)

第二章 探索掃描(二)

作者:Justin Hutchens

譯者:飛龍

協議:CC BY-NC-SA 4.0

2.7 使用 Scapy 發現第三層

Scapy 是一種工具,允許用戶制作并向網絡中注入自定義數據包。 此工具可以用于構建 ICMP 協議請求,并將它們注入網絡來分析響應。 這個特定的秘籍演示了如何使用 Scapy 在遠程主機上執行第3層發現。

準備

使用 Scapy 執行第三層發現不需要實驗環境,因為 Internet 上的許多系統都將回復 ICMP 回顯請求。但是,強烈建議你只在您自己的實驗環境中執行任何類型的網絡掃描,除非你完全熟悉您受到任何管理機構施加的法律法規。如果你希望在實驗環境中執行此技術,你需要至少有一個響應 ICMP 請求的系統。在提供的示例中,使用 Linux 和 Windows 系統的組合。有關在本地實驗環境中設置系統的更多信息,請參閱第一章中的“安裝 Metasploitable2”和“安裝 Windows Server”秘籍。此外,本節還需要使用文本編輯器(如 VIM 或 Nano)將腳本寫入文件系統。有關編寫腳本的更多信息,請參閱第一章中的“使用文本編輯器(VIM 和 Nano)”秘籍。

操作步驟

為了使用 Scapy 發送 ICMP 回顯請求,我們需要開始堆疊層級來發送請求。 堆疊數據包時的一個好的經驗法則是,通過 OSI 按照的各層進行處理。 你可以通過使用斜杠分隔每個層級來堆疊多個層級。 為了生成 ICMP 回顯請求,IP 層需要與 ICMP 請求堆疊。 為了開始,請使用scapy命令打開 Scapy 交互式控制臺,然后將IP對象賦給變量:

root@KaliLinux:~# scapy Welcome to Scapy (2.2.0) 
>>> ip = IP() 
>>> ip.display() 
###[ IP ]###
  version= 4
  ihl= None
  tos= 0x0
  len= None
  id= 1
  flags=
  frag= 0
  ttl= 64
  proto= ip
  chksum= None
  src= 127.0.0.1
  dst= 127.0.0.1
  \options\ 

將新值賦給目標地址屬性后,可以通過再次調用display()函數來驗證更改。 請注意,當目標 IP 地址值更改為任何其他值時,源地址也會從回送地址自動更新為與默認接口關聯的 IP 地址。 現在 IP 對象的屬性已經適當修改了,我們將需要在我們的封包棧中創建第二層。 要添加到棧的下一個層是 ICMP 層,我們將其賦給單獨的變量:

>>> ping = ICMP() 
>>> ping.display() 
###[ ICMP ]###
  type= echo-request  
  code= 0  
  chksum= None  
  id= 0x0  
  seq= 0x0 

在所提供的示例中,ICMP 對象使用ping變量名稱初始化。 然后可以調用display()函數來顯示 ICMP 屬性的默認配置。 為了執行 ICMP 回顯請求,默認配置就足夠了。 現在兩個層都已正確配置,它們可以堆疊來準備發送。 在 Scapy 中,可以通過使用斜杠分隔每個層級來堆疊層級。 看看下面的命令集:

>>> ping_request = (ip/ping) 
>>> ping_request.display() 
###[ IP ]###
  version= 4
  ihl= None
  tos= 0x0
  len= None
  id= 1
  flags=
  frag= 0
  ttl= 64
  proto= icmp
  chksum= None
  src= 172.16.36.180
  dst= 172.16.36.135
  \options\
###[ ICMP ]###
     type= echo-request
     code= 0
     chksum= None
     id= 0x0
     seq= 0x0

一旦堆疊層級被賦給一個變量,display()函數可以顯示整個棧。 以這種方式堆疊層的過程通常被稱為數據報封裝。 現在已經堆疊了層級,并已經準備好發送請求。 這可以使用 Scapy 中的sr1()函數來完成:

>>> ping_reply = sr1(ping_request) 
..Begin emission:
.........
Finished to send 1 packets. 
...* 
Received 15 packets, got 1 answers, remaining 0 packets 
>>> ping_reply.display() 
###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0x0
  len= 28
  id= 62577
  flags=
  frag= 0L
  ttl= 64
  proto= icmp
  chksum= 0xe513
  src= 172.16.36.135
  dst= 172.16.36.180
  \options\ 
###[ ICMP ]###
     type= echo-reply
     code= 0
     chksum= 0xffff
     id= 0x0
     seq= 0x0 
###[ Padding ]###
        load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ x00\x00\x00\x00'

在提供的示例中,sr1()函數賦給了ping_reply變量。 這將執行該函數,然后將結果傳遞給此變量。 在接收到響應后,在ping_reply變量上調用display()函數來查看響應的內容。請注意,此數據包是從我們發送初始請求的主機發送的,目標地址是 Kali 系統的 IP 地址。 另外,注意響應的 ICMP 類型是回應應答。 基于此示例,使用 Scapy 發送和接收 ICMP 的過程看起來很有用,但如果你嘗試對非響應的目標地址使用相同的步驟,你會很快注意到問題:

>>> ip.dst = "172.16.36.136" 
>>> ping_request = (ip/ping) 
>>> ping_reply = sr1(ping_request) 
.Begin emission: 
......................................................................... ......................................................................... ........... 
Finished to send 1 packets 
.................................. .................................................................... 
                        *** {TRUNCATED} *** 

示例輸出被截斷,但此輸出應該無限繼續,直到你使用Ctrl + C強制關閉。不向函數提供超時值,sr1()函數會繼續監聽,直到接收到響應。 如果主機不是活動的,或者如果 IP 地址沒有與任何主機關聯,則不會發送響應,并且該功能也不會退出。 為了在腳本中有效使用此函數,應定義超時值:

>>> ping_reply = sr1(ping_request, timeout=1) 
.Begin emission: 
....................................................................... ....................................................................... 
Finished to send 1 packets. 
.................................... 
Received 3982 packets, got 0 answers, remaining 1 packets

通過提供超時值作為傳遞給sr1()函數的第二個參數,如果在指定的秒數內沒有收到響應,進程將退出。 在所提供的示例中,sr1()函數用于將 ICMP 請求發送到無響應地址,因為未收到響應,會在 1 秒后退出。 到目前為止提供的示例中,我們將函數賦值給變量,來創建持久化和可操作的對象。 但是,這些函數不必復制給變量,也可以通過直接調用函數生成。

>>> answer = sr1(IP(dst="172.16.36.135")/ICMP(),timeout=1) 
.Begin emission:
...*
Finished to send 1 packets.
Received 5 packets, got 1 answers, remaining 0 packets 
>>> response.display() 
###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0x0
  len= 28
  id= 62578
  flags=
  frag= 0L
  ttl= 64
  proto= icmp
  chksum= 0xe512
  src= 172.16.36.135
  dst= 172.16.36.180
  \options\ 
###[ ICMP ]###
     type= echo-reply
     code= 0
     chksum= 0xffff
     id= 0x0
     seq= 0x0 
###[ Padding ]###
        load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ x00\x00\x00\x00' 

在這里提供的示例中,之前使用四個單獨的命令完成的所有工作,實際上可以通過直接調用函數的單個命令來完成。 請注意,如果在超時值指定的時間范圍內, ICMP 請求沒有收到 IP 地址的回復,調用對象會產生異常。 由于未收到響應,因此此示例中賦值為響應的應答變量不會初始化:

>>> answer = sr1(IP(dst="83.166.169.231")/ICMP(),timeout=1) 
Begin emission: 
..........................................
Finished to send 1 packets. 
......................................................................... ..........................
Received 1180 packets, got 0 answers, remaining 1 packets 
>>> answer.display() 
Traceback (most recent call last):  File "<console>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'display'

有關這些不同響應的知識,可以用于生成在多個 IP 地址上按順序執行 ICMP 請求的腳本。 腳本會循環遍歷目標 IP 地址中最后一個八位字節的所有可能值,并為每個值發送一個 ICMP 請求。 當從每個sr1()函數返回時,將評估響應來確定是否接收到應答的響應:

#!/usr/bin/python

import logging 
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) 
from scapy.all import *

if len(sys.argv) != 2:   
    print "Usage - ./pinger.py [/24 network address]"   
    print "Example - ./pinger.py 172.16.36.0"   
    print "Example will perform an ICMP scan of the 172.16.36.0/24 range"   
    sys.exit()

address = str(sys.argv[1]) 
prefix = address.split('.')[0] + '.' + address.split('.')[1] + '.' + address.split('.')[2] + '.'

for addr in range(1,254):   
    answer=sr1(ARP(pdst=prefix+str(addr)),timeout=1,verbose=0)   
    if answer == None:      
        pass   
    else:      
        print prefix+str(addr)

腳本的第一行標識了 Python 解釋器所在的位置,以便腳本可以在不傳遞到解釋器的情況下執行。 然后腳本導入所有 Scapy 函數,并定義 Scapy 日志記錄級別,以消除腳本中不必要的輸出。 還導入了子過程庫,以便于從系統調用中提取信息。 第二個代碼塊是條件測試,用于評估是否向腳本提供了所需的參數。 如果在執行時未提供所需的參數,則腳本將輸出使用情況的說明。 該說明包括工具的用法,示例和所執行任務的解釋。

在這個代碼塊之后,有一個單獨的代碼行將所提供的參數賦值給interface變量。下一個代碼塊使用check_output()子進程函數執行ifconfig系統調用,該調用也使用grepcut從作為參數提供的本地接口提取 IP 地址。然后將此輸出賦給ip變量。然后使用split函數從 IP 地址字符串中提取/ 24網絡前綴。例如,如果ip變量包含192.168.11.4字符串,則值為192.168.11。它將賦給prefix變量。

最后一個代碼塊是一個用于執行實際掃描的for循環。 for循環遍歷介于 0 和 254 之間的所有值,并且對于每次迭代,該值隨后附加到網絡前綴后面。在早先提供的示例的中,將針對192.168.11.0192.168.11.254之間的每個 IP 地址發送 ICMP 回顯請求。然后對于每個回復的活動主機,將相應的 IP 地址打印到屏幕上,以表明主機在 LAN 上活動。一旦腳本被寫入本地目錄,你可以在終端中使用句號和斜杠,然后是可執行腳本的名稱來執行它。看看以下用于執行腳本的命令:

root@KaliLinux:~# ./pinger.py 
Usage - ./pinger.py [/24 network address] 
Example - ./pinger.py 172.16.36.0 
Example will perform an ICMP scan of the 172.16.36.0/24 range 
root@KaliLinux:~# ./pinger.py 
172.16.36.0 
172.16.36.2 
172.16.36.1 
172.16.36.132 
172.16.36.135 

如果在沒有提供任何參數的情況下執行腳本,則會將使用方法輸出到屏幕。 使用方法輸出表明,此腳本需要用于定義要掃描的/ 24網絡的單個參數。 提供的示例使用172.16.36.0網絡地址來執行腳本。 該腳本然后輸出在/ 24網絡范圍上的活動 IP 地址的列表。 此輸出也可以使用尖括號重定向到輸出文本文件,后跟輸出文件名。 一個例子如下:

root@KaliLinux:~# ./pinger.py 172.16.36.0 > output.txt 
root@KaliLinux:~# ls output.txt 
output.txt 
root@KaliLinux:~# cat output.txt 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135

然后可以使用ls命令來驗證輸出文件是否已寫入文件系統,或者可以使用cat命令查看其內容。 也可以修改此腳本,來接受 IP 地址列表作為輸入。 為此,必須更改for循環來循環遍歷從指定的文本文件讀取的行。 一個例子如下:

#!/usr/bin/python

import logging 
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) 
from scapy.all import *

if len(sys.argv) != 2:   
    print "Usage - ./pinger.py [filename]"   
    print "Example - ./pinger.py iplist.txt"   
    print "Example will perform an ICMP ping scan of the IP addresses listed in iplist.txt"   
    sys.exit()

filename = str(sys.argv[1]) 
file = open(filename,'r')

for addr in file:   
    ans=sr1(IP(dst=addr.strip())/ICMP(),timeout=1,verbose=0)   
    if ans == None:      
        pass   
    else:      
        print addr.strip()

與之前的腳本唯一的主要區別是,它接受一個輸入文件名作為參數,然后循環遍歷此文件中列出的每個 IP 地址進行掃描。 與其他腳本類似,生成的輸出包括響應 ICMP 回顯請求的系統的相關 IP 地址的簡單列表,其中包含 ICMP 回顯響應:

root@KaliLinux:~# ./pinger.py 
Usage - ./pinger.py [filename] 
Example - ./pinger.py iplist.txt 
Example will perform an 
ICMP ping scan of the IP addresses listed in iplist.txt 
root@KaliLinux:~# ./pinger.py iplist.txt 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135

此腳本的輸出可以以相同的方式重定向到輸出文件。 使用作為參數提供的輸入文件來執行腳本,然后使用尖括號重定向輸出,后跟輸出文本文件的名稱。 一個例子如下:

root@KaliLinux:~# ./pinger.py iplist.txt > output.txt 
root@KaliLinux:~# ls output.txt 
output.txt 
root@KaliLinux:~# cat output.txt 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135

工作原理

此處使用 Scapy 通過構造包括 IP 層和附加的 ICMP 請求的請求來執行 ICMP 第三層發現。 IP 層能夠將封包路由到本地網絡之外,并且 ICMP 請求用于從遠程系統請求響應。 在 Python 腳本中使用此技術,可以按順序執行此任務,來掃描多個系統或整個網絡范圍。

2.8 使用 Nmap 發現第三層

Nmap 是 Kali Linux 中最強大和最通用的掃描工具之一。 因此,毫不奇怪,Nmap 也支持 ICMP 發現掃描。 該秘籍演示了如何使用 Nmap 在遠程主機上執行第三層發現。

準備

使用 Nmap 執行第三層發現不需要實驗環境,因為 Internet 上的許多系統都將回復 ICMP 回顯請求。但是,強烈建議你只在您自己的實驗環境中執行任何類型的網絡掃描,除非你完全熟悉您受到任何管理機構施加的法律法規。如果你希望在實驗環境中執行此技術,你需要至少有一個響應 ICMP 請求的系統。在提供的示例中,使用 Linux 和 Windows 系統的組合。有關在本地實驗環境中設置系統的更多信息,請參閱第一章中的“安裝 Metasploitable2”和“安裝 Windows Server”秘籍。此外,本節還需要使用文本編輯器(如 VIM 或 Nano)將腳本寫入文件系統。有關編寫腳本的更多信息,請參閱第一章中的“使用文本編輯器(VIM 和 Nano)”秘籍。

操作步驟

Nmap是一種自適應工具,它可以按需自動調整,并執行第2層,第3層或第4層發現。 如果-sn選項在 Nmap 中用于掃描本地網段上不存在的 IP 地址,則 ICMP 回顯請求將用于確定主機是否處于活動狀態和是否響應。 為了對單個目標執行 ICMP 掃描,請使用帶有-sn選項的Nmap,并傳遞要掃描的 IP 地址作為參數:

root@KaliLinux:~# nmap -sn 74.125.228.1
Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-16 23:05 EST 
Nmap scan report for iad23s05-in-f1.1e100.net (74.125.228.1) 
Host is up (0.00013s latency). 
Nmap done: 1 IP address (1 host up) scanned in 0.02 seconds 

此命令的輸出表明了設備是否已啟動,還會提供有關所執行掃描的詳細信息。 此外請注意,系統名稱也已確定。 Nmap 還執行 DNS 解析來在掃描輸出中提供此信息。 它還可以用于使用破折號符號掃描 IP 地址連續范圍。 Nmap 默認情況下是多線程的,并且并行運行多個進程。 因此,Nmap 在返回掃描結果時非常快。 看看下面的命令:

root@KaliLinux:~# nmap -sn 74.125.228.1-255
Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-16 23:14 EST 
Nmap scan report for iad23s05-in-f1.1e100.net (74.125.228.1) 
Host is up (0.00012s latency). 
Nmap scan report for iad23s05-in-f2.1e100.net (74.125.228.2) 
Host is up (0.0064s latency). 
Nmap scan report for iad23s05-in-f3.1e100.net (74.125.228.3) 
Host is up (0.0070s latency). 
Nmap scan report for iad23s05-in-f4.1e100.net (74.125.228.4) 
Host is up (0.00015s latency). 
Nmap scan report for iad23s05-in-f5.1e100.net (74.125.228.5) 
Host is up (0.00013s latency). 
Nmap scan report for iad23s05-in-f6.1e100.net (74.125.228.6) 
Host is up (0.00012s latency). 
Nmap scan report for iad23s05-in-f7.1e100.net (74.125.228.7) 
Host is up (0.00012s latency). 
Nmap scan report for iad23s05-in-f8.1e100.net (74.125.228.8) 
Host is up (0.00012s latency). 
                    *** {TRUNCATED} ***

在提供的示例中,Nmap 用于掃描整個/ 24網絡范圍。 為了方便查看,此命令的輸出被截斷。 通過使用 Wireshark 分析通過接口的流量,你可能會注意到這些地址沒有按順序掃描。 這可以在以下屏幕截圖中看到。 這是 Nmap 的多線程特性的進一步證據,并展示了當其他進程完成時,如何從隊列中的地址啟動進程:

或者,Nmap 也可用于掃描輸入文本文件中的 IP 地址。 這可以使用-iL選項,后跟文件或文件路徑的名稱來完成:

root@KaliLinux:~# cat iplist.txt 
74.125.228.13 74.125.228.28 
74.125.228.47 74.125.228.144 
74.125.228.162 74.125.228.211 
root@KaliLinux:~# nmap -iL iplist.txt -sn
Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-16 23:14 EST 
Nmap scan report for iad23s05-in-f13.1e100.net (74.125.228.13) 
Host is up (0.00010s latency). 
Nmap scan report for iad23s05-in-f28.1e100.net (74.125.228.28) 
Host is up (0.0069s latency). 
Nmap scan report for iad23s06-in-f15.1e100.net (74.125.228.47) 
Host is up (0.0068s latency). 
Nmap scan report for iad23s17-in-f16.1e100.net (74.125.228.144) 
Host is up (0.00010s latency). 
Nmap scan report for iad23s18-in-f2.1e100.net (74.125.228.162) 
Host is up (0.0077s latency). 
Nmap scan report for 74.125.228.211 
Host is up (0.00022s latency). 
Nmap done: 6 IP addresses (6 hosts up) scanned in 0.04 seconds

在提供的示例中,執行目錄中存在六個 IP 地址的列表。 然后將此列表輸入到 Nmap 中,并掃描每個列出的地址來嘗試識別活動主機。

工作原理

Nmap 通過對提供的范圍或文本文件中的每個 IP 地址發出 ICMP 回顯請求,來執行第3層掃描。 由于 Nmap 是一個多線程工具,所以它會并行發送多個請求,結果會很快返回給用戶。 由于 Nmap 的發現功能是自適應的,它只會使用 ICMP 發現,如果 ARP 發現無法有效定位本地子網上的主機。 或者,如果 ARP 發現或 ICMP 發現都不能有效識別給定 IP 地址上的活動主機時,那么將采第四層發現技術。

2.9 使用 fping 探索第三層

fping工具費長類似于著名的ping工具。 但是,它也內建了在ping中不存在的許多附加功能。 這些附加功能讓fping能夠用作功能掃描工具,無需額外修改。 該秘籍演示了如何使用fping在遠程主機上執行第3層發現。

準備

使用fping執行第三層發現不需要實驗環境,因為 Internet 上的許多系統都將回復 ICMP 回顯請求。但是,強烈建議你只在您自己的實驗環境中執行任何類型的網絡掃描,除非你完全熟悉您受到任何管理機構施加的法律法規。如果你希望在實驗環境中執行此技術,你需要至少有一個響應 ICMP 請求的系統。在提供的示例中,使用 Linux 和 Windows 系統的組合。有關在本地實驗環境中設置系統的更多信息,請參閱第一章中的“安裝 Metasploitable2”和“安裝 Windows Server”秘籍。

操作步驟

fping非常類似于添加了一些額外功能的ping工具。 它可以以ping的相同方式,向單個目標發送 ICMP 回顯請求,以確定它是否活動。 這通過將 IP 地址作為參數傳遞給fping實用程序來完成:

root@KaliLinux:~# fping 172.16.36.135 
172.16.36.135 is alive

與標準ping工具不同,fping會在收到單個應答后停止發送 ICMP 回顯請求。 在接收到回復時,它將顯示對應該地址的主機是活動的。 或者,如果未從地址接收到響應,則在確定主機不可達之前,fping通常嘗試聯系系統四次:

root@KaliLinux:~# fping 172.16.36.136 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.136 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.136 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.136 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 
172.16.36.136 172.16.36.136 is unreachable

可以使用-c count選項修改此默認連接嘗試次數,并向其提供一個定義嘗試次數的整數值:

root@KaliLinux:~# fping 172.16.36.135 -c 1 
172.16.36.135 : [0], 84 bytes, 0.67 ms (0.67 avg, 0% loss)

172.16.36.135 : xmt/rcv/%loss = 1/1/0%, min/avg/max = 0.67/0.67/0.67 
root@KaliLinux:~# fping 172.16.36.136 -c 1

172.16.36.136 : xmt/rcv/%loss = 1/0/100%

當以這種方式執行時,輸出更加隱蔽一些,但可以通過仔細分析來理解。 任何主機的輸出包括 IP 地址,嘗試次數(xmt),接收的回復數(rcv)和丟失百分比(%loss)。 在提供的示例中,fping發現第一個地址處于聯機狀態。 這可以由接收的字節數和應答的等待時間都被返回的事實來證明。 你還可以通過檢查百分比損失,來輕松確定是否存在與提供的 IP 地址關聯的活動主機。 如果百分比損失為 100,則未收到回復。

ping(最常用作故障排除工具)不同,fping內建了集成功能,可掃描多個主機。 可以使用fping掃描主機序列,使用-g選項動態生成 IP 地址列表。 要指定掃描范圍,請使用該參數傳遞所需序列范圍中的第一個和最后一個 IP 地址:

root@KaliLinux:~# fping -g 172.16.36.1 172.16.36.4 
172.16.36.1 is alive 
172.16.36.2 is alive 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.3
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.3 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.3 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.3 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.4 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.4 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.4 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.4 172.16.36.3 is unreachable 
172.16.36.4 is unreachable

生成列表選項也可用于基于 CIDR 范圍符號生成列表。 以相同的方式,fping將循環遍歷這個動態生成的列表并掃描每個地址:

root@KaliLinux:~# fping -g 172.16.36.0/24 
172.16.36.1 is alive 
172.16.36.2 is alive 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.3 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.4 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.5 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.6 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.7 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.8 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.9 
                    *** {TRUNCATED} ***

最后,fping還可以用于掃描由輸入文本文件的內容指定的一系列地址。 要使用輸入文件,請使用-f文件選項,然后提供輸入文件的文件名或路徑:

root@KaliLinux:~# fping -f iplist.txt 172.16.36.2 is alive 172.16.36.1 is alive 172.16.36.132 is alive 172.16.36.135 is alive 172.16.36.180 is alive 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.203 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.203 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.203 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.203 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.205 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.205 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.205 
ICMP Host Unreachable from 172.16.36.180 for ICMP Echo sent to 172.16.36.205 
172.16.36.203 is unreachable 
172.16.36.205 is unreachable 
172.16.36.254 is unreachable

工作原理

fping工具執行ICMP發現的方式與我們之前討論的其他工具相同。 對于每個 IP 地址,fping發送一個或多個 ICMP 回顯請求,然后評估所接收的響應以識別活動主機。 fping還可以用于通過提供適當的參數,來掃描一系列系統或 IP 地址的輸入列表。 因此,我們不必使用bash腳本來操作工具,就像使用ping操作一樣,使其成為有效的掃描工具。

2.10 使用 hping3 探索第三層

hping3可以用于以多種不同方式執行主機發現的更多功能。 它比fping更強大,因為它可以執行多種不同類型的發現技術,但作為掃描工具不太有用,因為它只能用于定位單個主機。 然而,這個缺點可以使用 bash 腳本克服。 該秘籍演示了如何使用hping3在遠程主機上執行第3層發現。

準備

使用hping3執行第三層發現不需要實驗環境,因為 Internet 上的許多系統都將回復 ICMP 回顯請求。但是,強烈建議你只在您自己的實驗環境中執行任何類型的網絡掃描,除非你完全熟悉您受到任何管理機構施加的法律法規。如果你希望在實驗環境中執行此技術,你需要至少有一個響應 ICMP 請求的系統。在提供的示例中,使用 Linux 和 Windows 系統的組合。有關在本地實驗環境中設置系統的更多信息,請參閱第一章中的“安裝 Metasploitable2”和“安裝 Windows Server”秘籍。

hping3是一個非常強大的發現工具,具有大量可操作的選項和模式。它能夠在第3層和第4層上執行發現。為了使用hping3對單個主機地址執行基本的 ICMP 發現, 只需要將要測試的 IP 地址和所需的 ICMP 掃描模式傳遞給它:

root@KaliLinux:~# hping3 172.16.36.1 --icmp 
HPING 172.16.36.1 (eth1 172.16.36.1): icmp mode set, 28 headers + 0 data bytes 
len=46 ip=172.16.36.1 ttl=64 id=41835 icmp_seq=0 rtt=0.3 ms 
len=46 ip=172.16.36.1 ttl=64 id=5039 icmp_seq=1 rtt=0.3 ms 
len=46 ip=172.16.36.1 ttl=64 id=54056 icmp_seq=2 rtt=0.6 ms 
len=46 ip=172.16.36.1 ttl=64 id=50519 icmp_seq=3 rtt=0.5 ms 
len=46 ip=172.16.36.1 ttl=64 id=47642 icmp_seq=4 rtt=0.4 ms 
^C 
--- 172.16.36.1 hping statistic --5 packets transmitted, 
5 packets received, 0% packet loss 
round-trip min/avg/max = 0.3/0.4/0.6 ms

提供的演示使用Ctrl + C停止進程。與標準ping工具類似,hping3 ICMP 模式將無限繼續,除非在初始命令中指定了特定數量的數據包。 為了定義要發送的嘗試次數,應包含-c選項和一個表示所需嘗試次數的整數值:

root@KaliLinux:~# hping3 172.16.36.1 --icmp -c 2 
HPING 172.16.36.1 (eth1 172.16.36.1): icmp mode set, 28 headers + 0 data bytes 
len=46 ip=172.16.36.1 ttl=64 id=40746 icmp_seq=0 rtt=0.3 ms 
len=46 ip=172.16.36.1 ttl=64 id=12231 icmp_seq=1 rtt=0.5 ms
--- 
172.16.36.1 hping statistic --
2 packets transmitted, 2 packets received, 0% packet loss 
round-trip min/avg/max = 0.3/0.4/0.5 ms

雖然hping3默認情況下不支持掃描多個系統,但可以使用 bash 腳本輕易編寫腳本。 為了做到這一點,我們必須首先確定與活動地址相關聯的輸出,以及與非響應地址相關聯的輸出之間的區別。 為此,我們應該在未分配主機的 IP 地址上使用相同的命令:

root@KaliLinux:~# hping3 172.16.36.4 --icmp -c 2 
HPING 172.16.36.4 (eth1 172.16.36.4): icmp mode set, 28 headers + 0 data bytes
--- 
172.16.36.4 hping statistic --
2 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms 
1 packets transmitted, 1 packets received, 0% packet loss 
round-trip min/avg/max = 0.2/0.2/0.2 ms
--- 172.16.36.4 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms 

盡管產生了期望的結果,在這種情況下,grep函數似乎不能有效用于輸出。 由于hping3中的輸出顯示處理,它難以通過管道傳遞到grep函數,并只提取所需的行,我們可以嘗試通過其他方式解決這個問題。 具體來說,我們將嘗試確定輸出是否可以重定向到一個文件,然后我們可以直接從文件中grep。 為此,我們嘗試將先前使用的兩個命令的輸出傳遞給handle.txt文件:

root@KaliLinux:~# hping3 172.16.36.1 --icmp -c 1 >> handle.txt

--- 172.16.36.1 hping statistic --
1 packets transmitted, 1 packets received, 0% packet loss 
round-trip min/avg/max = 0.4/0.4/0.4 ms 
root@KaliLinux:~# hping3 172.16.36.4 --icmp -c 1 >> handle.txt

--- 172.16.36.4 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms 
root@KaliLinux:~# cat handle.txt 
HPING 172.16.36.1 (eth1 172.16.36.1): icmp mode set, 28 headers + 0 data bytes 
len=46 ip=172.16.36.1 ttl=64 id=56022 icmp_seq=0 rtt=0.4 ms 
HPING 172.16.36.4 (eth1 172.16.36.4): icmp mode set, 28 headers + 0 data bytes 

雖然這種嘗試并不完全成功,因為輸出沒有完全重定向到文件,我們可以看到通過讀取文件中的輸出,足以創建一個有效的腳本。 具體來說,我們能夠重定向一個唯一的行,該行只與成功的ping嘗試相關聯,并且包含該行中相應的 IP 地址。 要驗證此解決方法是否可行,我們需要嘗試循環訪問/ 24范圍中的每個地址,然后將結果傳遞到handle.txt文件:

root@KaliLinux:~# for addr in $(seq 1 254); do hping3 172.16.36.$addr --icmp -c 1 >> handle.txt & done

--- 172.16.36.2 hping statistic --
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 6.6/6.6/6.6 ms

--- 172.16.36.1 hping statistic --
1 packets transmitted, 1 packets received, 0% packet loss 
round-trip min/avg/max = 55.2/55.2/55.2 ms

--- 172.16.36.8 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms 
                    *** {TRUNCATED} ***

通過這樣做,仍然有大量的輸出(提供的輸出為了方便而被截斷)包含未重定向到文件的輸出。 但是,以下腳本的成功不取決于初始循環的過多輸出,而是取決于從輸出文件中提取必要信息的能力:

root@KaliLinux:~# ls 
Desktop  handle.txt  pinger.sh 
root@KaliLinux:~# grep len handle.txt 
len=46 ip=172.16.36.2 ttl=128 id=7537 icmp_seq=0 rtt=6.6 ms 
len=46 ip=172.16.36.1 ttl=64 id=56312 icmp_seq=0 rtt=55.2 ms 
len=46 ip=172.16.36.132 ttl=64 id=47801 icmp_seq=0 rtt=27.3 ms 
len=46 ip=172.16.36.135 ttl=64 id=62601 icmp_seq=0 rtt=77.9 ms
root@KaliLinux:~# grep len handle.txt | cut -d " " -f 2 
ip=172.16.36.2 
ip=172.16.36.1 
ip=172.16.36.132 
ip=172.16.36.135
root@KaliLinux:~# grep len handle.txt | cut -d " " -f 2 | cut -d "=" -f 2 
172.16.36.2 
172.16.36.1 
172.16.36.132
172.16.36.135 

通過將輸出使用管道連接到一系列cut函數,我們可以從輸出中提取 IP 地址。 現在我們已經成功地確定了一種方法,來掃描多個主機并輕易識別結果,我們應該將其集成到一個腳本中。 將所有這些操作組合在一起的功能腳本的示例如下:

#!/bin/bash

if [ "$#" -ne 1 ]; then
    echo "Usage - ./ping_sweep.sh [/24 network address]" 
    echo "Example - ./ping_sweep.sh 172.16.36.0" 
    echo "Example will perform an ICMP ping sweep of the 172.16.36.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 --icmp -c 1 >> handle.txt; 
done

grep len handle.txt | cut -d " " -f 2 | cut -d "=" -f 2 >> output.txt 
rm handle.txt 

在提供的 bash 腳本中,第一行定義了 bash 解釋器的位置。 接下來的代碼塊執行測試來確定是否提供了預期的一個參數。 這通過評估提供的參數的數量是否不等于 1 來確定。如果未提供預期參數,則輸出腳本的用法,并且退出腳本。 用法輸出表明,腳本需要接受/ 24網絡地址作為參數。 下一行代碼從提供的網絡地址中提取網絡前綴。 例如,如果提供的網絡地址是192.168.11.0,則前綴變量將被賦值為192.168.11。 然后對/ 24范圍內的每個地址執行hping3操作,并將每個任務的結果輸出放入handle.txt文件中。

一旦完成,grep用于從handle文件中提取與活動主機響應相關聯的行,然后從這些行中提取 IP 地址。 然后將生成的 IP 地址傳遞到output.txt文件,并從目錄中刪除handle.txt臨時文件。 此腳本可以使用句號和斜杠,后跟可執行腳本的名稱執行:

root@KaliLinux:~# ./ping_sweep.sh 
Usage - ./ping_sweep.sh [/24 network address] 
Example - ./ping_sweep.sh 172.16.36.0 
Example will perform an ICMP ping sweep of the 172.16.36.0/24 network and output to an output.txt file 
root@KaliLinux:~# ./ping_sweep.sh 172.16.36.0
--- 172.16.36.1 hping statistic --
1 packets transmitted, 1 packets received, 0% packet loss 
round-trip min/avg/max = 0.4/0.4/0.4 ms
--- 172.16.36.2 hping statistic --
1 packets transmitted, 1 packets received, 0% packet loss 
round-trip min/avg/max = 0.5/0.5/0.5 ms
--- 172.16.36.3 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms
                        *** {TRUNCATED} ***

一旦完成,腳本應該返回一個output.txt文件到執行目錄。 這可以使用ls驗證,并且cat命令可以用于查看此文件的內容:

root@KaliLinux:~# ls output.txt 
output.txt 
root@KaliLinux:~# cat output.txt 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135 
172.16.36.253

當腳本運行時,你仍然會看到在初始循環任務時看到的大量輸出。 幸運的是,你發現的主機列表不會在此輸出中消失,因為它每次都會寫入你的輸出文件。

工作原理

我們需要進行一些調整,才能使用hping3對多個主機或地址范圍執行主機發現。 提供的秘籍使用 bash 腳本順序執行 ICMP 回應請求。 這是可性的,因為成功和不成功的請求能夠生成唯一響應。 通過將函數傳遞給一個循環,并將唯一響應傳遞給grep,我們可以高效開發出一個腳本,對多個系統依次執行 ICMP 發現,然后輸出活動主機列表。

2.11 使用 Scapy 探索第四層

多種不同方式可以用于在第四層執行目標發現。可以使用用戶數據報協議(UDP)或傳輸控制協議(TCP)來執行掃描。 Scapy 可以用于使用這兩種傳輸協議來制作自定義請求,并且可以與 Python 腳本結合使用以開發實用的發現工具。 此秘籍演示了如何使用 Scapy 執行 TCP 和 UDP 的第四層發現。

準備

使用 Scapy 執行第四層發現不需要實驗環境,因為 Internet 上的許多系統都將回復 TCP 和 UDP 請求。但是,強烈建議你只在您自己的實驗環境中執行任何類型的網絡掃描,除非你完全熟悉您受到任何管理機構施加的法律法規。如果你希望在實驗環境中執行此技術,你需要至少有一個響應 TCP/UDP 請求的系統。在提供的示例中,使用 Linux 和 Windows 系統的組合。有關在本地實驗環境中設置系統的更多信息,請參閱第一章中的“安裝 Metasploitable2”和“安裝 Windows Server”秘籍。此外,本節還需要使用文本編輯器(如 VIM 或 Nano)將腳本寫入文件系統。有關編寫腳本的更多信息,請參閱第一章中的“使用文本編輯器(VIM 和 Nano)”秘籍。

操作步驟

為了驗證從活動主機接收到的 RST 響應,我們可以使用 Scapy 向已知的活動主機發送 TCP ACK 數據包。 在提供的示例中,ACK 數據包將發送到 TCP 目標端口 80。此端口通常用于運行 HTTP Web 服務。 演示中使用的主機當前擁有在此端口上運行的 Apache 服務。 為此,我們需要構建我們的請求的每個層級。 要構建的第一層是IP層。 看看下面的命令:

root@KaliLinux:~# scapy Welcome to Scapy (2.2.0) 
>>> i = IP() 
>>> i.display() 
###[ IP ]###
  version= 4
  ihl= None
  tos= 0x0
  len= None
  id= 1
  flags=
  frag= 0
  ttl= 64
  proto= ip
  chksum= None
  src= 127.0.0.1
  dst= 127.0.0.1
  \options\ 
>>> i.dst="172.16.36.135" 
>>> i.display() 
###[ IP ]###
  version= 4
  ihl= None
  tos= 0x0
  len= None
  id= 1
  flags=
  frag= 0
  ttl= 64
  proto= ip
  chksum= None
  src= 172.16.36.180
  dst= 172.16.36.135
  \options\ 

這里,我們將i變量初始化為IP對象,然后重新配置標準配置,將目標地址設置為目標服務器的 IP 地址。 請注意,當為目標地址提供除回送地址之外的任何 IP 地址時,源 IP 地址會自動更新。 我們需要構建的下一層是我們的 TCP 層。 這可以在以下命令中看到:

>>> t = TCP() 
>>> t.display()
###[ TCP ]###
  sport= ftp_data
  dport= http
  seq= 0
  ack= 0
  dataofs= None
  reserved= 0
  flags= S
  window= 8192
  chksum= None
  urgptr= 0
  options= {} 
>>> t.flags='A' 
>>> t.display() 
###[ TCP ]###
  sport= ftp_data
  dport= http
  seq= 0
  ack= 0
  dataofs= None
  reserved= 0
  flags= A
  window= 8192
  chksum= None
  urgptr= 0
  options= {}

這里,我們將t變量初始化為TCP對象。 注意,對象的默認配置已經將目標端口設置為 HTTP 或端口 80。這里,我們只需要將 TCP 標志從S(SYN)更改為A(ACK)。 現在,可以通過使用斜杠分隔每個層級來構建棧,如以下命令中所示:

>>> request = (i/t) 
>>> request.display() 
###[ IP ]###
  version= 4
  ihl= None
  tos= 0x0
  len= None
  id= 1
  flags=
  frag= 0
  ttl= 64
  proto= tcp
  chksum= None
  src= 172.16.36.180
  dst= 172.16.36.135
  \options\ 
###[ TCP ]###
     sport= ftp_data
     dport= http
     seq= 0
     ack= 0
     dataofs= None
     reserved= 0
     flags= A
     window= 8192
     chksum= None
     urgptr= 0
     options= {}

這里,我們將整個請求棧賦給request變量。 現在,可以使用sendrecieve函數跨線路發送請求,然后可以評估響應來確定目標地址的狀態:

>>> response = sr1(request) 
Begin emission: 
.......Finished to send 1 packets. 
....* 
Received 12 packets, got 1 answers, remaining 0 packets 
>>> response.display() 
###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0x0
  len= 40
  id= 0
  flags= DF
  frag= 0L
  ttl= 64
  proto= tcp
  chksum= 0x9974
  src= 172.16.36.135
  dst= 172.16.36.180
  \options\ 
###[ TCP ]###
     sport= http
     dport= ftp_data
     seq= 0
     ack= 0
     dataofs= 5L
     reserved= 0L
     flags= R
     window= 0
     chksum= 0xe21
     urgptr= 0
     options= {} 
###[ Padding ]###
        load= '\x00\x00\x00\x00\x00\x00'

請注意,遠程系統使用設置了 RST 標志的 TCP 數據包進行響應。 這由分配給flags屬性的R值表示。 通過直接調用函數,可以將堆疊請求和發送和接收響應的整個過程壓縮為單個命令:

>>> response = sr1(IP(dst="172.16.36.135")/TCP(flags='A')) 
.Begin emission: 
................
Finished to send 1 packets. 
....* 
Received 22 packets, got 1 answers, remaining 0 packets 
>>> response.display() 
###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0x0
  len= 40
  id= 0
  flags= DF
  frag= 0L
  ttl= 64
  proto= tcp
  chksum= 0x9974
  src= 172.16.36.135
  dst= 172.16.36.180
  \options\ 
###[ TCP ]###
     sport= http
     dport= ftp_data
     seq= 0
     ack= 0
     dataofs= 5L
     reserved= 0L
     flags= R
     window= 0
     chksum= 0xe21
     urgptr= 0
     options= {} 
###[ Padding ]###
        load= '\x00\x00\x00\x00\x00\x00'

現在我們已經確定了與發送到活動主機上的打開端口的 ACK 數據包相關聯的響應,讓我們嘗試向活動系統上的已關閉端口發送類似的請求,并確定響應是否有任何變化:

>>> response = sr1(IP(dst="172.16.36.135")/TCP(dport=1111,flags='A')) 
.Begin emission: 
.........
Finished to send 1 packets. 
....* 
Received 15 packets, got 1 answers, remaining 0 packets 
>>> response.display() 
###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0x0
  len= 40
  id= 0
  flags= DF
  frag= 0L
  ttl= 64
  proto= tcp
  chksum= 0x9974
  src= 172.16.36.135
  dst= 172.16.36.180
  \options\ 
###[ TCP ]###
     sport= 1111
     dport= ftp_data
     seq= 0
     ack= 0
     dataofs= 5L
     reserved= 0L
     flags= R
     window= 0
     chksum= 0xa1a
     urgptr= 0
     options= {} 
###[ Padding ]###
        load= '\x00\x00\x00\x00\x00\x00'

在此請求中,目標 TCP 端口已從默認端口 80 更改為端口 1111(未在其上運行服務的端口)。 請注意,從活動系統上的打開端口和關閉端口返回的響應是相同的。 無論這是否是在掃描端口上主動運行的服務,活動系統都會返回 RST 響應。 另外,應當注意,如果將類似的掃描發送到與活動系統無關的 IP 地址,則不會返回響應。 這可以通過將請求中的目標 IP 地址修改為與實際系統無關的 IP 地址來驗證:

>>> response = sr1(IP(dst="172.16.36.136")/TCP(dport=80,flags='A'),timeo ut=1) 
Begin emission:
......................................................................... ......................................................................... ......
Finished to send 1 packets. 
..................... 
Received 3559 packets, got 0 answers, remaining 1 packets

因此,通過查看,我們發現對于發送到活動主機任何端口的 ACK 數據包,無論端口狀態如何,都將返回 RST 數據包,但如果沒有活動主機與之相關,則不會從 IP 接收到響應。 這是一個好消息,因為它意味著,我們可以通過只與每個系統上的單個端口進行交互,在大量系統上執行發現掃描。 將 Scapy 與 Python 結合使用,我們可以快速循環訪問/ 24網絡范圍中的所有地址,并向每個系統上的僅一個 TCP 端口發送單個 ACK 數據包。 通過評估每個主機返回的響應,我們可以輕易輸出活動 IP 地址列表。

#!/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.py [/24 network address]"   
    print "Example - ./ACK_Ping.py 172.16.36.0"   
    print "Example will perform a TCP ACK ping scan of the 172.16.36.0/24 range"  
    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=80,flags='A'), timeout=1,verbose=0)  
    try:      
        if int(response[TCP].flags) == 4:         
            print "172.16.36."+str(addr)   
    except:      
        pass 

提供的示例腳本相當簡單。 當循環遍歷 IP 地址中的最后一個八位字節的每個可能值時,ACK 封包被發送到 TCP 端口 80,并且評估響應來確定響應中的 TCP 標志的整數轉換是否具有值4 (與單獨 RST 標志相關的值)。 如果數據包具有 RST 標志,則腳本將輸出返回響應的系統的 IP 地址。 如果沒有收到響應,Python 無法測試響應變量的值,因為沒有為其賦任何值。 因此,如果沒有返回響應,將發生異常。 如果返回異常,腳本將會跳過。 生成的輸出是活動目標 IP 地址的列表。 此腳本可以使用句號和斜杠,后跟可執行腳本的名稱執行:

root@KaliLinux:~# ./ACK_Ping.py 
Usage - ./ACK_Ping.py [/24 network address] 
Example - ./ACK_Ping.py 172.16.36.0 
Example will perform a TCP ACK ping scan of the 172.16.36.0/24 range 
root@KaliLinux:~# ./ACK_Ping.py 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135 

類似的發現方法可以用于使用 UDP 協議來執行第四層發現。 為了確定我們是否可以使用 UDP 協議發現主機,我們需要確定如何從任何運行 UDP 的活動主機觸發響應,而不管系統是否有在 UDP 端口上運行服務。 為了嘗試這個,我們將首先在 Scapy 中構建我們的請求棧:

root@KaliLinux:~# scapy Welcome to Scapy (2.2.0) 
>>> i = IP() 
>>> i.dst = "172.16.36.135" 
>>> u = UDP() 
>>> request = (i/u) 
>>> request.display()
###[ IP ]###
  version= 4
  ihl= None
  tos= 0x0
  len= None
  id= 1
  flags=
  frag= 0
  ttl= 64
  proto= udp
  chksum= None
  src= 172.16.36.180
  dst= 172.16.36.135
  \options\ 
###[ UDP ]###
     sport= domain
     dport= domain
     len= None
     chksum= None

注意,UDP對象的默認源和目標端口是域名系統(DNS)。 這是一種常用的服務,可用于將域名解析為 IP 地址。 發送請求是因為它是有助于判斷,IP 地址是否與活動主機相關聯。 發送此請求的示例可以在以下命令中看到:

>>> reply = sr1(request,timeout=1,verbose=1) 
Begin emission: 
Finished to send 1 packets.
Received 7 packets, got 0 answers, remaining 1 packets

盡管與目標 IP 地址相關的主機是活動的,但我們沒有收到響應。 諷刺的是,缺乏響應實際上是由于 DNS 服務正在目標系統上使用。這是因為活動服務通常配置為僅響應包含特定內容的請求。 你可能會自然想到,有時可以嘗試通過探測未運行服務的 UDP 端口來高效識別主機,假設 ICMP 流量未被防火墻阻止。 現在,我們嘗試將同一請求發送到不在使用的不同 UDP 端口:

>>> u.dport = 123 
>>> request = (i/u)
>>> reply = sr1(request,timeout=1,verbose=1) 
Begin emission: Finished to send 1 packets.
Received 5 packets, got 1 answers, remaining 0 packets 
>>> reply.display() 
###[ IP ]###
  version= 4L
  ihl= 5L
  tos= 0xc0
  len= 56
  id= 62614
  flags=
  frag= 0L
  ttl= 64
  proto= icmp
  chksum= 0xe412
  src= 172.16.36.135
  dst= 172.16.36.180
  \options\ 
###[ ICMP ]###
     type= dest-unreach
     code= port-unreachable
     chksum= 0x9e72
     unused= 0 
###[ IP in ICMP ]###
        version= 4L
        ihl= 5L
        tos= 0x0
        len= 28
        id= 1
        flags=
        frag= 0L
        ttl= 64
        proto= udp
        chksum= 0xd974
        src= 172.16.36.180
        dst= 172.16.36.135
        \options\
###[ UDP in ICMP ]###
           sport= domain       
           dport= ntp        
           len= 8          
           chksum= 0x5dd2 

通過將請求目標更改為端口 123,然后重新發送它,我們現在會收到一個響應,表明目標端口不可達。如果檢查此響應的源 IP 地址,你可以看到它是從發送原始請求的主機發送的。此響應隨后表明原始目標 IP 地址處的主機處于活動狀態。不幸的是,在這些情況下并不總是返回響應。這種技術的效率在很大程度上取決于你正在探測的系統及其配置。正因為如此,UDP 發現通常比 TCP 發現更難執行。它從來不會像發送帶有單個標志的 TCP 數據包那么簡單。在服務確實存在的情況下,通常需要服務特定的探測。幸運的是,有各種相當復雜的 UDP 掃描工具,可以使用各種 UDP 請求和服務特定的探針,來確定活動主機是否關聯了任何給定的IP地址。

工作原理

這里提供的示例使用 UDP 和 TCP 發現方式。 我們能夠使用 Scapy 來制作自定義請求,來使用這些協議識別活動主機。 在 TCP 的情況下,我們構造了自定義的 ACK 封包并將其發送到每個目標系統上的任意端口。 在接收到 RST 應答的情況下,系統被識別為活動的。 或者,空的 UDP 請求被發送到任意端口,來嘗試請求 ICMP 端口不可達響應。 響應可用作活動系統的標識。 然后這些技術中的每一個都可以在 Python 腳本中使用,來對多個主機或地址范圍執行發現。

2.12 使用 Nmap 探索第四層

除了集成到 Nmap 工具中的許多其他掃描功能,還有一個選項用于執行第四層發現。 這個具體的秘籍演示了如何使用 Nmap 執行 TCP 和 UDP 協議的第4層發現。

準備

使用 Nmap 執行第四層發現不需要實驗環境,因為 Internet 上的許多系統都將回復 TCP 和 UDP 請求。但是,強烈建議你只在您自己的實驗環境中執行任何類型的網絡掃描,除非你完全熟悉您受到任何管理機構施加的法律法規。如果你希望在實驗環境中執行此技術,你需要至少有一個響應 TCP/UDP 請求的系統。在提供的示例中,使用 Linux 和 Windows 系統的組合。有關在本地實驗環境中設置系統的更多信息,請參閱第一章中的“安裝 Metasploitable2”和“安裝 Windows Server”秘籍。此外,本節還需要使用文本編輯器(如 VIM 或 Nano)將腳本寫入文件系統。有關編寫腳本的更多信息,請參閱第一章中的“使用文本編輯器(VIM 和 Nano)”秘籍。

操作步驟

在 Nmap 中有一些選項用于發現運行 TCP 和 UDP 的主機。 Nmap 的 UDP 發現已配置為,使用必需的唯一載荷來觸發無響應的服務。 為了使用 UDP 執行發現掃描,請使用-PU選項和端口來測試:

root@KaliLinux:~# nmap 172.16.36.135 -PU53 -sn

Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-11 20:11 EST 
Nmap scan report for 172.16.36.135 Host is up (0.00042s latency). 
MAC Address: 00:0C:29:3D:84:32 (VMware) 
Nmap done: 1 IP address (1 host up) scanned in 0.13 seconds 
This UDP discovery scan can also be modified to perform a scan of a sequential range by using dash notation. In the example provided, we will scan the entire 172.16.36.0/24 address range: 
root@KaliLinux:~# nmap 172.16.36.0-255 -PU53 -sn

Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 06:33 EST 
Nmap scan report for 172.16.36.1 
Host is up (0.00020s latency). 
MAC Address: 00:50:56:C0:00:08 (VMware) 
Nmap scan report for 172.16.36.2 
Host is up (0.00018s latency). 
MAC Address: 00:50:56:FF:2A:8E (VMware) 
Nmap scan report for 172.16.36.132 
Host is up (0.00037s latency). 
MAC Address: 00:0C:29:65:FC:D2 (VMware) 
Nmap scan report for 172.16.36.135 
Host is up (0.00041s latency).
MAC Address: 00:0C:29:3D:84:32 (VMware) 
Nmap scan report for 172.16.36.180 
Host is up. 
Nmap scan report for 172.16.36.254 
Host is up (0.00015s latency). 
MAC Address: 00:50:56:EB:E1:8A (VMware) 
Nmap done: 256 IP addresses (6 hosts up) scanned in 3.91 seconds

與之類似,也可以對輸入列表所定義的一系列 IP 地址執行 Nmap UDP ping 請求。 在提供的示例中,我們使用同一目錄中的iplist.txt文件來掃描以下列出的每個主機:

root@KaliLinux:~# nmap -iL iplist.txt -sn -PU53
Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 06:36 EST 
Nmap scan report for 172.16.36.2 
Host is up (0.00015s latency). 
MAC Address: 00:50:56:FF:2A:8E (VMware) 
Nmap scan report for 172.16.36.1 
Host is up (0.00024s latency). 
MAC Address: 00:50:56:C0:00:08 (VMware) 
Nmap scan report for 172.16.36.135 
Host is up (0.00029s latency). 
MAC Address: 00:0C:29:3D:84:32 (VMware) 
Nmap scan report for 172.16.36.132 
Host is up (0.00030s latency). 
MAC Address: 00:0C:29:65:FC:D2 (VMware) 
Nmap scan report for 172.16.36.180 
Host is up. 
Nmap scan report for 172.16.36.254 
Host is up (0.00021s latency). 
MAC Address: 00:50:56:EB:E1:8A (VMware) 
Nmap done: 6 IP addresses (6 hosts up) scanned in 0.31 seconds

盡管來自這些示例中的每一個的輸出表明發現了六個主機,但是這不一定標識六個主機都通過 UDP 發現方法被發現。 除了在 UDP 端口 53 上執行的探測之外,Nmap 還將利用任何其它發現技術,來發現在指定范圍內或在輸入列表內的主機。 雖然-sn選項有效防止了 Nmap 執行 TCP 端口掃描,但它不會完全隔離我們的 UDP ping 請求。 雖然沒有有效的方法來隔離這個任務,你可以通過分析 Wireshark 或 TCPdump 中的流量,來確定通過 UDP 請求發現的主機。 或者,Nmap 也可以用于以 Scapy 的相同方式,來執行 TCP ACK ping。 為了使用 ACK 數據包識別活動主機,請結合你要使用的端口使用-PA選項:

root@KaliLinux:~# nmap 172.16.36.135 -PA80 -sn

Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-11 20:09 EST 
Nmap scan report for 172.16.36.135 
Host is up (0.00057s latency). 
MAC Address: 00:0C:29:3D:84:32 (VMware) 
Nmap done: 1 IP address (1 host up) scanned in 0.21 seconds 

TCP ACK ping 發現方法還可以使用破折號符號在一定范圍的主機上執行,或者可以基于輸入列表在指定的主機地址上執行:

root@KaliLinux:~# nmap 172.16.36.0-255 -PA80 -sn

Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 06:46 EST 
Nmap scan report for 172.16.36.132 
Host is up (0.00033s latency). 
MAC Address: 00:0C:29:65:FC:D2 (VMware) 
Nmap scan report for 172.16.36.135 
Host is up (0.00013s latency). 
MAC Address: 00:0C:29:3D:84:32 (VMware) 
Nmap scan report for 172.16.36.180 
Host is up. 
Nmap done: 256 IP addresses (3 hosts up) scanned in 3.43 seconds 

root@KaliLinux:~# nmap -iL iplist.txt -PA80 -sn

Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 06:47 EST 
Nmap scan report for 172.16.36.135 
Host is up (0.00033s latency). 
MAC Address: 00:0C:29:3D:84:32 (VMware)

Nmap scan report for 172.16.36.132 
Host is up (0.00029s latency). 
MAC Address: 00:0C:29:65:FC:D2 (VMware) 
Nmap scan report for 172.16.36.180 
Host is up. 
Nmap done: 3 IP addresses (3 hosts up) scanned in 0.31 seconds

工作原理

Nmap 用于執行 TCP 發現的技術的基本原理,與 Scapy 用于執行 TCP 發現的技術相同。 Nmap 向目標系統上的任意端口發送一系列 TCP ACK 數據包,并嘗試請求 RST 響應作為活動系統的標識。 然而,Nmap 用于執行 UDP 發現的技術有點不同于 Scapy 的技術。 Nmap 不僅僅依賴于可能不一致或阻塞的 ICMP 主機不可達響應,而且通過向目標端口發送服務特定請求,嘗試請求響應,來執行主機發現。

2.13 使用 hping3 來探索第四層

我們之前討論過,使用hping3來執行第3層 ICMP 發現。 除了此功能,hping3還可以用于執行 UDP 和 TCP 主機發現。 然而,如前所述,hping3被開發用于執行定向請求,并且需要一些腳本來將其用作有效的掃描工具。 這個秘籍演示了如何使用hping3來執行 TCP 和 UDP 協議的第4層發現。

準備

使用hping3執行第四層發現不需要實驗環境,因為 Internet 上的許多系統都將回復 TCP 和 UDP 請求。但是,強烈建議你只在您自己的實驗環境中執行任何類型的網絡掃描,除非你完全熟悉您受到任何管理機構施加的法律法規。如果你希望在實驗環境中執行此技術,你需要至少有一個響應 TCP/UDP 請求的系統。在提供的示例中,使用 Linux 和 Windows 系統的組合。有關在本地實驗環境中設置系統的更多信息,請參閱第一章中的“安裝 Metasploitable2”和“安裝 Windows Server”秘籍。此外,本節還需要使用文本編輯器(如 VIM 或 Nano)將腳本寫入文件系統。有關編寫腳本的更多信息,請參閱第一章中的“使用文本編輯器(VIM 和 Nano)”秘籍。

操作步驟

與 Nmap 不同,hping3通過隔離任務,能夠輕易識別能夠使用 UDP 探針發現的主機。 通過使用--udp選項指定 UDP 模式,可以傳輸 UDP 探針來嘗試觸發活動主機的回復:

root@KaliLinux:~# hping3 --udp 172.16.36.132 
HPING 172.16.36.132 (eth1 172.16.36.132): udp mode set, 28 headers + 0 data bytes 
ICMP Port Unreachable from ip=172.16.36.132 name=UNKNOWN   status=0 port=2792 seq=0 
ICMP Port Unreachable from ip=172.16.36.132 name=UNKNOWN   status=0 port=2793 seq=1 
ICMP Port Unreachable from ip=172.16.36.132 name=UNKNOWN   status=0 port=2794 seq=2 ^F
ICMP Port Unreachable from ip=172.16.36.132 name=UNKNOWN   status=0 port=2795 seq=3 
^C 
--- 172.16.36.132 hping statistic --
4 packets transmitted, 4 packets received, 0% packet loss 
round-trip min/avg/max = 1.8/29.9/113.4 ms 

在提供的演示中,Ctrl + C用于停止進程。在 UDP 模式下使用hping3時,除非在初始命令中定義了特定數量的數據包,否則將無限繼續發現。 為了定義要發送的嘗試次數,應包含-c選項和一個表示所需嘗試次數的整數值:

root@KaliLinux:~# hping3 --udp 172.16.36.132 -c 1 
HPING 172.16.36.132 (eth1 172.16.36.132): udp mode set, 28 headers + 0 data bytes 
ICMP Port Unreachable from ip=172.16.36.132 name=UNKNOWN   status=0 port=2422 seq=0

--- 172.16.36.132 hping statistic --
1 packets transmitted, 1 packets received, 0% packet loss 
round-trip min/avg/max = 104.8/104.8/104.8 ms

雖然hping3默認情況下不支持掃描多個系統,但可以使用 bash 腳本輕易編寫腳本。 為了做到這一點,我們必須首先確定與活動地址相關的輸出,以及與非響應地址相關的輸出之間的區別。 為此,我們應該在未分配主機的 IP 地址上使用相同的命令:

root@KaliLinux:~# hping3 --udp 172.16.36.131 -c 1 
HPING 172.16.36.131 (eth1 172.16.36.131): udp mode set, 28 headers + 0 data bytes
--- 172.16.36.131 hping statistic 
--1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms 

通過識別這些請求中的每一個的相關響應,我們可以確定出我們可以grep的唯一字符串; 此字符串能夠隔離成功的發現嘗試與失敗的發現嘗試。 在以前的請求中,你可能已經注意到,“ICMP 端口不可達”的短語僅在返回響應的情況下顯示。 基于此,我們可以通過對Unreachable進行grep來提取成功的嘗試。 為了確定此方法在腳本中的有效性,我們應該嘗試連接兩個先前的命令,然后將輸出傳遞給我們的grep函數。 假設我們選擇的字符串對于成功的嘗試是唯一的,我們應該只看到與活動主機相關的輸出:

root@KaliLiniux:~# hping3 --udp 172.16.36.132 -c 1; hping3 --udp 172.16.36.131 -c 1 | grep "Unreachable"HPING 172.16.36.132 (eth1 172.16.36.132): udp mode set, 28 headers + 0 data bytes 
ICMP Port Unreachable from ip=172.16.36.132 name=UNKNOWN   status=0 port=2836 seq=0

--- 172.16.36.132 hping statistic --
1 packets transmitted, 1 packets received, 0% packet loss 
round-trip min/avg/max = 115.2/115.2/115.2 ms
--- 172.16.36.131 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms

盡管產生了期望的結果,在這種情況下,grep函數似乎不能有效用于輸出。 由于hping3中的輸出顯示處理,它難以通過管道傳遞到grep函數,并只提取所需的行,我們可以嘗試通過其他方式解決這個問題。 具體來說,我們將嘗試確定輸出是否可以重定向到一個文件,然后我們可以直接從文件中grep。 為此,我們嘗試將先前使用的兩個命令的輸出傳遞給handle.txt文件:

root@KaliLinux:~# hping3 --udp 172.16.36.132 -c 1 >> handle.txt

--- 172.16.36.132 hping statistic --
1 packets transmitted, 1 packets received, 0% packet loss 
round-trip min/avg/max = 28.6/28.6/28.6 ms 
root@KaliLinux:~# hping3 --udp 172.16.36.131 -c 1 >> handle.txt

--- 172.16.36.131 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms 
root@KaliLinux:~# ls Desktop  handle.txt 
root@KaliLinux:~# cat handle.txt 
HPING 172.16.36.132 (eth1 172.16.36.132): udp mode set, 28 headers + 0 data bytes 
ICMP Port Unreachable from ip=172.16.36.132 name=UNKNOWN   status=0 port=2121 seq=0 
HPING 172.16.36.131 (eth1 172.16.36.131): udp mode set, 28 headers + 0 data bytes

雖然這種嘗試并不完全成功,因為輸出沒有完全重定向到文件,我們可以看到通過讀取文件中的輸出,足以創建一個有效的腳本。 具體來說,我們能夠重定向一個唯一的行,該行只與成功的ping嘗試相關聯,并且包含該行中相應的 IP 地址。 要驗證此解決方法是否可行,我們需要嘗試循環訪問/ 24范圍中的每個地址,然后將結果傳遞到handle.txt文件:

root@KaliLinux:~# for addr in $(seq 1 254); do hping3 --udp 172.16.36.$addr -c 1 >> handle.txt; done
--- 172.16.36.1 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms

--- 172.16.36.2 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms
--- 172.16.36.3 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms 

通過這樣做,仍然有大量的輸出(提供的輸出為了方便而被截斷)包含未重定向到文件的輸出。 但是,以下腳本的成功不取決于初始循環的過多輸出,而是取決于從輸出文件中提取必要信息的能力:

root@KaliLinux:~# ls 
Desktop  handle.txt 
root@KaliLinux:~# grep Unreachable handle.txt 
ICMP Port Unreachable from ip=172.16.36.132 HPING 172.16.36.133 (eth1 172.16.36.133): udp mode set, 28 headers + 0 data bytes 
ICMP Port Unreachable from ip=172.16.36.135 HPING 172.16.36.136 (eth1 172.16.36.136): udp mode set, 28 headers + 0 data bytes 

完成掃描循環后,可以使用ls命令在當前目錄中確定輸出文件,然后可以直接從此文件中對Unreachable的唯一字符串進行grep,如下一個命令所示。 在輸出中,我們可以看到,列出了通過 UDP 探測發現的每個活動主機。 此時,剩下的唯一任務是從此輸出中提取 IP 地址,然后將此整個過程重新創建為單個功能腳本:

root@KaliLinux:~# grep Unreachable handle.txt 
ICMP Port Unreachable from ip=172.16.36.132 
HPING 172.16.36.133 (eth1 172.16.36.133): udp mode set, 28 headers + 0 data bytes 
ICMP Port Unreachable from ip=172.16.36.135 
HPING 172.16.36.136 (eth1 172.16.36.136): udp mode set, 28 headers + 0 data bytes 
root@KaliLinux:~# grep Unreachable handle.txt | cut -d " " -f 5 ip=172.16.36.132 ip=172.16.36.135 
root@KaliLinux:~# grep Unreachable handle.txt | cut -d " " -f 5 | cut -d "=" -f 2 172.16.36.132 172.16.36.135


通過將輸出使用管道連接到一系列cut函數,我們可以從輸出中提取 IP 地址。 現在我們已經成功地確定了一種方法,來掃描多個主機并輕易識別結果,我們應該將其集成到一個腳本中。 將所有這些操作組合在一起的功能腳本的示例如下:

#!/bin/bash
if [ "$#" -ne 1 ]; then 
    echo "Usage - ./udp_sweep.sh [/24 network address]" 
    echo "Example - ./udp_sweep.sh 172.16.36.0" 
    echo "Example will perform a UDP ping sweep of the 172.16.36.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 -c 1 >> handle.txt; 
done

grep Unreachable handle.txt | cut -d " " -f 5 | cut -d "=" -f 2 >> output.txt 
rm handle.txt 

在提供的 bash 腳本中,第一行定義了 bash 解釋器的位置。 接下來的代碼塊執行測試來確定是否提供了預期的一個參數。 這通過評估提供的參數的數量是否不等于 1 來確定。如果未提供預期參數,則輸出腳本的用法,并且退出腳本。 用法輸出表明,腳本需要接受/ 24網絡地址作為參數。 下一行代碼從提供的網絡地址中提取網絡前綴。 例如,如果提供的網絡地址是192.168.11.0,則前綴變量將被賦值為192.168.11。 然后對/ 24范圍內的每個地址執行hping3操作,并將每個任務的結果輸出放入handle.txt文件中。

root@KaliLinux:~# ./udp_sweep.sh 
Usage - ./udp_sweep.sh [/24 network address] 
Example - ./udp_sweep.sh 172.16.36.0 
Example will perform a UDP ping sweep of the 172.16.36.0/24 network and output to an output.txt file
root@KaliLinux:~# ./udp_sweep.sh 172.16.36.0
--- 172.16.36.1 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms
--- 172.16.36.2 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms
--- 172.16.36.3 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms
                *** {TRUNCATED} ***
root@KaliLinux:~# ls output.txt 
output.txt 
root@KaliLinux:~# cat output.txt 
172.16.36.132 
172.16.36.135 
172.16.36.253 

當腳本運行時,你仍然會看到在初始循環任務時看到的大量輸出。 幸運的是,你發現的主機列表不會在此輸出中消失,因為它每次都會寫入你的輸出文件。

你還可以使用hping3執行 TCP 發現。 TCP 模式實際上是hping3使用的默認發現模式,并且可以通過將要掃描的 IP 地址傳遞到hping3來使用此模式:

root@KaliLinux:~# hping3 172.16.36.132 
HPING 172.16.36.132 (eth1 172.16.36.132): NO FLAGS are set, 40 headers + 0 data bytes 
len=46 ip=172.16.36.132 ttl=64 DF id=0 sport=0 flags=RA seq=0 win=0 rtt=3.7 ms 
len=46 ip=172.16.36.132 ttl=64 DF id=0 sport=0 flags=RA seq=1 win=0 rtt=0.7 ms 
len=46 ip=172.16.36.132 ttl=64 DF id=0 sport=0 flags=RA seq=2 win=0 rtt=2.6 ms 
^C 
--- 172.16.36.132 hping statistic --
3 packets transmitted, 3 packets received, 0% packet loss 
round-trip min/avg/max = 0.7/2.3/3.7 ms

我們之前創建一個bash腳本循環訪問/ 24網絡并使用hping3執行 UDP 發現,與之相似,我們可以為 TCP 發現創建一個類似的腳本。 首先,必須確定唯一短語,它存在于活動主機的相關輸出中,但不在非響應主機的相關輸出中。 為此,我們必須評估每個響應:

root@KaliLinux:~# hping3 172.16.36.132 -c 1 
HPING 172.16.36.132 (eth1 172.16.36.132): NO FLAGS are set, 40 headers + 0 data bytes 
len=46 ip=172.16.36.132 ttl=64 DF id=0 sport=0 flags=RA seq=0 win=0 rtt=3.4 ms
--- 172.16.36.132 hping statistic --
1 packets transmitted, 1 packets received, 0% packet loss 
round-trip min/avg/max = 3.4/3.4/3.4 ms 
root@KaliLinux:~# hping3 172.16.36.131 -c 1 
HPING 172.16.36.131 (eth1 172.16.36.131): NO FLAGS are set, 40 headers + 0 data bytes
--- 172.16.36.131 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms 

在這種情況下,長度值僅存在于活動主機的相關輸出中。 再一次,我們可以開發一個腳本,將輸出重定向到臨時handle文件,然后grep此文件的輸出來確定活動主機:

#!/bin/bash
if [ "$#" -ne 1 ]; then 
    echo "Usage - ./tcp_sweep.sh [/24 network address]" 
    echo "Example - ./tcp_sweep.sh 172.16.36.0" 
    echo "Example will perform a TCP ping sweep of the 172.16.36.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 >> handle.txt; 
done

grep len handle.txt | cut -d " " -f 2 | cut -d "=" -f 2 >> output.txt
 rm handle.txt

此腳本的執行方式類似于 UDP 發現腳本。 唯一的區別是在循環序列中執行的命令,grep值和提取 IP 地址的過程。 執行后,此腳本將生成一個output.txt文件,其中將包含使用 TCP 發現方式來發現的主機的相關 IP 地址列表。

root@KaliLinux:~# ./tcp_sweep.sh 
Usage - ./tcp_sweep.sh [/24 network address] 
Example - ./tcp_sweep.sh 172.16.36.0 
Example will perform a TCP ping sweep of the 172.16.36.0/24 network and output to an output.txt file 
root@KaliLinux:~# ./tcp_sweep.sh 172.16.36.0
--- 172.16.36.1 hping statistic --
1 packets transmitted, 1 packets received, 0% packet loss 
round-trip min/avg/max = 0.4/0.4/0.4 ms
--- 172.16.36.2 hping statistic --
1 packets transmitted, 1 packets received, 0% packet loss 
round-trip min/avg/max = 0.6/0.6/0.6 ms
--- 172.16.36.3 hping statistic --
1 packets transmitted, 0 packets received, 100% packet loss 
round-trip min/avg/max = 0.0/0.0/0.0 ms
                    *** {TRUNCATED} *** 

你可以使用ls命令確認輸出文件是否已寫入執行目錄,并使用cat命令讀取其內容。 這可以在以下示例中看到:

root@KaliLinux:~# ls output.txt 
output.txt 
root@KaliLinux:~# cat output.txt 
172.16.36.1 
172.16.36.2 
172.16.36.132 
172.16.36.135 
172.16.36.253

工作原理

在提供的示例中,hping3使用 ICMP 主機不可達響應,來標識具有 UDP 請求的活動主機,并使用空標志掃描來標識具有 TCP 請求的活動主機。 對于 UDP 發現,一系列空 UDP 請求被發送到任意目標端口,來試圖請求響應。 對于 TCP 發現,一系列 TCP 請求被發送到目的端口 0,并沒有激活標志位。 所提供的示例請求激活了 ACK + RST 標志的響應。 這些任務中的每一個都傳遞給了 bash 中的循環,來在多個主機或一系列地址上執行掃描。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容