NMAP 使用小技巧
IDS 繞過 + 效率提升
簡介
僅僅是引論。
介紹 nmap 的工作流程、重點關注端口掃描技術。
介紹 nmap 提供掃描技術,以及適用場景。
介紹 nmap 速度調整選項。
介紹兩個常見的 IDS 檢測機制。以及如何繞過。
關於 nmap
工作流程
Script pre-scanning.
Target enumeration. -sL -n 分析用戶給出的目標。
Host discovery (ping scanning). 主機發現,用來避免對離線的主機進行接下來的掃描。
Reverse-DNS resolution.
Port scanning. 端口掃描,-sn 跳過這步
Version detection. 檢測 open 狀態端口的服務。
OS detection.
Traceroute.
Script scanning.
Output.
Script post-scanning.
端口掃描技術
這里只簡單介紹原理和適用場景,詳情請參照:https://nmap.org/book/scan-methods.html
-
-sS:SYN 掃描
-
-sF、-sN、-sX
用來判斷端口是否開放,但有可能無法建立連接。通常適用於低版本 unix。
原理是兩個特性:
- 利用了 RFC 793 里的一個細節,windows 不遵守。
- 如果一個端口關閉,非 RST 的請求以 RST 響應。
- 如果一個端口開放,非 SYN | RST | ACK 的請求,都忽略。
- 當無狀態防火牆被配置不允許外部主動發起連接(拒絕SYN),但可以主動向外發起連接(接收 SYNACK )
- 利用了 RFC 793 里的一個細節,windows 不遵守。
-
-sA:
不能用來確定端口是否開放,用來確定是否有防火牆,並且是否是基於狀態的防火牆。原理:
- 沒有防火牆,或基於規則防火牆。因為接收到非預期 ACK ,不管端口開放與否,都會響應 RST 。
- 基於狀態防火牆:檢測沒有主動發起連接,所以直接丟棄這個包,無響應。
-
-sT:能用 -sT ,就能用 -sS。
-
-sI:屬於旁信道探測。需要支持源地址欺騙,並且有一個網絡狀態空閑的僵屍機。條件較為苛刻,並且沒有帶來過多好處。附加一張圖。
-
-b
需要有一個支持代理的 ftp 服務器訪問權限,讓這個ftp 服務器向其它主機的端口發送文件,根據響應判斷端口是否開放。
-
-sW:
-sW 和 -sA 行為一樣,不過會進一步檢查 RST 響應的窗口值,來判斷端口是否開放。但不准(測試了win、linux)。官方文檔說少數系統有用。
-
-sM:
原理是 1996 BSD 的系統的小特性。現在都被修復了。
IDS 的繞過
IDS 如何檢測 nmap 的掃描行為
常見的有兩種:
-
根據 nmap 的流量特征字段 (IDS 規則)
window size、payload size
-
端口訪問行為。(sfportscan )
一段時間內訪問有效的端口與訪問無效端口之間 的數學統計。
配置 ids
snort 是一個開源 IDS/IPS 軟件。https://www.snort.org/
對於檢測端口掃描來說,其既支持通過 IDS 規則匹配流量特征、也支持通過 sfportscan 插件來對端口訪問行為進行統計檢測。
https://rules.emergingthreats.net/OPEN_download_instructions.html 開源 IDS 規則集。在其中下載適用於 snort 的規則集、在規則文件 emerging-scan.rules 中,關於 nmap ,有24 項規則,有端口掃描、服務探測、系統探測等檢測方面。
所以,想要繞過這個規則,只需要使以上任一條規則為假即可。
IDS 規則以及繞過
-sS
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"ET SCAN NMAP -sS window 1024"; fragbits:!D; dsize:0; flags:S,12; ack:0; window:1024; threshold: type both, track by_dst, count 1, seconds 60; reference:url,doc.emergingthreats.net/2009582; classtype:attempted-recon; sid:2009582; rev:3; metadata:created_at 2010_07_30, updated_at 2010_07_30;)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"ET SCAN NMAP -sS window 2048"; fragbits:!D; dsize:0; flags:S,12; ack:0; window:2048; threshold: type both, track by_dst, count 1, seconds 60; reference:url,doc.emergingthreats.net/2000537; classtype:attempted-recon; sid:2000537; rev:8; metadata:created_at 2010_07_30, updated_at 2010_07_30;)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"ET SCAN NMAP -sS window 3072"; fragbits:!D; dsize:0; flags:S,12; ack:0; window:3072; threshold: type both, track by_dst, count 1, seconds 60; reference:url,doc.emergingthreats.net/2009583; classtype:attempted-recon; sid:2009583; rev:3; metadata:created_at 2010_07_30, updated_at 2010_07_30;)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"ET SCAN NMAP -sS window 4096"; fragbits:!D; dsize:0; flags:S,12; ack:0; window:4096; threshold: type both, track by_dst, count 1, seconds 60; reference:url,doc.emergingthreats.net/2009584; classtype:attempted-recon; sid:2009584; rev:2; metadata:created_at 2010_07_30, updated_at 2010_07_30;)
-
fragbits:!D;
當 IP flags 字段 Don`t Fragment 比特位為 0 時,此條件為真。通過觀察上網過程中數據包,發現有 0 有 1 ,所以這條可以不用管。
-
dsize:0
表示傳輸層 payload 大小為 0 。攜帶的數據大小,nmap 提供
--data-length num
選項可以指定附加 num 個字節的隨機數據。但通常 SYN 數據包默認不攜帶載荷,即為 0。
-
flags:S,12
TCP flags 位,S 為 SYN 並且忽略 cwr(1)、ece(2)(這條語句匹配的是flags 中除這兩個bit位,其它bit 位只有 syn 置位)。實際數據包相似,不用更改。
-
ack:0
表示 TCP ack number 為 0 。實際握手數據包相似,不需要更改。
-
window:1024
TCP window size 為 1024 。在 tcpip.cc 665 行中,將其修改為
tcp->th_win = htons(12573+get_random_u8());
-sC
alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"ET SCAN Nmap Scripting Engine User-Agent Detected (Nmap NSE)"; flow:to_server,established; content:"User-Agent|3a| Nmap NSE"; http_header; reference:url,doc.emergingthreats.net/2009359; classtype:web-application-attack; sid:2009359; rev:4; metadata:created_at 2010_07_30, updated_at 2020_05_04;)
alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"ET SCAN Nmap Scripting Engine User-Agent Detected (Nmap Scripting Engine)"; flow:to_server,established; content:"User-Agent|3a| Mozilla/5.0 (compatible|3b| Nmap Scripting Engine"; fast_pattern:38,20; http_header; nocase; reference:url,doc.emergingthreats.net/2009358; classtype:web-application-attack; sid:2009358; rev:5; metadata:created_at 2010_07_30, updated_at 2020_04_22;)
alert tcp $HOME_NET any -> any any (msg:"ET SCAN Possible Nmap User-Agent Observed"; flow:to_server,established; content:"User-Agent|3a|"; http_header; content:"|20|Nmap"; http_header; fast_pattern; distance:0; classtype:web-application-attack; sid:2024364; rev:3; metadata:affected_product Any, attack_target Client_and_Server, created_at 2017_06_08, deployment Perimeter, former_category SCAN, performance_impact Low, signature_severity Informational, updated_at 2020_08_06;)
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"ET SCAN NMAP SQL Spider Scan"; flow:established,to_server; content:"GET"; http_method; content:" OR sqlspider"; http_uri; reference:url,nmap.org/nsedoc/scripts/sql-injection.html; classtype:web-application-attack; sid:2013778; rev:1; metadata:created_at 2011_10_19, updated_at 2020_04_20;)
-
flow:to_server,established;
當收到客戶端請求時,並且是已建立 tcp 連接的請求。 -
content:"User-Agent|3a| Nmap NSE";
content 表示在傳輸層 payload 中搜索。content 后直接跟的是一些修飾詞。對搜索做進一步限制。
http_header;
、http_method;
、http_uri;
限制其在 http 中不同部位進行搜索。fast_pattern:38,20;
用於性能優化的修飾詞,跟主題關系不大。distance:0;
用來指出上一個 content 結束后間隔多少個字節再匹配此 content 。nocase;
忽略大小寫
nselib/http.lua 159 行,修改即可。
Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36
-sV
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"ET SCAN NMAP -f -sV"; fragbits:!M; dsize:0; flags:S,12; ack:0; window:2048; threshold: type both, track by_dst, count 1, seconds 60; reference:url,doc.emergingthreats.net/2000545; classtype:attempted-recon; sid:2000545; rev:8; metadata:created_at 2010_07_30, updated_at 2010_07_30;)
-O
alert udp $EXTERNAL_NET 10000: -> $HOME_NET 10000: (msg:"ET SCAN NMAP OS Detection Probe"; dsize:300; content:"CCCCCCCCCCCCCCCCCCCC"; fast_pattern:only; content:"CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"; depth:255; content:"CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"; within:45; classtype:attempted-recon; sid:2018489; rev:3; metadata:created_at 2014_05_20, updated_at 2019_10_07;)
-
content 修飾詞
depth:255;
指的是在 tcp payload 最多查看前 255 個字節。within:45;
表示在前一個 content 末尾 45 個字節內搜索此content
在 osscan2.cc 2149 行中
將其更改為其它字節
static u8 patternbyte = 0x45; /* character 'E' */
-sA
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"ET SCAN NMAP -sA (1)"; fragbits:!D; dsize:0; flags:A,12; window:1024; threshold: type both, track by_dst, count 1, seconds 60; reference:url,doc.emergingthreats.net/2000538; classtype:attempted-recon; sid:2000538; rev:8; metadata:created_at 2010_07_30, updated_at 2010_07_30;)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"ET SCAN NMAP -sA (2)"; fragbits:!D; dsize:0; flags:A,12; window:3072; threshold: type both, track by_dst, count 1, seconds 60; reference:url,doc.emergingthreats.net/2000540; classtype:attempted-recon; sid:2000540; rev:8; metadata:created_at 2010_07_30, updated_at 2010_07_30;)
繞過以上,就足以繞過這些
-sF -sN -sX -sM
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"ET SCAN NMAP -f -sF"; fragbits:!M; dsize:0; flags:F,12; ack:0; window:2048; threshold: type both, track by_dst, count 1, seconds 60; reference:url,doc.emergingthreats.net/2000543; classtype:attempted-recon; sid:2000543; rev:7; metadata:created_at 2010_07_30, updated_at 2010_07_30;)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"ET SCAN NMAP -f -sN"; fragbits:!M; dsize:0; flags:0,12; ack:0; window:2048; threshold: type both, track by_dst, count 1, seconds 60; reference:url,doc.emergingthreats.net/2000544; classtype:attempted-recon; sid:2000544; rev:7; metadata:created_at 2010_07_30, updated_at 2010_07_30;)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"ET SCAN NMAP -f -sX"; fragbits:!M; dsize:0; flags:FPU,12; ack:0; window:2048; threshold: type both, track by_dst, count 1, seconds 60; reference:url,doc.emergingthreats.net/2000546; classtype:attempted-recon; sid:2000546; rev:7; metadata:created_at 2010_07_30, updated_at 2010_07_30;)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"GPL SCAN nmap XMAS"; flow:stateless; flags:FPU,12; reference:arachnids,30; classtype:attempted-recon; sid:2101228; rev:8; metadata:created_at 2010_09_23, updated_at 2010_09_23;)
繞過以上,就足以繞過這些
基於統計的 ids 繞過
- 掛代理
- 調整掃描速度
內網環境下源地址偽造
此外,還有些技術是基於內網環境端口掃描,例如以下。
- -S / -g 偽造源 ip / 源端口 -D 偽造多個源地址。不過試了一下,偽造失敗,推測網關路由器過濾不合法符的源 ip。可能對於交換機環境有用。
- -sI 基於源地址偽造的掃描技術。
時間與效率
nmap 提供的控制選項
可以參照來微調,
-
min-rtt-timeout \ max-rtt-timeout \ initial-rtt-timeout
指定一個探測請求的 timeout 。通常來講,可以通過來判斷 ping 目標的時間來設置。
-
max-retries
很值得設置如果確定整個通信過程比較穩定,那就設置為 0
測試結果
耗時:149,110,120,132,130,116,152,139
耗時:65,62,59,59,64,60,63,60
掃描結果是相同的。如果說網絡比較穩定,目標比較邊緣,不在意隱蔽性,那么就可以嘗試。
雖然一個目標可能差距不大,但數量一多,效率還是比較可觀。
其它
在虛擬機上掃的結果與主機上結果不同。用 wireshark 抓包后發現,在掃描結果出來后,7777 響應包才到,意味着響應時間超過 rtt 。
為排除其它軟件的影響,重啟后也一樣。
虛擬機使用的是 NAT ,vmware NAT 的處理也是要耗時的。對時間較為敏感的操作,盡量不要在 NAT 模式的虛擬機上做。橋接模式也類似,主機更穩定點。
總結
網上公開的資料不多,也受限於實驗環境,作為引論,歡迎小伙伴們一起交流。
-
針對端口掃描技術
- 首選 -sS ,盡量不要用 -sT
- -sN、-sF、-sX:三個是相似的,用來判斷端口是否開放,但有可能無法建立連接。通常適用於低版本 unix。
- -sA :用來判斷對方是否為有無狀態的防火牆。對於阿里雲之類的雲主機,可能是有防護。
- -sI、-b :通常只有在內網環境才能達成使用條件。
- -sM、-sW:完全不行了。
- -sU :使用較少。。
-
盡可能修改 nmap 的特征值,以繞過 ids 防護規則。
-
在網絡穩定的情況下。可以使用
--max-retries 0
以降低重傳的次數。對效率提升巨大。 -
根據目標判斷,如無特別必要,盡量不要掃全端口。百度、淘寶首頁之類服務器,基本不會開放其它端口。但像小型公司,或者邊緣業務,或者內網環境,就可以試試。
使用
--top-ports 4000
已經可以覆蓋 99% 常見端口。 -
追求隱秘性:
- 修改 nmap 特征。
- 特殊情況下,可以使用
--data-length <len>
來攜帶一定數量的載荷。 - 限制每秒發包的速率
--max-rate <num>
或者使用-T0 -T1
等時間模板的控制。 - 使用 socks 代理。
- 將要掃描的端口分段,在不同的時間段掃描。
-p
- 在內網環境下,可以進一步使用
-S -D --spoof-mac
等偽造來源的技術。