使用SpringBoot+nmap4j獲取端口信息的代碼詳解
序言
今天在工作的時(shí)候,領(lǐng)導(dǎo)突然安排和我說一個(gè)需求,就是根據(jù)一個(gè) ip 和 端口去獲取對(duì)應(yīng)服務(wù)上對(duì)應(yīng)端口的信息,當(dāng)時(shí)主要是為了確定數(shù)據(jù)庫的版本和型號(hào),比如 MySQL、Oracle 這些數(shù)據(jù)庫,我后面嘗試發(fā)現(xiàn)其他端口也可以獲取信息。這個(gè)在公司里之前是通過 python 來寫的,python 里面剛好有這個(gè)模塊,但是 Java 沒有,所以寫這篇文章記錄一下,幫助大家以后避免踩坑。
nmap4j
nmap4j 是一個(gè)用于 Java 語言的 Nmap 端口掃描器的包裝庫,它允許 Java 開發(fā)者在自己的項(xiàng)目中方便地調(diào)用 Nmap 的功能進(jìn)行網(wǎng)絡(luò)掃描和探測(cè)。
在運(yùn)行這個(gè)代碼之前,我們是需要下載 nmap 的可執(zhí)行文件,地址為:Download the Free Nmap Security Scanner for Linux/Mac/Windows
這里下載第一個(gè),下載后安裝就行了。
代碼說明
接下來和大家說一下 nmap4j 中的測(cè)試代碼,這里面有個(gè)坑,我當(dāng)時(shí)找了好久,代碼在 test/org/nmap4j/Nmap4jTest.java
public class Nmap4jTest { @Test public void basicNmap4jUsageTest() { try { // 這里的路徑要改為剛才 nmap 軟件的安裝路徑 String path = "/usr/local" ; Nmap4j nmap4j = new Nmap4j( path ) ; // 這地方使用了 -oX 后面要跟文件名稱 nmap4j.addFlags( "-sV -T5 -O -oX -" ) ; nmap4j.includeHosts( "localhost" ) ; nmap4j.execute() ; if( !nmap4j.hasError() ) { NMapRun nmapRun = nmap4j.getResult() ; // 這一行一定要注釋掉,不然會(huì)一直報(bào)錯(cuò) String output = nmap4j.getOutput() ; // 這一樣代碼意義也不大,我直接刪掉了 if( output == null ) { fail() ; } String errors = nmap4j.getExecutionResults().getErrors() ; if (errors == null ) { fail() ; } } } catch (NMapInitializationException e) { // TODO Auto-generated catch block e.printStackTrace(); fail() ; } catch (NMapExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); fail() ; } } }
參數(shù)說明:
目標(biāo)選擇參數(shù):
- -iL :從文件中讀取掃描目標(biāo)列表。例如,
nmap -iL targets.txt
,會(huì)從targets.txt
文件中讀取每行一個(gè)的 IP 地址或域名作為掃描目標(biāo)。 - -iR :隨機(jī)選擇指定數(shù)量的主機(jī)進(jìn)行掃描。如
nmap -iR 100
,會(huì)隨機(jī)選取 100 個(gè)主機(jī)進(jìn)行掃描。 - --exclude <host1[,host2,...]> :排除指定的主機(jī)或網(wǎng)絡(luò)不進(jìn)行掃描。例如,
nmap 192.168.1.0/24 --exclude 192.168.1.100,192.168.1.200
,將掃描192.168.1.0/24
網(wǎng)段,但排除192.168.1.100
和192.168.1.200
這兩臺(tái)主機(jī)。 - --excludefile <exclude_file> :從文件中讀取要排除的主機(jī)或網(wǎng)絡(luò)列表。
- -iL :從文件中讀取掃描目標(biāo)列表。例如,
掃描類型參數(shù)
- -sS:TCP SYN 掃描,也稱為半開放掃描。它發(fā)送 SYN 包到目標(biāo)端口,如果收到 SYN/ACK 響應(yīng),就表示端口開放;如果收到 RST 響應(yīng),則表示端口關(guān)閉。這種掃描方式速度快,且不容易被目標(biāo)系統(tǒng)記錄,相對(duì)隱蔽,例如
nmap -sS 192.168.1.100
。 - -sT:TCP 連接掃描,通過完整的 TCP 三次握手來確定端口是否開放。這種掃描方式最準(zhǔn)確,但也最容易被檢測(cè)到,如
nmap -sT 192.168.1.100
。 - -sU:UDP 掃描,用于檢測(cè)目標(biāo)主機(jī)上的 UDP 端口是否開放。因?yàn)?UDP 是無連接協(xié)議,所以判斷端口狀態(tài)相對(duì)復(fù)雜,
nmap -sU 192.168.1.100
可對(duì)指定主機(jī)進(jìn)行 UDP 掃描。 - -sF、-sX、-sN:分別是 FIN 掃描、XMAS 掃描和 NULL 掃描。這些掃描方式通過發(fā)送特殊標(biāo)志位的 TCP 包來判斷端口狀態(tài),常用于繞過一些簡(jiǎn)單的防火墻檢測(cè)。
- -sS:TCP SYN 掃描,也稱為半開放掃描。它發(fā)送 SYN 包到目標(biāo)端口,如果收到 SYN/ACK 響應(yīng),就表示端口開放;如果收到 RST 響應(yīng),則表示端口關(guān)閉。這種掃描方式速度快,且不容易被目標(biāo)系統(tǒng)記錄,相對(duì)隱蔽,例如
端口指定參數(shù)
- -p :指定要掃描的端口范圍??梢允菃蝹€(gè)端口,如
-p 80
;也可以是多個(gè)端口,如-p 80,443,8080
;還可以是端口范圍,如-p 1-1000
表示掃描 1 到 1000 號(hào)端口。 - --top-ports :掃描最常用的指定數(shù)量的端口。例如,
nmap --top-ports 100 192.168.1.100
會(huì)掃描目標(biāo)主機(jī)上最常用的 100 個(gè)端口。 - -F:快速掃描模式,只掃描一些常見的端口,相當(dāng)于
-p 1-1024
加上一些其他常用端口。
- -p :指定要掃描的端口范圍??梢允菃蝹€(gè)端口,如
服務(wù)探測(cè)參數(shù)
- -sV:?jiǎn)⒂梅?wù)版本探測(cè),嘗試確定目標(biāo)主機(jī)上運(yùn)行的服務(wù)及其版本信息。例如,
nmap -sV 192.168.1.100
可以掃描出目標(biāo)主機(jī)開放端口上運(yùn)行的服務(wù)名稱和版本號(hào)。 - --version-intensity :設(shè)置服務(wù)版本探測(cè)的強(qiáng)度,級(jí)別越高,探測(cè)越全面,但耗時(shí)也越長(zhǎng),取值范圍是 0 到 9。
- -sV:?jiǎn)⒂梅?wù)版本探測(cè),嘗試確定目標(biāo)主機(jī)上運(yùn)行的服務(wù)及其版本信息。例如,
操作系統(tǒng)探測(cè)參數(shù)
- -O:?jiǎn)⒂貌僮飨到y(tǒng)探測(cè),嘗試識(shí)別目標(biāo)主機(jī)的操作系統(tǒng)類型和版本。如
nmap -O 192.168.1.100
。 - --osscan-limit:限制操作系統(tǒng)探測(cè)只對(duì)可能的目標(biāo)進(jìn)行,這樣可以加快掃描速度,但可能會(huì)降低準(zhǔn)確性。
- --osscan-guess:更積極地猜測(cè)操作系統(tǒng)類型,當(dāng) Nmap 不確定時(shí)會(huì)給出更寬泛的猜測(cè)結(jié)果。
- -O:?jiǎn)⒂貌僮飨到y(tǒng)探測(cè),嘗試識(shí)別目標(biāo)主機(jī)的操作系統(tǒng)類型和版本。如
輸出參數(shù)
- -oN :將掃描結(jié)果以正常格式保存到指定文件。例如,
nmap -oN scan_results.txt 192.168.1.100
會(huì)把掃描結(jié)果保存到scan_results.txt
文件中。 - -oX :將掃描結(jié)果以 XML 格式保存到指定文件,方便后續(xù)使用腳本或其他工具進(jìn)行解析和處理。
- -oG :將掃描結(jié)果以 Grep 格式保存,這種格式便于使用文本處理工具進(jìn)行分析。
- -oA :以多種格式(包括正常、XML 和 Grep 格式)保存掃描結(jié)果,文件名為指定的基本名稱加上相應(yīng)的擴(kuò)展名。
- -v:詳細(xì)輸出模式,顯示更多的掃描過程信息,如發(fā)送的數(shù)據(jù)包、收到的響應(yīng)等。使用多個(gè)
v
可以增加詳細(xì)程度,如-vv
、-vvv
。
- -oN :將掃描結(jié)果以正常格式保存到指定文件。例如,
這里給大家看一下改造后的代碼
/** * 使用 nmap4j 工具進(jìn)行掃描 * * @param ip 目標(biāo) ip * @param ports 目標(biāo)端口 * @return 端口信息列表 */ @RequestMapping("/querydb") public List<NmapPortInfo> querydb(@RequestParam(value = "ip") String ip, @RequestParam("ports") List<String> ports) { ArrayList<NmapPortInfo> portInfos = new ArrayList<>(); // 1.拼接端口 String portStr = StrUtil.join(",", ports); //2. 指定 nmap 路徑 String path = "D:/StudyApps/nmap"; String fileName = "temp_result.xml"; Nmap4j nmap4j = new Nmap4j(path); //3.讀取端口耗時(shí)較長(zhǎng),可以使用異步 CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { nmap4j.addFlags("-sV -p " + portStr + " -T5 -O -oX " + fileName); nmap4j.includeHosts(ip); try { nmap4j.execute(); } catch (Exception e) { throw new RuntimeException(e); } }, threadPoolExecutor); future.join(); //4. 獲取端口信息 return getPortInfo(portInfos, fileName); }
/** * 獲取 ip + 端口信息,封裝為集合返回前端 * * @param portInfos 返回前端集合 * @param fileName 臨時(shí)的 xml 文件 * @return 信息列表 */ @SneakyThrows private List<NmapPortInfo> getPortInfo(List<NmapPortInfo> portInfos, String fileName) { // 獲取項(xiàng)目所在路徑 String projectPath = System.getProperty("user.dir"); // 拼接文件路徑 String filePath = projectPath + FileUtil.FILE_SEPARATOR + fileName; log.info("文件路徑:{}", filePath); // nmap 返回 xml 格式固定,使用 dom4j 解析 SAXReader reader = new SAXReader(); org.dom4j.Document document = reader.read(FileUtil.file(filePath)); org.dom4j.Element rootElement = document.getRootElement(); org.dom4j.Element element = rootElement.element("host"); org.dom4j.Element xmlPorts = element.element("ports"); List<org.dom4j.Element> port = xmlPorts.elements("port"); for (org.dom4j.Element port1 : port) { Element service = port1.element("service"); String product = service.attributeValue("product"); String version = service.attributeValue("version"); NmapPortInfo nmapPortInfo = new NmapPortInfo(product, version); portInfos.add(nmapPortInfo); } // 刪除臨時(shí)文件 FileUtil.del(filePath); return portInfos; } }
我這里就是沒有去按照官網(wǎng)上的寫法,我的思路是文件已經(jīng)下載了我直接去讀取 xml 文件解決會(huì)更快,這里是使用 dom4j 來讀取的 xml 文件。代碼就這么多,最后請(qǐng)求是可以獲取到數(shù)據(jù)的:
總結(jié)
忘記和大家說了,nmap4j 在maven倉庫是搜不到的,所以只通過 jar 包(點(diǎn)擊下載)的方式來引入。
以上就是使用SpringBoot+nmap4j獲取端口信息的代碼詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot nmap4j獲取端口信息的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MyBatis中的SQL映射文件配置結(jié)果映射的操作指南
MyBatis?是一款優(yōu)秀的?ORM?框架,它提供了多種配置方式來定義?SQL?語句以及結(jié)果映射規(guī)則,本文將介紹?MyBatis?中的?SQL?映射文件如何配置結(jié)果映射,包括常規(guī)類型、集合類型等多種情況,需要的朋友可以參考下2023-07-07spring boot動(dòng)態(tài)加載Echart餅狀圖
這篇文章主要為大家詳細(xì)介紹了spring boot動(dòng)態(tài)加載Echart餅狀圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12Java之String字符串在JVM中的存儲(chǔ)及其內(nèi)存地址的問題
這篇文章主要介紹了Java之String字符串在JVM中的存儲(chǔ)及其內(nèi)存地址的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07簡(jiǎn)單講解Android開發(fā)中觸摸和點(diǎn)擊事件的相關(guān)編程方法
這篇文章主要介紹了Android開發(fā)中觸摸和點(diǎn)擊事件的相關(guān)編程方法,包括事件偵聽器等安卓開發(fā)中常用的接口的基本使用方法,需要的朋友可以參考下2015-12-12Spring動(dòng)態(tài)代理實(shí)現(xiàn)日志功能詳解
這篇文章主要為大家詳細(xì)介紹了Spring動(dòng)態(tài)代理實(shí)現(xiàn)日志功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08Jenkins中自動(dòng)化部署Spring?Boot項(xiàng)目的全過程
這篇文章主要介紹了如何使用Jenkins從Git倉庫拉取SpringBoot項(xiàng)目并進(jìn)行自動(dòng)化部署,通過配置Jenkins任務(wù),實(shí)現(xiàn)項(xiàng)目的構(gòu)建、鏡像構(gòu)建和容器運(yùn)行,確保項(xiàng)目在更新時(shí)自動(dòng)部署,需要的朋友可以參考下2025-01-01mybatis-plus 實(shí)現(xiàn)分頁查詢的示例代碼
本文介紹了在MyBatis-Plus中實(shí)現(xiàn)分頁查詢,包括引入依賴、配置分頁插件、使用分頁查詢以及在控制器中調(diào)用分頁查詢的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11