java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot nmap4j获取端口信息

使用SpringBoot+nmap4j获取端口信息的代码详解

作者:发愤图强的羔羊

这篇文章主要介绍了使用 SpringBoot + nmap4j 获取端口信息,包括需求背景、nmap4j 的相关介绍、代码说明(含测试代码、改造后的代码及参数说明),还提到了文件读取方式和依赖引入方式,最终请求能获取到数据,需要的朋友可以参考下

序言

今天在工作的时候,领导突然安排和我说一个需求,就是根据一个 ip 和 端口去获取对应服务上对应端口的信息,当时主要是为了确定数据库的版本和型号,比如 MySQL、Oracle 这些数据库,我后面尝试发现其他端口也可以获取信息。这个在公司里之前是通过 python 来写的,python 里面刚好有这个模块,但是 Java 没有,所以写这篇文章记录一下,帮助大家以后避免踩坑。

nmap4j

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

在运行这个代码之前,我们是需要下载 nmap 的可执行文件,地址为:Download the Free Nmap Security Scanner for Linux/Mac/Windows

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

代码说明

接下来和大家说一下 nmap4j 中的测试代码,这里面有个坑,我当时找了好久,代码在 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() ;  // 这一行一定要注释掉,不然会一直报错
				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() ;
		}
		
	}

}

参数说明:

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

/**
 * 使用 nmap4j 工具进行扫描
 *
 * @param ip    目标 ip
 * @param ports 目标端口
 * @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.读取端口耗时较长,可以使用异步
    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  临时的 xml 文件
     * @return 信息列表
     */
    @SneakyThrows
    private List<NmapPortInfo> getPortInfo(List<NmapPortInfo> 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<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);
        }

        // 删除临时文件
        FileUtil.del(filePath);
        return portInfos;
    }
}

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

总结

忘记和大家说了,nmap4j 在maven仓库是搜不到的,所以只通过 jar 包(点击下载)的方式来引入。

以上就是使用SpringBoot+nmap4j获取端口信息的代码详解的详细内容,更多关于SpringBoot nmap4j获取端口信息的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文