Nmap原始碼分析(指令碼引擎)

2021-06-09 05:27:32 字數 4346 閱讀 9323

2023年9月6日

nmap提供了強大的指令碼引擎(nse),以支援通過lua程式設計來擴充套件nmap的功能。目前指令碼庫已經包含300多個常用的lua指令碼,輔助完成nmap的主機發現、埠掃瞄、服務偵測、作業系統偵測四個基本功能,並補充了其他掃瞄能力:如執行http服務詳細的探測、暴力破解簡單密碼、檢查常見的漏洞資訊等等。如果使用者需要對特定的應用做更深入的**,可以按照nse指令碼格式編寫lua指令碼來增強nmap的掃瞄能力。

nse(nmap scripting engine)是nmap最為強大、最為靈活的功能之一。

nse主要分為兩大部分:內嵌lua直譯器與nse library。

直譯器:nmap採用嵌入的lua直譯器來支援lua指令碼語言。lua語言小巧簡單而且擴充套件靈活,能夠很好地與nmap自身的c/c++語言融合。

nse library:為lua指令碼與nmap提供了連線,負責完成基本初始化及提供指令碼排程、併發執行、io框架及異常處理,並且提供了預設的實用的指令碼程式。

nse中提供的lua指令碼分為不同的類別(category),目前的類別如下:

auth  負責處理鑑權證書(繞開鑑權)的指令碼

broadcast  在區域網內探查更多服務開啟狀況,如dhcp/dns/sqlserver等服務。

brute  提供暴力破解方式,針對常見的應用如http/snmp等

default  這是使用-sc或-a選項掃瞄時候預設的指令碼,提供基本指令碼掃瞄能力

discovery  對網路進行更多的資訊,如smb列舉、snmp查詢等

dos  用於進行拒絕服務攻擊(denial of service)

exploit  利用已知的漏洞入侵系統

external  利用第三方的資料庫或資源,例如進行whois解析

fuzzer  模糊測試的指令碼,傳送異常的包到目標機,探測出潛在漏洞

intrusive 入侵性的指令碼,此類指令碼可能引發對方的ids/ips的記錄或遮蔽

malware 探測目標機是否感染了病毒、開啟了後門等資訊

safe 此類與intrusive相反,屬於安全性指令碼

version 負責增強服務與版本掃瞄(version detection)功能的指令碼。

vuln 負責檢查目標機是否有常見的漏洞(vulnerability),如是否有ms08_067。

nmap提供的命令列引數如下:

-sc: 等價於--script=default,使用預設類別的指令碼進行掃瞄。

--script=: 使用某個或某類指令碼進行掃瞄,支援萬用字元描述

--script-args=: 為指令碼提供預設引數

--script-args-file=filename: 使用檔案來為指令碼提供引數

--script-trace: 顯示指令碼執行過程中傳送與接收的資料

--script-updatedb: 更新指令碼資料庫

--script-help=: 顯示指令碼的幫助資訊,其中部分可以逗號分隔的檔案或指令碼類別。

nmap指令碼引擎所需要的的檔案:

初始化流程

在命令列引數中指定指令碼(--script/-sc)或指定-a選項或指定-sv選項,都會觸發nmap啟動指令碼引擎。其中-a選項表示aggressive scan,會呼叫default類別的指令碼掃瞄;而-sv選項表示應用與版本偵測,會呼叫version類別的指令碼,輔助偵測服務詳細資訊。

在nmap.cc的nmap_main()函式中,若判斷到需要啟動指令碼引擎,那麼呼叫open_nse()函式進行nse環境的準備。在open_nse()中主要建立luastate(管理lua直譯器的執行的全域性變數),然後呼叫init_main()進行詳細的初始化過程。

進入init_main()函式,首先載入lua標準庫與nmap的擴充套件庫,隨後準備引數環境,然後載入並執行nse_main.lua檔案。

nse_main.lua指令碼為後續的指令碼執行準備lua環境,載入使用者選擇的需要呼叫的指令碼(例如,使用者--script discovery,那麼會將該類別中所有的指令碼載入進來),返回乙個main()函式物件給init_main(),該main()是否後續指令碼掃瞄需要的主函式,被儲存在lua的環境的登錄檔中。

在nse_main.lua中,定義兩個核心的類,scriptthread,script用於管理nse指令碼,當新的指令碼被載入時,呼叫script.new建立指令碼物件,該物件被儲存下來在後續的掃瞄過程中使用;thread用於管理指令碼的執行,該類中也包含對指令碼健全性的檢查(sanity check,如是否包含action函式)。在指令碼執行時,如果指令碼之間存在依賴關係,那麼會將基礎的無依賴的指令碼統一執行完畢,再執行依賴性的指令碼。

指令碼掃瞄流程

執行指令碼掃瞄時,從nmap_main()中呼叫script_scan()函式。

在進入script_scan()後,會標記掃瞄階段型別,然後進入到初始化階段返回的main()函式(來自nse_main.lua指令碼中的main)中,在函式中解析具體的掃瞄型別。

main()函式負責處理三種型別的指令碼掃瞄:預掃瞄(script_pre_scan)、指令碼掃瞄(script_scan)、後掃瞄(script_post_scan)。預掃瞄即在nmap呼叫的最前面(沒有進行主機發現、埠掃瞄等操作)執行的指令碼掃瞄,通常該類掃瞄用於準備基本的資訊,例如到第三伺服器查詢相關的dns資訊。而指令碼掃瞄,是使用nse指令碼來掃瞄目標主機,這是最核心的掃瞄方式。後掃瞄,是整個掃瞄結束後,做一些善後處理的指令碼,比如優化整理某些掃瞄。

在main()函式中核心操作由run函式負責。而run()函式的本身設計用於執行所有同一級別的指令碼(根據依賴關係劃分的級別),直到所有執行緒執行完畢才退出。

run()函式中實現三個佇列:執行佇列(running queue)、等待佇列(waiting queue)、掛起佇列(pending queue),並管理三個佇列中線程的切換,直到全部隊列為空或出錯而退出。

///l_nse用於儲存lua程式的狀態

static lua_state *l_nse = null;

///open_nse用於建立lua狀態,準備lua直譯器環境

///呼叫init_main()完成初始化操作。

void open_nse (void)

}///scipt_scan函式具體執行指令碼掃瞄的過程

///設定掃瞄狀態;呼叫run_main()函式執行具體指令碼掃瞄過程。

void script_scan (std::vector&targets, stype scantype)

void close_nse (void)

}static int init_main (lua_state *l)

/* get lua main function */

///呼叫由nse_main.lua轉換後的匿名函式(棧索引2):

///傳入2個引數(棧索引3/4),輸出1個結果(執行完畢後放在棧頂),

///錯誤處理函式對應的棧區索引為1(即debug.traceback)。

///功能:在nse_main.lua會載入使用者選擇的所有的指令碼,並初始化script/thread類

if (lua_pcall(l, 2, 1, 1) != 0) lua_error(l); /* we wanted a traceback */

///將執行nse_main.lua返回的結果(nse_main.lua中的main函式物件)放入登錄檔中,

///以便後續的指令碼掃瞄過程直接呼叫此main函式。

lua_setfield(l, lua_registryindex, nse_main);

return 0;

}static int run_main (lua_state *l)

lua_pop(l, 1); /* pop nse_current_hosts */

///設定main()第二個引數,掃瞄型別

/* push script scan type phase */

switch (o.current_scantype)

///以保護模式執行main()函式,兩個引數,0個返回值,錯誤處理函式在棧區的index1位置

if (lua_pcall(l, 2, 0, 1) != 0) lua_error(l); /* we wanted a traceback */

return 0;

}

Nmap原始碼分析(指令碼引擎)

nmap提供了強大的指令碼引擎 nse 以支援通過lua程式設計來擴充套件nmap的功能。目前指令碼庫已經包含300多個常用的lua指令碼,輔助完成nmap的主機發現 埠掃瞄 服務偵測 作業系統偵測四個基本功能,並補充了其他掃瞄能力 如執行http服務詳細的探測 暴力破解簡單密碼 檢查常見的漏洞資訊...

Nmap 原始碼學習二 整體架構

docs 相關文件 libdnet stripped 開源網路介面庫 liblinear 開源大型線性分類庫 liblua 開源lua指令碼語言庫 libnetutil 基本的網路函式 libpcap 開源抓包庫 libpcre 開源正規表示式庫 macosx xcode專案檔案 mswin32 v...

spring原始碼分析 spring原始碼分析

1.spring 執行原理 spring 啟動時讀取應用程式提供的 bean 配置資訊,並在 spring 容器中生成乙份相應的 bean 配置登錄檔,然後根據這張登錄檔例項化 bean,裝配好 bean 之間的依賴關係,為上 層應用提供準備就緒的執行環境。二 spring 原始碼分析 1.1spr...