【網絡攻防課實驗】五:Nmap腳本引擎 (NSE) 的使用及腳本編寫


實驗簡述

Nmap具有強大的腳本引擎NSE(Nmap Scripting Engine),它允許用戶編寫(和共享)簡單的腳本(使用lua編程語言)自動化各種網絡任務。

本次實驗目的在於掌握Nmap腳本的基本使用方法。

實驗環境

kali,IP地址:192.168.11.11

Linux,IP地址:192.168.11.21

實驗內容

1、初識NSE

Nmap提供的腳本相關命令行參數如下:

  • -sC: 等價於–script=default,使用默認類別的腳本進行掃描 可更換其他類別
  • –script=: 使用某個或某類腳本進行掃描,支持通配符描述
  • –script-args=<n1=v1,[n2=v2,…]>: 爲腳本提供默認參數
  • –script-args-file=filename: 使用文件來爲腳本提供參數
  • –script-trace: 顯示腳本執行過程中發送與接收的數據
  • –script-updatedb: 更新腳本數據庫
  • –script-help=: 顯示腳本的幫助信息,其中部分可以逗號分隔的文件或腳本類別

該步驟簡單介紹腳本的相關使用。

在使用Nmap時,通過--script=腳本名語句來調用腳本,而且Nmap自帶衆多腳本,路徑如下:
在這裏插入圖片描述
這些腳本大致分爲以下幾種:

  • auth 處理身份驗證
  • broadcast 網絡廣播
  • brute 暴力猜解
  • default 默認
  • discovery 服務發現
  • dos 拒絕服務
  • exploit 漏洞利用
  • external 外部擴展
  • fuzzer 模糊測試
  • intrusive 掃描可能造成不良後果
  • malware 檢測後門
  • safe 掃描危害較小
  • version 版本識別
  • vuln 漏洞檢測

在調用腳本時,可以使用種類名來調用該分類下的全部腳本,如--scritp vuln,但是比較費時間,在此就不演示,本次以 http-methods 腳本爲例,來演示腳本的大致使用。

使用--script-help腳本名來查看腳本的說明和用法,比如查看 http-methods.nse 腳本信息:
在這裏插入圖片描述
使用http-methods.nse腳本來對目標主機進行探測,用於得到目標支持的http請求方式

nmap --script-help=http-methods 192.168.11.21

在這裏插入圖片描述
可以看到探測出來目標主機支持的http請求有 GET、POST、HEAD、OPTIONS 四種。

因爲所有的腳本都是以服務名來命名,比如 http 相關的腳本就是 http 開頭,ssl 相關腳本是以 ssl開頭:
在這裏插入圖片描述
因此在調用腳本時,可以使用通配符 * 來調用相關服務下的所有腳本,以mysql服務爲例,所有mysql腳本如下:
在這裏插入圖片描述
使用語句 --script "mysql*" 來選擇mysql相關的所有腳本,探測結果如下:

nmap --script "mysql*" 192.168.11.21

在這裏插入圖片描述

2、NSE參數

Nmap在使用腳本時,如果腳本支持,我們還可以通過 --script-args 傳入參數。

已知一些網站會通過判斷 user-agent 來判斷請求是否合法,那Nmap在請求時有沒有帶上自己的特徵呢?同樣使用剛纔的 http-methos.nse 腳本,打開wireshark抓包,啓動以下命令:

nmap --script=http-methods.nse 192.168.11.21

在這裏插入圖片描述
可以看到在請求包的 User-Agent 字段信息包含 Nmap Scripting Engine,也就是代表該請求來自 Nmap的腳本,如果目標主機對該請求進行了過濾,那麼就無法成功探測。

因此需要加入一定的參數,來改變 User-Agent 字段信息,繞過過濾,使用 --script-args 修改 User-Agent 的值

命令如下:

nmap --script=http-methods --script-args http.useragent="Mozilla 42" 192.168.11.21

在這裏插入圖片描述
重新抓包,發現 User-Agent 字段內容已經更改
在這裏插入圖片描述
還有其他腳本參數,後續繼續學習。

3、輸出細節

在使用腳本時,可以添加 --script-trace 參數來打印出所有交互數據包的細節

nmap --script=http-methods --script-trace 192.168.11.21

在這裏插入圖片描述
使用 -d1-9 來進入調試模式,查看掃描信息,數字越大,輸出越詳細,以 d2 爲例:

nmap --script=http-methods -d2 192.168.11.21

在這裏插入圖片描述

4、腳本格式

Nmap腳本使用 lua 語言編寫,採用嚴格的格式規範,一個完整的NSE包括以下幾個部分:

  • 引用API(local aaa require(“aaa”))
  • description字段:腳本的介紹及描述
  • author字段:作者信息
  • categories字段:腳本分類信息
  • rule字段:腳本觸發執行的條件
  • action字段:腳本執行內容

依然以 http-methods.nse 腳本爲例,來展示nse的組成:

1.引用API部分:使用 require 函數調用模塊
在這裏插入圖片描述
2.description字段:腳本的介紹及描述
在這裏插入圖片描述
3.author字段:作者信息
在這裏插入圖片描述
4.categories字段:腳本分類信息
在這裏插入圖片描述
5.rule字段:描述腳本執行的規則,也就是確定腳本觸發執行的條件,這個規則是一個lua函數,返回值只有true和false兩種,只有返回true時,action中的函數纔會執行
在這裏插入圖片描述
6.action字段:腳本具體的執行內容,當腳本通過rule字段的檢查被觸發執行時,就會調用action字段定義的函數
在這裏插入圖片描述
Nmap的擴展腳本語言都基於lua來開發的,執行也是調用了內部封裝的lua解釋器。正常情況下,調用任何一個擴展腳本會首先執行nse_main.lua,該腳本主要做了以下幾件事:

  • 加載一些Nmap的核心庫(nselib文件夾中)

    定義多線程函數

    定義輸出結果處理函數

    讀取、加載擴展腳本

    定義擴展腳本函數接口

    執行擴展腳本

擴展腳本執行的規則在nse_main.lua中有定義:
在這裏插入圖片描述
具體的執行規則如下:

  • prerule:在掃描任何主機之前,prerule函數運行一次
  • hostrule:在掃描一個主機後運行一次
  • portrule:在掃描一個主機的端口後運行一次
  • postrule:在全部掃描完畢以後運行一次

可以編寫一個nse文件進行簡單的驗證:
在這裏插入圖片描述
其中action函數是在 hostrule 或 portsule 返回 true 時,纔會,因爲 prerule 和 postrule 沒有判斷條件。

執行結果如下:
在這裏插入圖片描述
也就是說,

  • prerule 和 postrule 是在開始和結束運行,並且只運行一次
  • hostrule 是掃描一個主機就運行一次,有N個主機就會運行N次
  • portrule 是掃描到一個端口就運行一次,有N個端口就運行N次

瞭解了這些後,我們試着編寫一個簡單的腳本,來體驗一下NSE的功能。

5、編寫腳本

在開始編寫腳本之前,還應該對NSE中數據的傳遞做簡單瞭解

在腳本引擎中,用戶可以輕鬆訪問Nmap已經瞭解的有關目標主機的信息。該數據作爲參數傳遞給NSE腳本的 action 方法,參數 host 和 port 是 lua 表,其中包含腳本執行的目標的信息。

每個表裏面所含有的變量:

host 表:

host:
該表作爲參數傳遞給規則和操作功能。
host.os:
操作系統匹配表數組。
host.ip:
包含目標主機IP地址的字符串表示形式。
host.nam:
包含表示爲字符串的掃描目標主機的反向DNS條目。
host.targetname:
包含在命令行上指定的主機名。
host.reason:
包含目標主機爲何處於其當前狀態的原因的字符串表示形式。
host.reason_ttl:
包含響應數據包的TTL值,用於確定目標主機到達時的狀態。
host.directly_connected:
一個布爾值,指示目標主機是否直接連接到運行Nmap的主機(即與該主機處於同一網段)。
host.mac_addr:
MAC地址 目標主機的名稱(六字節長的二進制字符串)(如果有),否則nil。
host.mac_addr_next_hop:
到主機的路由中第一跳的MAC地址,或者 nil如果不可用。
host.mac_addr_src:
我們自己的MAC地址,用於連接到主機(我們的網卡或(帶有 --spoof-mac) 欺騙性地址)。
host.interface:
包含接口名稱的字符串(dnet樣式) 通過它向主機發送數據包。
host.interface_mtu:
MTU(最大傳輸單位)host.interface,如果未知,則爲0。
host.bin_ip:
目標主機的IP地址爲4字節(IPv4)或16字節(IPv6)字符串。
host.bin_ip_src:
我們主機的(正在運行的Nmap)源IP地址爲4字節(IPv4)或16字節(IPv6)字符串。
host.times:
該表包含主機的Nmap時序數據。
host.traceroute:
這是使用該–traceroute選項時出現的traceroute躍點數組。
host.os_fp:
如果執行了OS檢測,則這是一個字符串,其中包含主機的OS指紋。

port 表:

port.number:
目標端口的端口號。
port.protocol:
目標端口的協議,有效值爲 “tcp"和"udp”。
port.service:
包含 port.numberNmap 服務檢測所檢測到的正在運行的服務的字符串表示形式 。
port.reason:
包含目標端口爲何處於其當前狀態的原因的字符串表示形式(由提供port.state)。
port.reason_ttl:
包含響應數據包的TTL值,用於確定目標端口到達時的狀態。此響應數據包是也用於設置的數據包port.reason。
port.state:
包含有關端口狀態的信息。服務腳本只能再次運行。
port.version相關:
此項是一個表,其中包含Nmap版本掃描引擎檢索到的信息。

參考 Nmap官方文檔:https://nmap.org/book/nse-api.html

瞭解了NSE中數據的傳遞,嘗試寫一個簡單的腳本。

實現的功能是當發現目標開放端口後,便輸出"IP *** open *** port"的語句,嚴格按照格式來編寫一個完整的腳本:
在這裏插入圖片描述

description = [[
this is my fisrt nmap script.
]]

author = {"wx"}

categories = {"default"}

portrule = function(host, port)
	return true
end

action = function(host, port)
	return string.format("IP <%s> open <%d> port", host.ip, port.number)
	       -- "IP".. host .."open".. port.number .."port"
end

運行結果:
在這裏插入圖片描述
那如果想在指定端口下輸出結果呢?以 80 端口爲例,此時代碼如下:
在這裏插入圖片描述
只需要返回指定的端口,即當判斷是 80 端口時,就會返回True,然後執行 action 函數。

運行結果:
在這裏插入圖片描述
至此,實驗基本結束。

實驗總結

本次實驗瞭解了Nmap的腳本引擎NSE,學習了在Nmap中如何使用腳本以及腳本的編寫,通過學習編寫了簡單的測試腳本。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章