网易首页 > 网易号 > 正文 申请入驻

高效端口扫描:SpringBoot + nmap4j 获取端口神器!

0
分享至

Java精选面试题(微信小程序):5000+道面试题和选择题,真实面经简历模版,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计、大厂真题等,在线随时刷题!

序言

今天在工作的时候,领导突然安排和我说一个需求,就是根据一个 ip 和 端口去获取对应服务上对应端口的信息,当时主要是为了确定数据库的版本和型号,比如 MySQL、Oracle 这些数据库,我后面尝试发现其他端口也可以获取信息。

这个在公司里之前是通过 python 来写的,python 里面刚好有这个模块,但是 Java 没有,所以写这篇文章记录一下,帮助大家以后避免踩坑。

代码已经提交到了我的GitHub:

https://github.com/maoshengyzx/SpringBoot

nmap4j

nmap4j 是一个用于 Java 语言的 Nmap 端口扫描器的包装库,它允许 Java 开发者在自己的项目中方便地调用 Nmap 的功能进行网络扫描和探测。

GitHub地址:

https://github.com/narkisr/nmap4j

在运行这个代码之前,我们是需要下载 nmap 的可执行文件,地址为:

https://nmap.org/download.html#windows

这里下载第一个,下载后安装就行了。

代码说明

接下来和大家说一下 nmap4j 中的测试代码,这里面有个坑,我当时找了好久,代码在test/org/nmap4j/Nmap4jTest.java

publicclassNmap4jTest{ @Test publicvoidbasicNmap4jUsageTest(){ 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() ;  // 这一行一定要注释掉,不然会一直报错     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() ;   }  } }
参数说明:

目标选择参数:

  • -iL从文件中读取扫描目标列表。例如,nmap -iL targets.txt,会从targets.txt文件中读取每行一个的 IP 地址或域名作为扫描目标。

  • -iR随机选择指定数量的主机进行扫描。如nmap -iR 100,会随机选取 100 个主机进行扫描。

  • --exclude 排除指定的主机或网络不进行扫描。例如,nmap 192.168.1.0/24 --exclude 192.168.1.100,192.168.1.200,将扫描192.168.1.0/24网段,但排除192.168.1.100192.168.1.200这两台主机。

  • --excludefile 从文件中读取要排除的主机或网络列表。

扫描类型参数:

  • -sSTCP SYN 扫描,也称为半开放扫描。它发送 SYN 包到目标端口,如果收到SYN/ACK响应,就表示端口开放;如果收到 RST 响应,则表示端口关闭。这种扫描方式速度快,且不容易被目标系统记录,相对隐蔽,例如nmap -sS 192.168.1.100

  • -sTTCP 连接扫描,通过完整的 TCP 三次握手来确定端口是否开放。这种扫描方式最准确,但也最容易被检测到,如nmap -sT 192.168.1.100

  • -sUUDP 扫描,用于检测目标主机上的 UDP 端口是否开放。因为 UDP 是无连接协议,所以判断端口状态相对复杂,nmap -sU 192.168.1.100可对指定主机进行 UDP 扫描。

  • -sF、-sX、-sN分别是 FIN 扫描、XMAS 扫描和 NULL 扫描。这些扫描方式通过发送特殊标志位的 TCP 包来判断端口状态,常用于绕过一些简单的防火墙检测。

端口指定参数:

  • -p指定要扫描的端口范围。可以是单个端口,如-p 80;也可以是多个端口,如-p 80,443,8080;还可以是端口范围,如-p 1-1000表示扫描 1 到 1000 号端口。

  • --top-ports扫描最常用的指定数量的端口。例如,nmap --top-ports 100 192.168.1.100会扫描目标主机上最常用的 100 个端口。

  • -F快速扫描模式,只扫描一些常见的端口,相当于-p 1-1024加上一些其他常用端口。

服务探测参数:

  • -sV启用服务版本探测,尝试确定目标主机上运行的服务及其版本信息。例如,nmap -sV 192.168.1.100可以扫描出目标主机开放端口上运行的服务名称和版本号。

  • --version-intensity设置服务版本探测的强度,级别越高,探测越全面,但耗时也越长,取值范围是 0 到 9。

操作系统探测参数:

  • -O启用操作系统探测,尝试识别目标主机的操作系统类型和版本。如nmap -O 192.168.1.100

  • --osscan-limit限制操作系统探测只对可能的目标进行,这样可以加快扫描速度,但可能会降低准确性。

  • --osscan-guess更积极地猜测操作系统类型,当 Nmap 不确定时会给出更宽泛的猜测结果。

输出参数:

  • -oN将扫描结果以正常格式保存到指定文件。例如,nmap -oN scan_results.txt 192.168.1.100会把扫描结果保存到scan_results.txt文件中。

  • -oX将扫描结果以 XML 格式保存到指定文件,方便后续使用脚本或其他工具进行解析和处理。

  • -oG将扫描结果以 Grep 格式保存,这种格式便于使用文本处理工具进行分析。

  • -oA以多种格式(包括正常、XML 和 Grep 格式)保存扫描结果,文件名为指定的基本名称加上相应的扩展名。

  • -v详细输出模式,显示更多的扫描过程信息,如发送的数据包、收到的响应等。使用多个v可以增加详细程度,如-vv-vvv

这里给大家看一下改造后的代码:

/**  * 使用 nmap4j 工具进行扫描  *  * @param ip    目标 ip  * @param ports 目标端口  * @return 端口信息列表  */ @RequestMapping("/querydb") public List   querydb(@RequestParam(value = "ip") String ip, @RequestParam("ports") List ports)  {     ArrayList 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.读取端口耗时较长,可以使用异步     CompletableFuture future = CompletableFuture.runAsync(() -> {         nmap4j.addFlags("-sV -p " + portStr + " -T5 -O -oX " + fileName);         nmap4j.includeHosts(ip);         try {             nmap4j.execute();         } catch (Exception e) {             thrownew RuntimeException(e);         }     }, threadPoolExecutor);     future.join();     //4. 获取端口信息     return getPortInfo(portInfos, fileName); }

/**      * 获取 ip + 端口信息,封装为集合返回前端      *      * @param portInfos 返回前端集合      * @param fileName  临时的 xml 文件      * @return 信息列表      */     @SneakyThrows     private List   getPortInfo(List portInfos, String fileName) {         // 获取项目所在路径         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 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);         }         // 删除临时文件         FileUtil.del(filePath);         return portInfos;     } }

我这里就是没有去按照官网上的写法,我的思路是文件已经下载了我直接去读取 xml 文件解决会更快,这里是使用 dom4j 来读取的 xml 文件。代码就这么多,最后请求是可以获取到数据的:

补充

由于这段代码是在windows上运行的,而在实际的环境中项目都会部署到 Linux 环境汇总,所以我不得不在 Linux 上去运行调试这段代码。代码如下:

/**  * 使用 nmap4j 工具进行扫描, linux系统  *  * @param ip    目标 ip  * @param ports 目标端口  * @return 端口信息列表  */ @GetMapping("/linux/querydb") @SneakyThrows public List   linuxQuerydb(@RequestParam(value = "ip") String ip, @RequestParam("ports") List ports)  {     ArrayList portInfos =  new ArrayList<>();     // 1.拼接端口     String portStr = StrUtil.join(",", ports);     String fileName = "temp_result.xml";     //2. linux namp 命令     String nmapCommand = "nmap -sV -p " + portStr + " -T5 -O -oX " + fileName + " " + ip;     //3. 读取端口耗时较长,可以使用异步     CompletableFuture future = CompletableFuture.runAsync(() -> {         Process nampProcess = null;         try {             // 3. 运行命令             nampProcess = Runtime.getRuntime().exec(nmapCommand);             // 4. 等待命令执行完成             nampProcess.waitFor();         } catch (Exception e) {             thrownew RuntimeException(e);         }     }, threadPoolExecutor);     future.join();     // 5. 获取端口信息     return getPortInfo(portInfos, fileName); }

这里的初步思路是直接调用 Linux 的命令执行 nmap (Linux系统中必须下载 nmap)。至于下载这里就不多说了,大家只需要注意下载的版本最好也为 7.95,其他版本下载的 xml 文件有问题,无法解析。

总结

忘记和大家说了,nmap4j 在maven仓库是搜不到的,所以只通过 jar 包的方式来引入,地址为:

https://master.dl.sourceforge.net/project/nmap4j/1.1.0/org.nmap4j-1.1.0-RELEASE.zip?viasf=1

作者:发愤图强的羔羊

来源:https://juejin.cn/post/7458189303063035958

公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!

文章有帮助的话,点在看,转发吧!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
张康阳现状证明,不怕富二代躺平就怕有野心,仅5年千亿身价归零

张康阳现状证明,不怕富二代躺平就怕有野心,仅5年千亿身价归零

以茶带书
2026-03-19 17:34:09
暴跌93%,理想失控了!

暴跌93%,理想失控了!

财经三分钟pro
2026-03-18 19:04:41
为什么只有革命卫队与美以干,而伊朗40万国防军沉默观战?

为什么只有革命卫队与美以干,而伊朗40万国防军沉默观战?

廖保平
2026-03-17 09:04:38
首款进口乙肝治愈新药,最快年底上市

首款进口乙肝治愈新药,最快年底上市

药圈观察局
2026-03-18 15:08:35
逃到亚兹德也没用!伊朗最后两架C-130被摧毁

逃到亚兹德也没用!伊朗最后两架C-130被摧毁

老马拉车莫少装
2026-03-19 19:00:31
对中国来说,古巴就像一场持续了67年的社会试验

对中国来说,古巴就像一场持续了67年的社会试验

刘润
2026-03-19 08:37:39
网红日料创始人道歉!广州太古汇店监控画面公开

网红日料创始人道歉!广州太古汇店监控画面公开

南方都市报
2026-03-19 17:11:06
一图看懂|为何美军害怕伊朗布设水雷?

一图看懂|为何美军害怕伊朗布设水雷?

澎湃新闻
2026-03-14 07:32:27
有网民在互联网平台发布“大量特警在重庆九龙坡合信石大酒店抓人”,当地辟谣

有网民在互联网平台发布“大量特警在重庆九龙坡合信石大酒店抓人”,当地辟谣

环球网资讯
2026-03-19 13:10:17
4000万欧打水漂?大巴黎壕无人性,抛弃世一门又无视身价最贵门将

4000万欧打水漂?大巴黎壕无人性,抛弃世一门又无视身价最贵门将

体坛老球迷
2026-03-19 11:10:38
张兰不同意在台北置业,马筱梅宣布孩子与母姓,她到底有多离谱

张兰不同意在台北置业,马筱梅宣布孩子与母姓,她到底有多离谱

小俎娱乐
2026-03-20 03:22:47
距亚洲纪录只差0.14秒!张展硕200自强势摘金,潘展乐无缘领奖台

距亚洲纪录只差0.14秒!张展硕200自强势摘金,潘展乐无缘领奖台

全景体育V
2026-03-19 19:19:22
女子赴发小婚礼穿瑜伽裤,打扮过于火辣,网友直呼跟没穿似的

女子赴发小婚礼穿瑜伽裤,打扮过于火辣,网友直呼跟没穿似的

一盅情怀
2026-03-16 17:28:45
阎王爷点破真相:烧纸时烟往身上飘,那不是风吹的!是亡者提醒你

阎王爷点破真相:烧纸时烟往身上飘,那不是风吹的!是亡者提醒你

混沌录
2026-03-18 23:44:16
华为,要拿小米磨刀?

华为,要拿小米磨刀?

ZAKER新闻
2026-03-19 12:21:52
3.20日早评|重磅公布!央行大消息!A股有救了?

3.20日早评|重磅公布!央行大消息!A股有救了?

龙行天下虎
2026-03-20 04:06:10
纽约期金突破4660美元/盎司,日内涨1.18%

纽约期金突破4660美元/盎司,日内涨1.18%

每日经济新闻
2026-03-20 06:09:04
沙特、卡塔尔,遇袭!战火点燃化工品;白宫“改口”了!美联储:不确定性上升

沙特、卡塔尔,遇袭!战火点燃化工品;白宫“改口”了!美联储:不确定性上升

金融界
2026-03-19 08:36:10
斩首高层对改变伊朗政权有用吗?有!

斩首高层对改变伊朗政权有用吗?有!

黔有虎
2026-03-19 16:12:54
中央下令严查宅基地!2026年新规执行 每家每户都要注意

中央下令严查宅基地!2026年新规执行 每家每户都要注意

三农雷哥
2026-03-18 19:10:57
2026-03-20 06:55:00
Java精选
Java精选
一场永远也演不完的戏
1778文章数 3859关注度
往期回顾 全部

科技要闻

小米新一代SU7上市,售价21.99万

头条要闻

美军一架F-35战机疑似被伊朗火力击中后紧急降落

头条要闻

美军一架F-35战机疑似被伊朗火力击中后紧急降落

体育要闻

他们专卖“老头鞋”,却能签下19岁NBA未来门面?

娱乐要闻

胡歌初恋回应曝光书信 否认用爆料赚钱

财经要闻

伊朗战争会是"美国金融危机"导火索吗?

汽车要闻

不到10万还有激光雷达 零跑A10体验超预期

态度原创

亲子
游戏
教育
时尚
本地

亲子要闻

尿道下裂

《GTA6》价格定调了!CEO暗示70到80美元

教育要闻

2025年高校撤销专业TOP15公布,给高考志愿提了个醒

边生活,边艺术:LEDIN「智趣千金」的灵感手记

本地新闻

春色满城关不住|绍兴春日顶流,这片樱花海藏不住了

无障碍浏览 进入关怀版