第三章 端口掃描(二)
作者:Justin Hutchens
譯者:飛龍
協(xié)議:CC BY-NC-SA 4.0
3.6 Scapy 隱秘掃描
執(zhí)行 TCP 端口掃描的一種方式就是執(zhí)行一部分。目標端口上的 TCP 三次握手用于識別端口是否接受連接。這一類型的掃描指代隱秘掃描, SYN 掃描,或者半開放掃描。這個秘籍演示了如何使用 Scapy 執(zhí)行 TCP 隱秘掃描。
準備
為了使用 Scapy 執(zhí)行 TCP 隱秘 掃描,你需要一個運行 TCP 網(wǎng)絡服務的遠程服務器。這個例子中我們使用 Metasploitable2 實例來執(zhí)行任務。配置 Metasploitable2 的更多信息請參考第一章中的“安裝 Metasploitable2”秘籍。
此外,這一節(jié)也需要編寫腳本的更多信息,請參考第一章中的“使用文本編輯器*VIM 和 Nano)。
操作步驟
為了展示如何執(zhí)行 SYN 掃描,我們需要使用 Scapy 構造 TCP SYN 請求,并識別和開放端口、關閉端口以及無響應系統(tǒng)有關的響應。為了向給定端口發(fā)送 TCP SYN 請求,我們首先需要構建請求的各個層面。我們需要構建的第一層就是 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\
為了構建請求的 IP 層,我們需要將IP對象賦給變量i。通過調(diào)用display函數(shù),我們可以確定對象的屬性配置。通常,發(fā)送和接受地址都設為回送地址,127.0.0.1。這些值可以通過修改目標地址來修改,也就是設置i.dst為想要掃描的地址的字符串值。通過再次調(diào)用dislay函數(shù),我們看到不僅僅更新的目標地址,也自動更新了和默認接口相關的源 IP 地址。現(xiàn)在我們構建了請求的 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= {}
為了構建請求的 TCP 層,我們使用和 IP 層相同的技巧。在這個立即中,TCP對象賦給了t變量。像之前提到的那樣,默認的配置可以通過調(diào)用display函數(shù)來確定。這里我們可以看到目標端口的默認值為 HTTP 端口 80。對于我們的首次掃描,我們將 TCP 設置保留默認?,F(xiàn)在我們創(chuàng)建了 TCP 和 IP 層,我們需要將它們疊放來構造請求。
>>> 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= S
window= 8192
chksum= None
urgptr= 0
options= {}
我們可以通過以斜杠分離變量來疊放 IP 和 TCP 層。這些層面之后賦給了新的變量,它代表整個請求。我們之后可以調(diào)用dispaly函數(shù)來查看請求的配置。一旦構建了請求,可以將其傳遞給sr1函數(shù)來分析響應:
>>> response = sr1(request)
...Begin emission:
........Finished to send 1 packets.
....*
Received 16 packets, got 1 answers, remaining 0 packets
>>> response.display()
###[ IP ]###
version= 4L
ihl= 5L
tos= 0x0
len= 44
id= 0
flags= DF
frag= 0L
ttl= 64
proto= tcp
chksum= 0x9970
src= 172.16.36.135
dst= 172.16.36.180
\options\
###[ TCP ]###
sport= http
dport= ftp_data
seq= 2848210323L
ack= 1
dataofs= 6L
reserved= 0L
flags= SA
window= 5840
chksum= 0xf82d
urgptr= 0
options= [('MSS', 1460)]
###[ Padding ]###
load= '\x00\x00'
相同的請求可以不通過構建和堆疊每一層來執(zhí)行。反之,我們使用單獨的一條命令,通過直接調(diào)用函數(shù)并傳遞合適的參數(shù):
>>> sr1(IP(dst="172.16.36.135")/TCP(dport=80))
.Begin emission: .............Finished to send 1 packets.
....*
Received 19 packets, got 1 answers, remaining 0 packets
<IP version=4L ihl=5L tos=0x0 len=44 id=0 flags=DF frag=0L ttl=64 proto=tcp chksum=0x9970 src=172.16.36.135 dst=172.16.36.180 options=[] |<TCP sport=http dport=ftp_data seq=542529227 ack=1 dataofs=6L reserved=0L flags=SA window=5840 chksum=0x6864 urgptr=0 options=[('MSS', 1460)] |<Padding load='\x00\x00' |>>>
要注意當 SYN 封包發(fā)往目標 Web 服務器的 TCP 端口 80,并且該端口上運行了 HTTP 服務時,響應中會帶有 TCP 標識 SA 的值,這表明 SYN 和 ACK 標識都被激活。這個響應表明特定的目標端口是開放的,并接受連接。如果相同類型的封包發(fā)往不接受連接的端口,會收到不同的請求。
>>> response = sr1(IP(dst="172.16.36.135")/TCP(dport=4444))
..Begin emission:
.Finished to send 1 packets.
...* Received 7 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= 4444
dport= ftp_data
seq= 0
ack= 1
dataofs= 5L
reserved= 0L
flags= RA
window= 0
chksum= 0xfd03
urgptr= 0
options= {}
###[ Padding ]###
load= '\x00\x00\x00\x00\x00\x00'
當 SYN 請求發(fā)送給關閉的端口時,返回的響應中帶有 TCP 標識 RA,這表明 RST 和 ACK 標識為都被激活。ACK 為僅僅用于承認請求被接受,RST 為用于斷開連接,因為端口不接受連接。作為替代,如果 SYN 封包發(fā)往崩潰的系統(tǒng),或者防火墻過濾了這個請求,就可能接受不到任何信息。由于這個原因,在sr1函數(shù)在腳本中使用時,應該始終使用timeout選項,來確保腳本不會在無響應的主機上掛起。
>>> response = sr1(IP(dst="172.16.36.136")/TCP(dport=4444),timeout=1,verb ose=1)
Begin emission:
Finished to send 1 packets
Received 15 packets, got 0 answers, remaining 1 packets
如果函數(shù)對無響應的主機使用時,timeout值沒有指定,函數(shù)會無限繼續(xù)下去。這個演示中,timout值為 1秒,用于使這個函數(shù)更加完備,響應的值可以用于判斷是否收到了響應:
root@KaliLinux:~#
python Python 2.7.3 (default, Jan 2 2013, 16:53:07)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from scapy.all import *
>>> response = sr1(IP(dst="172.16.36.136")/TCP(dport=4444),timeout=1,verb ose=1)
Begin emission:
WARNING: Mac address to reach destination not found. Using broadcast. Finished to send 1 packets.
Received 15 packets, got 0 answers, remaining 1 packets
>>> if response == None:
... print "No Response!!!"
...
No Response!!!
Python 的使用使其更易于測試變量來識別sr1函數(shù)是否對其復制。這可以用作初步檢驗,來判斷是否接收到了任何響應。對于接收到的響應,可以執(zhí)行一系列后續(xù)檢查來判斷響應表明端口開放還是關閉。這些東西可以輕易使用 Python 腳本來完成,像這樣:
#!/usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
import sys
if len(sys.argv) != 4:
print "Usage - ./syn_scan.py [Target-IP] [First Port] [Last Port]"
print "Example - ./syn_scan.py 10.0.0.5 1 100"
print "Example will TCP SYN scan ports 1 through 100 on 10.0.0.5"
sys.exit()
ip = sys.argv[1]
start = int(sys.argv[2])
end = int(sys.argv[3])
for port in range(start,end):
ans = sr1(IP(dst=ip)/TCP(dport=port),timeout=1,verbose=0)
if ans == None:
pass
else:
if int(ans[TCP].flags) == 18:
print port
else:
pass
在這個 Python 腳本中,用于被提示來輸入 IP 地址,腳本之后會對定義好的端口序列執(zhí)行 SYN 掃描。腳本之后會得到每個連接的響應,并嘗試判斷響應的 SYN 和 ACK 標識是否激活。如果響應中出現(xiàn)并僅僅出現(xiàn)了這些標識,那么會輸出相應的端口號碼。
root@KaliLinux:~# chmod 777 syn_scan.py
root@KaliLinux:~# ./syn_scan.py
Usage - ./syn_scan.py [Target-IP] [First Port] [Last Port]
Example - ./syn_scan.py 10.0.0.5 1 100
Example will TCP SYN scan ports 1 through 100 on 10.0.0.5
root@KaliLinux:~# ./syn_scan.py 172.16.36.135 1 100
21
22
23
25
53
80
運行這個腳本之后,輸出會顯示所提供的 IP 地址的系統(tǒng)上,前 100 個端口中的開放端口。
工作原理
這一類型的掃描由發(fā)送初始 SYN 封包給遠程系統(tǒng)的目標 TCP 端口,并且通過返回的響應類型來判斷端口狀態(tài)來完成。如果遠程系統(tǒng)返回了 SYN+ACK 響應,那么它正在準備建立連接,我們可以假設這個端口開放。如果服務返回了 RST 封包,這就表明端口關閉并且不接收連接。此外,如果沒有返回響應,掃描系統(tǒng)和遠程系統(tǒng)之間可能存在防火墻,它丟棄了請求。這也可能表明主機崩潰或者目標 IP 上沒有關聯(lián)任何系統(tǒng)。
3.7 Nmap 隱秘掃描
Nmap 擁有可以執(zhí)行遠程系統(tǒng) SYN 掃描的掃描模式。這個秘籍展示了如何使用 Namp 執(zhí)行 TCP 隱秘掃描。
準備
為了使用 Nmap 執(zhí)行 TCP 隱秘掃描,你需要一個運行 TCP 網(wǎng)絡服務的遠程服務器。這個例子中我們使用 Metasploitable2 實例來執(zhí)行任務。配置 Metasploitable2 的更多信息請參考第一章中的“安裝 Metasploitable2”秘籍。
操作步驟
就像多數(shù)掃描需求那樣,Nmap 擁有簡化 TCP 隱秘掃描執(zhí)行過程的選項。為了使用 Nmap 執(zhí)行 TCP 隱秘掃描,應使用-sS選項,并附帶被掃描主機的 IP 地址。
root@KaliLinux:~# nmap -sS 172.16.36.135 -p 80
Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 21:47 EST
Nmap scan report for 172.16.36.135
Host is up (0.00043s latency).
PORT STATE SERVICE
80/tcp open http
MAC Address: 00:0C:29:3D:84:32 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 13.05 seconds
在提供的例子中,特定的 IP 地址的 TCP 80 端口上執(zhí)行了 TCP 隱秘掃描。和 Scapy 中的技巧相似,Nmap 監(jiān)聽響應并通過分析響應中所激活的 TCP 標識來識別開放端口。我們也可以使用 Namp 執(zhí)行多個特定端口的掃描,通過傳遞逗號分隔的端口號列表。
root@KaliLinux:~# nmap -sS 172.16.36.135 -p 21,80,443
Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 21:48 EST
Nmap scan report for 172.16.36.135
Host is up (0.00035s latency).
PORT STATE SERVICE
21/tcp open ftp
80/tcp open http
443/tcp closed https
MAC Address: 00:0C:29:3D:84:32 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 13.05 seconds
在這個例子中,目標 IP 地址的端口 21、80 和 443 上執(zhí)行了 SYN 掃描。我們也可以使用 Namp 來掃描主機序列,通過標明要掃描的第一個和最后一個端口號,以破折號分隔:
root@KaliLinux:~# nmap -sS 172.16.36.135 -p 20-25
Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 21:48 EST
Nmap scan report for 172.16.36.135
Host is up (0.00035s latency).
PORT STATE SERVICE
20/tcp closed ftp-data
21/tcp open ftp
22/tcp open ssh
23/tcp open telnet
24/tcp closed priv-mail
25/tcp open smtp
MAC Address: 00:0C:29:3D:84:32 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 13.05 seconds
在所提供的例子中,SYN 掃描在 TCP 20 到 25 端口上執(zhí)行。除了擁有指定被掃描端口的能力之外。Nmap 同時擁有配置好的 1000 和常用端口的列表。我們可以執(zhí)行這些端口上的掃描,通過不帶任何端口指定信息來運行 Nmap:
root@KaliLinux:~# nmap -sS 172.16.36.135
Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 21:46 EST
Nmap scan report for 172.16.36.135
Host is up (0.00038s latency). N
ot shown: 977 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
23/tcp open telnet
25/tcp open smtp
53/tcp open domain
80/tcp open http
111/tcp open rpcbind
139/tcp open netbios-ssn
445/tcp open microsoft-ds
512/tcp open exec
513/tcp open login
514/tcp open shell
1099/tcp open rmiregistry
1524/tcp open ingreslock
2049/tcp open nfs
2121/tcp open ccproxy-ftp
3306/tcp open mysql
5432/tcp open postgresql
5900/tcp open vnc
6000/tcp open X11
6667/tcp open irc
8009/tcp open ajp13
8180/tcp open unknown
MAC Address: 00:0C:29:3D:84:32 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 13.17 seconds
在上面的例子中,掃描了 Nmap 定義的 1000 個常用端口,用于識別 Metasploitable2 系統(tǒng)上的大量開放端口。雖然這個技巧在是被多數(shù)設備上很高效,但是也可能無法識別模糊的服務或者不常見的端口組合。如果掃描在所有可能的 TCP 端口上執(zhí)行,所有可能的端口地址值都需要被掃描。定義了源端口和目標端口地址的 TCP 頭部部分是 16 位長。并且,每一位可以為 1 或者 0。因此,共有2 ** 16或者 65536 個可能的 TCP 端口地址。對于要掃描的全部可能的地址空間,需要提供 0 到 65535 的端口范圍,像這樣:
root@KaliLinux:~# nmap -sS 172.16.36.135 -p 0-65535
Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 21:51 EST
Nmap scan report for 172.16.36.135
Host is up (0.00033s latency).
Not shown: 65506 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
23/tcp open telnet
25/tcp open smtp
53/tcp open domain
80/tcp open http
111/tcp open rpcbind
139/tcp open netbios-ssn
445/tcp open microsoft-ds
512/tcp open exec
513/tcp open login
514/tcp open shell
1099/tcp open rmiregistry
1524/tcp open ingreslock
2049/tcp open nfs
2121/tcp open ccproxy-ftp
3306/tcp open mysql
3632/tcp open distccd
5432/tcp open postgresql
5900/tcp open vnc
6000/tcp open X11
6667/tcp open irc
6697/tcp open unknown
8009/tcp open ajp13
8180/tcp open unknown
8787/tcp open unknown
34789/tcp open unknown
50333/tcp open unknown
56375/tcp open unknown
57385/tcp open unknown
MAC Address: 00:0C:29:3D:84:32 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 16.78 seconds
這個例子中,Metasploitable2 系統(tǒng)上所有可能的 65536 和 TCP 地址都掃描了一遍。要注意該掃描中識別的多數(shù)服務都在標準的 Nmap 1000 掃描中識別過了。這就表明在嘗試識別目標的所有可能的攻擊面的時候,完整掃描是個最佳實踐。Nmap 可以使用破折號記法,掃描主機列表上的 TCP 端口:
root@KaliLinux:~# nmap 172.16.36.0-255 -sS -p 80
Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 21:56 EST
Nmap scan report for 172.16.36.1 Host is up (0.00023s latency).
PORT STATE SERVICE
80/tcp closed http
MAC Address: 00:50:56:C0:00:08 (VMware)
Nmap scan report for 172.16.36.2 Host is up (0.00018s latency).
PORT STATE SERVICE
80/tcp closed http
MAC Address: 00:50:56:FF:2A:8E (VMware)
Nmap scan report for 172.16.36.132 Host is up (0.00047s latency).
PORT STATE SERVICE
80/tcp closed http
MAC Address: 00:0C:29:65:FC:D2 (VMware)
Nmap scan report for 172.16.36.135
Host is up (0.00016s latency).
PORT STATE SERVICE
80/tcp open http
MAC Address: 00:0C:29:3D:84:32 (VMware)
Nmap scan report for 172.16.36.180
Host is up (0.0029s latency).
PORT STATE SERVICE
80/tcp open http
Nmap done: 256 IP addresses (5 hosts up) scanned in 42.85 seconds
這個例子中,TCP 80 端口的 SYN 掃描在指定地址范圍內(nèi)的所有主機上執(zhí)行。雖然這個特定的掃描僅僅執(zhí)行在單個端口上,Nmap 也能夠同時掃描多個系統(tǒng)上的多個端口和端口范圍。此外,Nmap 也能夠進行配置,基于 IP 地址的輸入列表來掃描主機。這可以通過-iL選項并指定文件名,如果文件存放于執(zhí)行目錄中,或者文件路徑來完成。Nmap 之后會遍歷輸入列表中的每個地址,并對地址執(zhí)行特定的掃描。
root@KaliLinux:~# cat iplist.txt
172.16.36.1
172.16.36.2
172.16.36.132
172.16.36.135
root@KaliLinux:~# nmap -sS -iL iplist.txt -p 80
Starting Nmap 6.25 ( http://nmap.org ) at 2013-12-17 21:59 EST
Nmap scan report for 172.16.36.1
Host is up (0.00016s latency).
PORT STATE SERVICE
80/tcp closed http
MAC Address: 00:50:56:C0:00:08 (VMware)
Nmap scan report for 172.16.36.2
Host is up (0.00047s latency).
PORT STATE SERVICE
80/tcp closed http
MAC Address: 00:50:56:FF:2A:8E (VMware)
Nmap scan report for 172.16.36.132
Host is up (0.00034s latency).
PORT STATE SERVICE
80/tcp closed http
MAC Address: 00:0C:29:65:FC:D2 (VMware)
Nmap scan report for 172.16.36.135
Host is up (0.00016s latency).
PORT STATE SERVICE
80/tcp open http
MAC Address: 00:0C:29:3D:84:32 (VMware)
Nmap done: 4 IP addresses (4 hosts up) scanned in 13.05 seconds
工作原理
Nmap SYN 掃描背后的底層機制已經(jīng)討論過了。但是,Nmap 擁有多線程功能,是用于執(zhí)行這類掃描的快速高效的方式。
3.8 Metasploit 隱秘掃描
除了其它已經(jīng)討論過的工具之外,Metasploit 擁有用于 SYN 掃描的輔助模塊。這個秘籍展示了如何使用 Metasploit 來執(zhí)行 TCP 隱秘掃描。
準備
為了使用 Metasploit 執(zhí)行 TCP 隱秘掃描,你需要一個運行 TCP 網(wǎng)絡服務的遠程服務器。這個例子中我們使用 Metasploitable2 實例來執(zhí)行任務。配置 Metasploitable2 的更多信息請參考第一章中的“安裝 Metasploitable2”秘籍。
操作步驟
Metasploit 擁有可以對特定 TCP 端口執(zhí)行 SYN 掃描的輔助模塊。為了在 Kali 中啟動 Metasploit,我們在終端中執(zhí)行msfconsole命令。
root@KaliLinux:~# msfconsole
IIIIII dTb.dTb _.---._
II 4' v 'B .'"".'/|\`.""'.
II 6. .P : .' / | \ `. :
II 'T;. .;P' '.' / | \ `.'
II 'T; ;P' `. / | \ .'
IIIIII 'YvP' `-.__|__.-'
I love shells --egypt
Using notepad to track pentests? Have Metasploit Pro report on hosts, services, sessions and evidence -- type 'go_pro' to launch it now.
=[ metasploit v4.6.0-dev [core:4.6 api:1.0]
+ -- --=[ 1053 exploits - 590 auxiliary - 174 post
+ -- --=[ 275 payloads - 28 encoders - 8 nops
msf > use auxiliary/scanner/portscan/syn
msf auxiliary(syn) > show options
Module options (auxiliary/scanner/portscan/syn):
Name Current Setting Required Description
---- --------------- -------- ----------
BATCHSIZE 256 yes The number of hosts to scan per set
INTERFACE no The name of the interface
PORTS 1-10000 yes Ports to scan (e.g. 2225,80,110-900)
RHOSTS yes The target address range or CIDR identifier
SNAPLEN 65535 yes The number of bytes to capture
THREADS 1 yes The number of concurrent threads
TIMEOUT 500 yes The reply read timeout in milliseconds
為了在 Metasploit 中執(zhí)行 SYN 掃描,以輔助模塊的相對路徑調(diào)用use命令。一旦模塊被選中,可以執(zhí)行show options命令來確認或修改掃描配置。這個命令會展示四列的表格,包括name、current settings、required和description。name列標出了每個可配置變量的名稱。current settings列列出了任何給定變量的現(xiàn)有配置。required列標出對于任何給定變量,值是否是必須的。description列描述了每個變量的功能。任何給定變量的值可以使用set命令,并且將新的值作為參數(shù)來修改。
msf auxiliary(syn) > set RHOSTS 172.16.36.135
RHOSTS => 172.16.36.135
msf auxiliary(syn) > set THREADS 20
THREADS => 20
msf auxiliary(syn) > set PORTS 80
PORTS => 80
msf auxiliary(syn) > show options
Module options (auxiliary/scanner/portscan/syn):
Name Current Setting Required Description
---- --------------- -------- ----------
BATCHSIZE 256 yes The number of hosts to scan per set
INTERFACE no The name of the interface
PORTS 80 yes Ports to scan (e.g. 2225,80,110-900)
RHOSTS 172.16.36.135 yes The target address range or CIDR identifier
SNAPLEN 65535 yes The number of bytes to capture
THREADS 20 yes The number of concurrent threads
TIMEOUT 500 yes The reply read timeout in milliseconds
在上面的例子中,RHOSTS值修改為我們打算掃描的遠程系統(tǒng)的 IP 地址。地外,線程數(shù)量修改為 20。THREADS的值定義了在后臺執(zhí)行的當前任務數(shù)量。確定線程數(shù)量涉及到尋找一個平衡,既能提升任務速度,又不會過度消耗系統(tǒng)資源。對于多數(shù)系統(tǒng),20 個線程可以足夠快,并且相當合理。PORTS值設為 TCP 端口 80(HTTP)。修改了必要的變量之后,可以再次使用show options命令來驗證。一旦所需配置驗證完畢,就可以執(zhí)行掃描了。
msf auxiliary(syn) > run
[*] TCP OPEN 172.16.36.135:80 [*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed The run command is used in Metasploit to execute the selected auxiliary module. In the example provided, the run command executed a TCP SYN scan against port 80 of the specified IP address. We can also run this TCP SYN scan module against a sequential series of TCP ports by supplying the first and last values, separated by a dash notation:
msf auxiliary(syn) > set PORTS 0-100
PORTS => 0-100
msf auxiliary(syn) > show options
Module options (auxiliary/scanner/portscan/syn):
Name Current Setting Required Description
---- --------------- -------- ----------
BATCHSIZE 256 yes The number of hosts to scan per set
INTERFACE no The name of the interface
PORTS 0-100 yes Ports to scan (e.g. 2225,80,110-900)
RHOSTS 172.16.36.135 yes The target address range or CIDR identifier
SNAPLEN 65535 yes The number of bytes to capture
THREADS 20 yes The number of concurrent threads
TIMEOUT 500 yes The reply read timeout in milliseconds
msf auxiliary(syn) > run
[*] TCP OPEN 172.16.36.135:21
[*] TCP OPEN 172.16.36.135:22
[*] TCP OPEN 172.16.36.135:23
[*] TCP OPEN 172.16.36.135:25
[*] TCP OPEN 172.16.36.135:53
[*] TCP OPEN 172.16.36.135:80
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
上面的例子中,所指定的遠程主機的錢 100 個 TCP 端口上執(zhí)行了 TCP SYN 掃描。雖然這個掃描識別了目標系統(tǒng)的多個設備,我們不能確認所有設備都識別出來,除非所有可能的端口地址都掃描到。定義來源和目標端口地址的TCP 頭部部分是 16 位長。并且,每一位可以為 1 或者 0。因此,共有2 ** 16或 65536 個可能的 TCP 端口地址。對于要掃描的整個地址空間,需要提供 0 到 65535 的 端口范圍,像這樣:
msf auxiliary(syn) > set PORTS 0-65535
PORTS => 0-65535
msf auxiliary(syn) > show options
Module options (auxiliary/scanner/portscan/syn):
Name Current Setting Required Description
---- --------------- -------- ----------
BATCHSIZE 256 yes The number of hosts to scan per set
INTERFACE no The name of the interface
PORTS 0-65535 yes Ports to scan (e.g. 2225,80,110-900)
RHOSTS 172.16.36.135 yes The target address range or CIDR identifier
SNAPLEN 65535 yes The number of bytes to capture
THREADS 20 yes The number of concurrent threads
TIMEOUT 500 yes The reply read timeout in milliseconds
msf auxiliary(syn) > run
[*] TCP OPEN 172.16.36.135:21
[*] TCP OPEN 172.16.36.135:22
[*] TCP OPEN 172.16.36.135:23
[*] TCP OPEN 172.16.36.135:25
[*] TCP OPEN 172.16.36.135:53
[*] TCP OPEN 172.16.36.135:80
[*] TCP OPEN 172.16.36.135:111
[*] TCP OPEN 172.16.36.135:139
[*] TCP OPEN 172.16.36.135:445
[*] TCP OPEN 172.16.36.135:512
[*] TCP OPEN 172.16.36.135:513
[*] TCP OPEN 172.16.36.135:514
[*] TCP OPEN 172.16.36.135:1099
[*] TCP OPEN 172.16.36.135:1524
[*] TCP OPEN 172.16.36.135:2049
[*] TCP OPEN 172.16.36.135:2121
[*] TCP OPEN 172.16.36.135:3306
[*] TCP OPEN 172.16.36.135:3632
[*] TCP OPEN 172.16.36.135:5432
[*] TCP OPEN 172.16.36.135:5900
[*] TCP OPEN 172.16.36.135:6000
[*] TCP OPEN 172.16.36.135:6667
[*] TCP OPEN 172.16.36.135:6697
[*] TCP OPEN 172.16.36.135:8009
[*] TCP OPEN 172.16.36.135:8180
[*] TCP OPEN 172.16.36.135:8787
[*] TCP OPEN 172.16.36.135:34789
[*] TCP OPEN 172.16.36.135:50333
[*] TCP OPEN 172.16.36.135:56375
[*] TCP OPEN 172.16.36.135:57385
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
在這個李忠,遠程系統(tǒng)的所有開放端口都由掃描所有可能的 TCP 端口地址來識別。我們也可以修改掃描配置使用破折號記法來掃描地址序列。
msf auxiliary(syn) > set RHOSTS 172.16.36.0-255
RHOSTS => 172.16.36.0-255
msf auxiliary(syn) > show options
Module options (auxiliary/scanner/portscan/syn):
Name Current Setting Required Description
---- --------------- -------- ----------
BATCHSIZE 256 yes The number of hosts to scan per set
INTERFACE no The name of the interface
PORTS 80 yes Ports to scan (e.g. 2225,80,110-900)
RHOSTS 172.16.36.0-255 yes The target address range or CIDR identifier
SNAPLEN 65535 yes The number of bytes to capture
THREADS 20 yes The number of concurrent threads
TIMEOUT 500 yes The reply read timeout in milliseconds
msf auxiliary(syn) > run
[*] TCP OPEN 172.16.36.135:80
[*] Scanned 256 of 256 hosts (100% complete)
[*] Auxiliary module execution completed
這個例子中,TCP SYN 掃描執(zhí)行在由RHOST變量指定的所有主機地址的 80 端口上。與之相似,RHOSTS可以使用 CIDR 記法定義網(wǎng)絡范圍。
msf auxiliary(syn) > set RHOSTS 172.16.36.0/24
RHOSTS => 172.16.36.0/24
msf auxiliary(syn) > show options
Module options (auxiliary/scanner/portscan/syn):
Name Current Setting Required Description
---- --------------- -------- ----------
BATCHSIZE 256 yes The number of hosts to scan per set
INTERFACE no The name of the interface
PORTS 80 yes Ports to scan (e.g. 2225,80,110-900)
RHOSTS 172.16.36.0/24 yes The target address range or CIDR identifier
SNAPLEN 65535 yes The number of bytes to capture
THREADS 20 yes The number of concurrent threads
TIMEOUT 500 yes The reply read timeout in milliseconds
msf auxiliary(syn) > run
[*] TCP OPEN 172.16.36.135:80
[*] Scanned 256 of 256 hosts (100% complete)
[*] Auxiliary module execution completed
工作原理
Metasploit SYN 掃描輔助模塊背后的底層原理和任何其它 SYN 掃描工具一樣。對于每個被掃描的端口,會發(fā)送 SYN 封包。SYN+ACK 封包會用于識別活動服務。使用 MEtasploit 可能更加有吸引力,因為它擁有交互控制臺,也因為它是個已經(jīng)被多數(shù)滲透測試者熟知的工具。
7.9 hping3 隱秘掃描
除了我們之前學到了探索技巧,hping3 也可以用于執(zhí)行端口掃描。這個秘籍展示了如何使用 hping3 來執(zhí)行 TCP 隱秘掃描。
準備
為了使用 hping3 執(zhí)行 TCP 隱秘掃描,你需要一個運行 TCP 網(wǎng)絡服務的遠程服務器。這個例子中我們使用 Metasploitable2 實例來執(zhí)行任務。配置 Metasploitable2 的更多信息請參考第一章中的“安裝 Metasploitable2”秘籍。
操作步驟
除了我們之前學到了探索技巧,hping3 也可以用于執(zhí)行端口掃描。為了使用 hping3 執(zhí)行端口掃描,我們需要以一個整數(shù)值使用--scan模式來指定要掃描的端口號。
root@KaliLinux:~# hping3 172.16.36.135 --scan 80 -S
Scanning 172.16.36.135 (172.16.36.135), port 80
1 ports to scan, use -V to see all the replies
+----+-----------+---------+---+-----+-----+-----+
|port| serv name | flags |ttl| id | win | len |
+----+-----------+---------+---+-----+-----+-----+
80 http : .S..A... 64 0 5840 46
All replies received. Done.
Not responding ports:
上面的例子中,SYN 掃描執(zhí)行在指定 IP 地址的 TCP 端口 80 上。-S選項指明了發(fā)給遠程系統(tǒng)的封包中激活的 TCP 標識。表格展示了接收到的響應封包中的屬性。我們可以從輸出中看到,接收到了SYN+ACK 響應,所以這表示目標主機端口 80 是開放的。此外,我們可以通過輸入夠好分隔的端口號列表來掃描多個端口,像這樣:
root@KaliLinux:~# hping3 172.16.36.135 --scan 22,80,443 -S
Scanning 172.16.36.135 (172.16.36.135), port 22,80,443
3 ports to scan, use -V to see all the replies
+----+-----------+---------+---+-----+-----+-----+
|port| serv name | flags |ttl| id | win | len |
+----+-----------+---------+---+-----+-----+-----+
22 ssh : .S..A... 64 0 5840 46
80 http : .S..A... 64 0 5840 46
All replies received. Done.
Not responding ports:
在上面的掃描輸出中,你可以看到,僅僅展示了接受到 SYN+ACK 標識的結(jié)果。要注意和發(fā)送到 443 端口的 SYN 請求相關的響應并沒有展示。從輸出中可以看出,我們可以通過使用-v選項增加詳細讀來查看所有響應。此外,可以通過傳遞第一個和最后一個端口地址值,來掃描端口范圍,像這樣:
root@KaliLinux:~# hping3 172.16.36.135 --scan 0-100 -S
Scanning 172.16.36.135 (172.16.36.135), port 0-100
101 ports to scan, use -V to see all the replies
+----+-----------+---------+---+-----+-----+-----+
|port| serv name | flags |ttl| id | win | len |
+----+-----------+---------+---+-----+-----+-----+
21 ftp : .S..A... 64 0 5840 46
22 ssh : .S..A... 64 0 5840 46
23 telnet : .S..A... 64 0 5840 46
25 smtp : .S..A... 64 0 5840 46
53 domain : .S..A... 64 0 5840 46
80 http : .S..A... 64 0 5840 46
All replies received. Done.
Not responding ports:
這個例子中,100 個端口的掃描足以識別 Metasploitable2 系統(tǒng)上的服務。但是,為了執(zhí)行 所有 TCP 端口的掃描,需要掃描所有可能的端口地址值。定義了源端口和目標端口地址的 TCP 頭部部分是 16 位長。并且,每一位可以為 1 或者 0。因此,共有2 ** 16或者 65536 個可能的 TCP 端口地址。對于要掃描的全部可能的地址空間,需要提供 0 到 65535 的端口范圍,像這樣:
root@KaliLinux:~# hping3 172.16.36.135 --scan 0-65535 -S
Scanning 172.16.36.135 (172.16.36.135), port 0-65535
65536 ports to scan, use -V to see all the replies
+----+-----------+---------+---+-----+-----+-----+
|port| serv name | flags |ttl| id | win | len |
+----+-----------+---------+---+-----+-----+-----+
21 ftp : .S..A... 64 0 5840 46
22 ssh : .S..A... 64 0 5840 46
23 telnet : .S..A... 64 0 5840 46
25 smtp : .S..A... 64 0 5840 46
53 domain : .S..A... 64 0 5840 46
111 sunrpc : .S..A... 64 0 5840 46
1099 rmiregistry: .S..A... 64 0 5840 46
1524 ingreslock : .S..A... 64 0 5840 46
2121 iprop : .S..A... 64 0 5840 46
8180 : .S..A... 64 0 5840 46
34789 : .S..A... 64 0 5840 46
512 exec : .S..A... 64 0 5840 46
513 login : .S..A... 64 0 5840 46
514 shell : .S..A... 64 0 5840 46
3632 distcc : .S..A... 64 0 5840 46
5432 postgresql : .S..A... 64 0 5840 46
56375 : .S..A... 64 0 5840 46
80 http : .S..A... 64 0 5840 46
445 microsoft-d: .S..A... 64 0 5840 46
2049 nfs : .S..A... 64 0 5840 46
6667 ircd : .S..A... 64 0 5840 46
6697 : .S..A... 64 0 5840 46
57385 : .S..A... 64 0 5840 46
139 netbios-ssn: .S..A... 64 0 5840 46
6000 x11 : .S..A... 64 0 5840 46
3306 mysql : .S..A... 64 0 5840 46
5900 : .S..A... 64 0 5840 46
8787 : .S..A... 64 0 5840 46
50333 : .S..A... 64 0 5840 46
8009 : .S..A... 64 0 5840 46
All replies received. Done.
Not responding ports:
工作原理
hping3 不用于一些已經(jīng)提到的其它工具,因為它并沒有 SYN 掃描模式。但是反之,它允許你指定 TCP 封包發(fā)送時的激活的 TCP 標識。在秘籍中的例子中,-S選項讓 hping3 使用 TCP 封包的 SYN 標識。
3.10 Scapy 連接掃描
在多數(shù)掃描工具當中,TCP 連接掃描比 SYN 掃描更加容易。這是因為 TCP 連接掃描并不需要為了生成和注入 SYN 掃描中使用的原始封包而提升權限。Scapy 是它的一大例外。Scapy 實際上非常難以執(zhí)行完全的 TCP 三次握手,也不實用。但是,出于更好理解這個過程的目的,我們來看看如何使用 Scapy 執(zhí)行連接掃描。
準備
為了使用 Scapy 執(zhí)行全連接掃描,你需要一個運行 UDP 網(wǎng)絡服務的遠程服務器。這個例子中我們使用 Metasploitable2 實例來執(zhí)行任務。配置 Metasploitable2 的更多信息請參考第一章中的“安裝 Metasploitable2”秘籍。
此外,這一節(jié)也需要編寫腳本的更多信息,請參考第一章中的“使用文本編輯器*VIM 和 Nano)。
操作步驟
Scapy 中很難執(zhí)行全連接掃描,因為系統(tǒng)內(nèi)核不知道你在 Scapy 中發(fā)送的請求,并且嘗試阻止你和遠程系統(tǒng)建立完整的三次握手。你可以在 Wireshark 或 tcpdump 中,通過發(fā)送 SYN 請求并嗅探相關流量來看到這個過程。當你接收到來自遠程系統(tǒng)的 SYN+ACK 響應時,Linux 內(nèi)核會攔截它,并將其看做來源不明的響應,因為它不知道你在 Scapy 中 發(fā)送的請求。并且系統(tǒng)會自動使用 TCP RST 封包來回復,因此會斷開握手過程??紤]下面的例子:
#!/usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
response = sr1(IP(dst="172.16.36.135")/TCP(dport=80,flags='S'))
reply = sr1(IP(dst="172.16.36.135")/TCP(dport=80,flags='A',ack=(respon se[TCP].seq + 1)))
這個 Python 腳本的例子可以用做 POC 來演系統(tǒng)破壞三次握手的問題。這個腳本假設你將帶有開放端口活動系統(tǒng)作為目標。因此,假設 SYN+ACK 回復會作為初始 SYN 請求的響應而返回。即使發(fā)送了最后的 ACK 回復,完成了握手,RST 封包也會阻止連接建立。我們可以通過觀察封包發(fā)送和接受來進一步演示。
#!/usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
SYN = IP(dst="172.16.36.135")/TCP(dport=80,flags='S')
print "-- SENT --"
SYN.display()
print "\n\n-- RECEIVED --"
response = sr1(SYN,timeout=1,verbose=0)
response.display()
if int(response[TCP].flags) == 18:
print "\n\n-- SENT --"
ACK = IP(dst="172.16.36.135")/TCP(dport=80,flags='A',ack=(response[ TCP].seq + 1))
response2 = sr1(ACK,timeout=1,verbose=0)
ACK.display()
print "\n\n-- RECEIVED --"
response2.display()
else:
print "SYN-ACK not returned"
在這個 Python 腳本中,每個發(fā)送的封包都在傳輸之前展示,并且每個收到的封包都在到達之后展示。在檢驗每個封包所激活的 TCP 標識的過程中,我們可以看到,三次握手失敗了??紤]由腳本生成的下列輸出:
root@KaliLinux:~# ./tcp_connect.py
-- SENT -
###[ 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 = S
window = 8192
chksum = None
urgptr = 0
options = {}
-- RECEIVED -
###[ IP ]###
version = 4L
ihl = 5L
tos = 0x0
len = 44
id = 0
flags = DF
frag = 0L
ttl = 64
proto = tcp
chksum = 0x9970
src = 172.16.36.135
dst = 172.16.36.180
\options \
###[ TCP ]###
sport = http
dport = ftp_data
seq = 3013979073L
ack = 1
dataofs = 6L
reserved = 0L
flags = SA
window = 5840
chksum = 0x801e
urgptr = 0
options = [('MSS', 1460)]
###[ Padding ]###
load = '\x00\x00'
-- SENT -
###[ 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 = 3013979074L
dataofs = None
reserved = 0
flags = A
window = 8192
chksum = None
urgptr = 0
options = {}
-- RECEIVED -
###[ 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 = 3013979074L
ack = 0
dataofs = 5L
reserved = 0L
flags = R
window = 0
chksum = 0xaeb8
urgptr = 0
options = {}
###[ Padding ]###
load = '\x00\x00\x00\x00\x00\x00'
在腳本的輸出中,我們看到了四個封包。第一個封包是發(fā)送的 SYN 請求,第二個封包時接收到的 SYN+ACK 回復,第三個封包時發(fā)送的 ACK 回復,之后接收到了 RST 封包,它是最后的 ACK 回復的響應。最后一個封包表明,在建立連接時出現(xiàn)了問題。Scapy 中可能能夠建立完成的三次握手,但是它需要對本地 IP 表做一些調(diào)整。尤其是,如果你去掉發(fā)往遠程系統(tǒng)的 TSR 封包,你就可以完成握手。通過使用 IP 表建立過濾機制,我們可以去掉 RST 封包來完成三次握手,而不會干擾到整個系統(tǒng)(這個配置出于功能上的原理并不推薦)。為了展示完整三次握手的成功建立,我們使用 Netcat 建立 TCP 監(jiān)聽服務。之后嘗試使用 Scapy 連接開放的端口。
admin@ubuntu:~$ nc -lvp 4444
listening on [any] 4444 ...
這個例子中,我們在 TCP 端口 4444 開啟了監(jiān)聽服務。我們之后可以修改之前的腳本來嘗試連接 端口 4444 上的 Netcat 監(jiān)聽服務。
#!/usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
response = sr1(IP(dst="172.16.36.135")/TCP(dport=4444,flags='S'))
reply = sr1(IP(dst="172.16.36.135")/TCP(dport=4444,flags='A',ack=(resp onse[TCP].seq + 1)))
這個腳本中,SYN 請求發(fā)送給了監(jiān)聽端口。收到 SYN+ACK 回復之后,會發(fā)送 ACK回復。為了驗證連接嘗試被系統(tǒng)生成的 RST 封包打斷,這個腳本應該在 Wireshark 啟動之后執(zhí)行,來捕獲請求蓄力。我們使用 Wireshark 的過濾器來隔離連接嘗試序列。所使用的過濾器是tcp && (ip.src == 172.16.36.135 || ip.dst == 172.16.36.135)。過濾器僅僅用于展示來自或發(fā)往被掃描系統(tǒng)的 TCP 流量。像這樣:

既然我們已經(jīng)精確定位了問題。我們可以建立過濾器,讓我們能夠去除系統(tǒng)生成的 RST 封包。這個過濾器可以通過修改本地 IP 表來建立:
以如下方式修改本地 IP 表會通過阻塞所有發(fā)出的 RST 響應,改變和目標系統(tǒng)之間的 TCP/IP 事務的處理方式。確保常見的 iptable 規(guī)則在這個秘籍完成之后移除,或者之后使用下列命令刷新 iptable。
iptables --flush
root@KaliLinux:~# iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 172.16.36.135 -j DROP
root@KaliLinux:~# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- anywhere 172.16.36.135 tcp flags:RST/RST
在這個例子中,本地 IP 表的修改去除了所有發(fā)往被掃描主機的目標地址的 TCP RST 封包。list選項隨后可以用于查看 IP 表的條目,以及驗證配置已經(jīng)做了修改。為了執(zhí)行另一次連接嘗試,我們需要確保 Natcat 仍舊監(jiān)聽目標的 4444 端口,像這樣:
admin@ubuntu:~$ nc -lvp 4444
listening on [any] 4444 ...
和之前相同的 Python 腳本可以再次使用,同時 WIreshark 會捕獲后臺的流量。使用之前討論的顯示過濾器,我們可以輕易專注于所需的流量。要注意三次握手的所有步驟現(xiàn)在都可以完成,而不會收到系統(tǒng)生成的 RST 封包的打斷,像這樣:

此外,如果我們看一看運行在目標系統(tǒng)的 Netcat 服務,我們可以注意到,已經(jīng)建立了連接。這是用于確認成功建立連接的進一步的證據(jù)。這可以在下面的輸出中看到:
admin@ubuntu:~$ nc -lvp 4444
listening on [any] 4444 ... 172.16.36.132: inverse host lookup failed: No address associated with name
connect to [172.16.36.135] from (UNKNOWN) [172.16.36.132] 42409
雖然這個練習對理解和解決 TCP 連接的問題十分有幫助,恢復 IP 表的條目也十分重要。RST 封包 是 TCP 通信的重要組成部分,去除這些響應會影響正常的通信功能。洗嘜按的命令可以用于刷新我們的 iptable 規(guī)則,并驗證刷新成功:
root@KaliLinux:~# iptables --flush
root@KaliLinux:~# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
就像例子中展示的那樣,flush選項應該用于清楚 IP 表的條目。我們可以多次使用list選項來驗證 IP 表的條目已經(jīng)移除了。
工作原理
執(zhí)行 TCP 連接掃描的同居通過執(zhí)行完整的三次握手,和遠程系統(tǒng)的所有被掃描端口建立連接。端口的狀態(tài)取決于連接是否成功建立。如果連接建立,端口被認為是開放的,如果連接不能成功建立,端口被認為是關閉的。