NSE 指令格式
NSE(Nmap Scripting Engine)指令的格式由一些描述性字元欄位、定義指令何時執行的規則以及包含實際指令的操作函數所組成,可以像分配其他Lua變量一樣,將值分配給這些描述性字元欄位,它們的名稱必須按照本節所示的小寫方式命名。
-- 描述性字元欄位
description = "This is a sample NSE script"
author = "Your Name"
license = "GPLv2+"
categories = {"default", "discovery"}
-- 執行規則
hostrule = function(host)
return true
end
-- 操作函數
action = function(host)
-- 執行指令操作,與目標主機進行交互
-- ...
end
在這個範例中,我們定義了描述性字元欄位,確定了指令的執行規則,並在操作函數中定義了實際的指令操作。這只是一個簡單的範例,實際的NSE指令可能包含更多複雜的邏輯和互動方式。
description 字元欄位
description 字元欄位用於描述指令的測試目的以及使用者應該注意的重要訊息;根據指令的複雜性,描述可以從幾個句子到幾個段落不等,第一段應該是對指令功能的簡要概要,適合單獨呈現給使用者;後面的段落可以提供更多有關指令的詳細資訊。
這個字元欄位的目的是幫助使用者了解指令的用途和功能,以便他們可以更好地使用和理解指令的運作方式;描述應該清晰、簡潔,並提供足夠的資訊,以便使用者明白指令的用途和工作原理。
以下是一個 description 的使用範例:
description = "This NSE script tests for the presence of a specific vulnerability in the target system. It checks if the target system is vulnerable to CVE-XXXX-XXXX, which could potentially allow remote attackers to execute arbitrary code. This script will not exploit the vulnerability but will provide information about its presence."
在這個範例中,description 簡要說明指令的測試目的,提到了測試的漏洞和指令的行為,這樣的描述有助於使用者了解指令的用途和作用。
categories字元欄位
categories字元欄位用於定義指令所屬的一個或多個類別,這些類別是不區分大小寫的,可以以任何順序指定,它們以類似 Lua 表格的方式列在一起,如下所示:
categories = {"default", "discovery", "safe"}
在這個範例中,指令屬於三個類別:default、discovery 和 safe;這些類別有助於組織和分類指令,使用者可以輕鬆找到和選擇適合他們需求的指令;以下是一些常見的類別範例:
default:預設類別,用於一般性指令。
discovery:用於主機和服務探索的指令。
intrusive:用於進行有可能對目標系統造成干擾或影響的指令。
safe:用於安全性較高的指令,通常不會對目標系統造成干擾。
vuln:用於測試目標系統漏洞的指令。
指令的類別有助於使用者快速了解其用途和特性,並確保它們適合特定的使用情境。
author 字元欄位
author 字元欄位包含指令作者名稱,也可加入聯絡訊息(例如個人網頁的URL);不再建議包含電子郵件,因為垃圾郵件發送者可能會從 NSEDoc 網站上爬取這些訊息;這個選擇性的字元欄位不會被 NSE 使用,但它可為作者提供應有的榮譽或責任感;此外,它也有助於知道誰負責維護和更新特定的指令。
license字元欄位
Nmap 是一個社群項目,歡迎各種類型的代碼貢獻,包括 NSE 指令;因此,如果您編寫了有價值的指令,請不要將其保留給自己!授權字元欄位的存在有助於確保我們擁有合法權限來發佈隨 Nmap 一起提供的所有指令;目前,所有這些指令都使用標準的 Nmap 授權(詳情請參閱“Nmap 版權和授權”部分),授權字元欄位包括:
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
Nmap 授權類似於 GNU GPL,如果指令作者更喜歡使用 BSD 風格的授權(無廣告條款),可以使用以下列範例來表示 BSD 風格的許可證:
license = "Simplified (2-clause) BSD license--See https://nmap.org/svn/docs/licenses/BSD-simplified"
dependencies字元欄位
dependencies 字元欄位是一個陣列,其中包含了指令的名稱,如果這些指令也被選擇執行,則它們應該在這個指令之前執行,這是用於當一個指令需要使用另一個指令的結果時;例如,大多數 smb-* 指令都依賴於 smb-brute,因為 smb-brute 找到的帳戶可能允許其他指令獲得更多訊息;列出在 dependencies 中的指令不會自動執行,它們仍然需要透過 --script 選項或其他方式被選擇執行;dependencies 字元欄位的主要作用,是確保選擇執行的指令按照正確的順序執行,以滿足相互依賴的情況;這是 smb-os-discovery 的一個依賴性表格範例:
dependencies = {"smb-brute"}
這表示當您選擇執行 smb-os-discovery 指令時,如果也選擇了 smb-brute,則 smb-brute 將在 smb-os-discovery 之前執行,這有助於確保在需要依賴的結果之前執行相關的指令。
dependencies 表格是選擇性的,如果省略了這個字元欄位,NSE 將假定指令沒有依賴關係。
依賴關係建立了指令的內部執行順序,為每個指令分配了一個稱為 "runlevel" 的數字[12],在執行指令時,您將在 NSE 的輸出中看到每個指令執行的 runlevel(以及runlevel 總數):
NSE: Script scanning 127.0.0.1.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 17:38
Completed NSE at 17:38, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 17:38
Completed NSE at 17:38, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 17:38
Completed NSE at 17:38, 0.00s elapsed
NSE: Script Scanning completed.
規則
Nmap 使用指令規則來確定是否對目標執行指令,規則是一個返回 true 或 false 的 Lua 函數,只有當規則評估為 true 時,才執行指令操作函數。
一個指令必須包含以下一個或多個函數,以確定指令何時執行:
prerule()
hostrule(host)
portrule(host, port)
postrule()
prerule 指令在任何主機被掃描之前,會在指令預先掃描階段執行一次;hostrule 和 portrule 在每批主機被掃描後執行,postrule 在所有主機都被掃描後一次執行,處於指令後掃描 (post-scanning) 階段,如果指令具有多個規則,則可能在多個階段執行。
prerule 和 postrule 不接受參數,hostrule 接受一個主機表,可以測試例如目標的 IP 位址或主機名稱等;portrule 接受一個主機表和一個埠號表,用於處於開放、開放、過濾、或未過濾狀態的任何埠,傳輸埠規則通常用於檢查傳輸埠的特定屬性,例如埠號、傳輸埠開放狀態、或傳輸埠上正在運作的服務名稱等因素;舉個例子,如果一個指令需要與Web伺服器進行互動,那麼它可能會使用連接埠規則來確定是否只在HTTP(連接埠80)上執行,以避免在不必要的連接埠上執行操作;規則的範例請至規則說明頁面查看。
使用者可以在選擇執行指令時,不受指令執行規則函數的限制;指令會根據一定的規則來決定是否對目標執行,可以透過在—script參數中的參數名稱(類別或其他表示式)前面加上+號,則無論這些規則函數的結果如何,都會強制執行該指令。
當您在編寫指令時,需要根據指令執行的性質選擇使用 prerule 或 postrule,如果指令需要在掃描之前執行主機探索或其他網路操作,則應使用 prerule 函數;而如果指令只需要報告掃描期間收集的資料和統計訊息,則應使用 postrule 函數;這有助於確保指令在正確的時間執行,以達到預期的效果。
動作
動作(action)是 NSE 指令的核心,包含了當 prerule、portrule、hostrule 或 postrule 觸發時要執行的所有指令;它是一個 Lua 函數,接受與規則相同的參數;動作的返回值可以是一個 “名稱-值” 的表格、一個字串,或者是 nil;有關 NSE 動作的範例,請參考“動作說明”。
如果動作的輸出是一個表格,則它會自動以結構化的方式格式化,以包含在正常(-oN)和 XML(-oX)輸出格式中;如果是一個字串,則該文本直接顯示在正常輸出中,並在 XML 輸出中作為 XML 屬性寫入;如果指令返回 nil,則不會產生輸出;有關不同返回值如何處理的詳細資訊,請參考“結構化和非結構化輸出”部分。
環境變數
每個指令都有自己的一組環境變數:
SCRIPT_PATH
指令的路徑
SCRIPT_NAME
指令的名稱,此變數可以在除錯的輸出中使用。
SCRIPT_TYPE
由於一個指令可以定義多個規則函數,此環境變數將顯示哪個規則哪個規則已經觸發了指令的執行,如果指令希望在不同的指令掃描階段之間共享一些代碼,則此變數將很有用;它將取其中一個字符串值:"prerule"、"hostrule"、"portrule" 或 "postrule",此變數僅在規則函數的評估期間和之後才可用。
prerule:表示指令正在 prerule 階段執行,即在開始對主機進行掃描之前。
hostrule:表示指令正在 hostrule 階段執行,即在每批主機掃描後執行。
portrule:表示指令正在 portrule 階段執行,即對每個具體的傳輸埠執行掃描時。
postrule:表示指令正在 postrule 階段執行,即在所有主機都已掃描完成後執行。
這個變數幫助指令(指令)確定當前是哪個階段執行,並允許根據需要共享程式碼或執行不同的操作。
以下範例是使用前述環境變數的除錯代碼,以及來自 dns-zone-transfer 的輸出資訊:
stdnse.print_debug(3, "Skipping '%s' %s, 'dnszonetransfer.server' argument is missing.", SCRIPT_NAME, SCRIPT_TYPE)
Initiating NSE at 15:31
NSE: Skipping 'dns-zone-transfer' prerule, 'dnszonetransfer.server' argument is missing.
[12] 在 Nmap 版本 5.10BETA2 之前,不存在依賴關係,指令必須手動設定 runlevel 字元欄位。
隨選即看研討會
延伸閱讀
CyberScope Nmap 滲透測試手持式網路分析儀,整合了 Nmap 功能,為站點存取層提供全面的網路安全風險評估、分析、和報告——包括所有的端點和網路探索、有線與無線網路安全、漏洞評估 (Nmap) 以及網段和配置驗證;IT 人員透過單一工具以及單一介面,即可快速且即時的掌握企業或組織的各種混合式網路環境 (有線、無線、PoE)、各種連網終端裝置的拓樸、架構、設置、網段、效能、直到網路安全評估。