java使用nmap工具进行端口扫描,简单学习

本文介绍了如何在Java中整合Nmap进行端口扫描。提供了两种方法,一种是使用nmap4j库,另一种是直接调用Runtime执行Nmap命令。代码示例展示了如何通过Nmap4j执行扫描并解析输出结果,以及如何通过Runtime执行Nmap命令并读取返回的XML数据进行解析。在实际应用中,作者发现直接调用Runtime执行Nmap命令的方式在效率上优于使用nmap4j库。
摘要由CSDN通过智能技术生成

java与nmap整合我目前使用过两种方式,可以参考一下:
1.导入nmap4j.jar的包,在src同级目录创建lib文件夹,把jar包放入然后右键->add as Library;
2.通过Java调用Runtime这个类可以执行其他的可执行程序;
这两种方法有一个相同的地方就是需要调用nmap的程序。为了方便我们可以把程序导入项目中,在通过相对路径进行引用即可。
官网链接https://nmap.org/download.html
下载nmap-X.XX-win32.zip这种以zip结尾的压缩包,解压出来就行了
目录结构如图:
在这里插入图片描述
第一种写法:使用nmap4j ,需要导入jar包,这里把连接放上
链接: https://pan.baidu.com/s/1qx9gHyzBrRFqnoM1wH_eHw
提取码:cart
贴上代码:

public void getResult(String param){
        //创建对象与nmap建立连接,相对路径
        Nmap4j nmap4j = new Nmap4j( "doc/nmap-7.91" ) ;
        //需要扫描的主机ip,可查询范围192.168.1.1-255
        nmap4j.includeHosts(param);
        //不需要扫描的主机范围
        //nmap4j.excludeHosts("192.168.1.1-246");
        //扫描规则
        nmap4j.addFlags( "-T3 -Pn -sV -v") ;
        try {
            nmap4j.execute();
            ExecutionResults executionResults = nmap4j.getExecutionResults();
            if( !nmap4j.hasError() ) {
                //输出扫描结果
                System.out.println(executionResults.getOutput());
            } else {
                System.out.println( executionResults.getErrors() ) ;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

这段代码的意思在注释中已经解释了,但是我遇到了问题,就是同样的执行命令通过命令行窗口运行比代码运行快,而且大多数时候代码运行一直没反应,不知道是不是阻塞了,网上有大神对jar包进行了修改,但是还是解决不了我的问题,所有我用的是第二种方法。
第二种写法:不使用nmap4j
在Java中通过调用Runtime类执行其他的可执行程序,执行后返回一个进程(Process),利用Process这个类我们可以取得程序执行的结果(一个String类型的xml),把结果解析成document然后获取节点就能得到我们需要的信息。
贴上代码:

@Component
public class NmapScan {

    private static Logger log = LoggerFactory.getLogger(NmapScan.class);

    private static String command;

    @Value("${nmap.command}")
    public void setCommand(String command){
        NmapScan.command = command;
    }

    public static List<Map<String,Object>> getResult(String ip){
        //创建空集合存筛选的结果
        List<Map<String,Object>> portList = new ArrayList<>();
        String returnData = getReturnData(ip);
        try{
            if(!StringUtils.isEmpty(returnData)){
                //解析String类型的xml
                Document xmldoc = DocumentHelper.parseText(returnData);
                //得到根节点
                Element rootEl = xmldoc.getRootElement();
                if(rootEl != null){
                    Element addrEl = rootEl.element("host").element("address");
                    if(addrEl != null){
                        //扫描到的ip
                        String scanIp = addrEl.attributeValue("addr");
                        if(scanIp.equals(ip)){
                            log.info("ip匹配成功,开始解析...");
                            //ip类型
                            String ipType = StringUtils.isEmpty(addrEl.attributeValue("addrtype"))?"":"地址:"+addrEl.attributeValue("addrtype")+" ";
                            //获取所有子节点的跟节点,xpath
                            List<Element> ports = rootEl.selectNodes("//ports/port");
                            if(ports.size()>0){
                                for(Element el:ports){
                                    Map<String,Object> portMap = new HashMap<>();
                                    //协议
                                    String agreement = el.attributeValue("protocol");
                                    //端口号
                                    String port = el.attributeValue("portid");

                                    Element stateEl = el.element("state");
                                    //状态
                                    String state = StringUtils.isEmpty(stateEl.attributeValue("state"))?"":"状态:"+stateEl.attributeValue("state")+" ";
                                    //reason
                                    String reason = StringUtils.isEmpty(stateEl.attributeValue("reason"))?"":"reason:"+stateEl.attributeValue("reason")+" ";
                                    //reason_ttl
                                    String reasonTTL = StringUtils.isEmpty(stateEl.attributeValue("reason_ttl"))?"":"reason_ttl:"+stateEl.attributeValue("reason_ttl")+" ";

                                    Element serviceEl = el.element("service");
                                    //服务名
                                    String servicename = StringUtils.isEmpty(serviceEl.attributeValue("name"))?"":"服务名:"+serviceEl.attributeValue("name")+" ";
                                    //product
                                    String product = StringUtils.isEmpty(serviceEl.attributeValue("product"))?"":"product:"+serviceEl.attributeValue("product")+" ";
                                    //操作系统
                                    String ostype = StringUtils.isEmpty(serviceEl.attributeValue("ostype"))?"":"操作系统:"+serviceEl.attributeValue("ostype")+" ";
                                    //主机名
                                    String hostname = StringUtils.isEmpty(serviceEl.attributeValue("hostname"))?"":"主机名:"+serviceEl.attributeValue("hostname")+" ";
                                    //附加信息
                                    String extrainfo = StringUtils.isEmpty(serviceEl.attributeValue("extrainfo"))?"":"附加信息:"+serviceEl.attributeValue("extrainfo")+" ";
                                    portMap.put("id", UUIDUtil.getUUID());
                                    portMap.put("ip",ip);
                                    portMap.put("wcode","12");
                                    portMap.put("website","Nmap扫描工具");
                                    portMap.put("port",port);
                                    portMap.put("agreement",agreement);
                                    String other = hostname + ostype + state + ipType + servicename + extrainfo + product + reason + reasonTTL;
                                    portMap.put("other",other);
                                    portList.add(portMap);
                                }
                                log.info("解析数据成功...");
                            }
                        }
                    }

                }else {
                    log.info("解析数据为空...");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.info("解析nmap数据失败...");
        }
        return portList;
    }

    /**
     * 调用nmap进行扫描
     * @return 执行回显
     * */
    public static String getReturnData(String ip){
        Process process = null;
        StringBuffer stringBuffer = new StringBuffer();
        try {
            process = Runtime.getRuntime().exec( "doc/nmap-7.91/nmap.exe " + command+" "+ip);
            log.info("开始对{}进行端口扫描...",ip);
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(),"UTF-8"));
            String line = null;
            while((line = reader.readLine()) != null){
                stringBuffer.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuffer.toString();
    }
}

代码仅供参考
参考博客:
https://blog.csdn.net/weixin_33834628/article/details/89986357
https://blog.csdn.net/weixin_34302798/article/details/92217281

nmap是一个网络连接端扫描软件,用来扫描网上电脑开放的网络连接端。确定哪些服务运行在哪些连接端,并且推断计算机运行哪个操作系统(这是亦称 fingerprinting)。它是网络管理员必用的软件之一,以及用以评估网络系统安全。 正如大多数被用于网络安全的工具nmap 也是不少黑客及骇客(又称脚本小子)爱用的工具 。系统管理员可以利用nmap来探测工作环境中未经批准使用的服务器,但是黑客会利用nmap来搜集目标电脑的网络设定,从而计划攻击的方法。 Nmap 常被跟评估系统漏洞软件Nessus 混为一谈。Nmap 以隐秘的手法,避开闯入检测系统的监视,并尽可能不影响目标系统的日常操作。 其基本功能有三个,一是探测一组主机是否在线;其次是扫描 主机端口,嗅探所提供的网络服务;还可以推断主机所用的操作系统 。Nmap可用于扫描仅有两个节点的LAN,直至500个节点以上的网络。Nmap 还允许用户定制扫描技巧。通常,一个简单使用ICMP协议的ping操作可以满足一般需求;也可以深入探测UDP或者TCP端口,直至主机所 使用的操作系统;还可以将所有探测结果记录到各种格式的日志中, 供进一步分析操作。 进行ping扫描,打印出对扫描做出响应的主机,不做进一步测试(如端口扫描或者操作系统探测): nmap -sP 192.168.1.0/24 仅列出指定网络上的每台主机,不发送任何报文到目标主机: nmap -sL 192.168.1.0/24 探测目标主机开放的端口,可以指定一个以逗号分隔的端口列表(如-PS22,23,25,80): nmap -PS 192.168.1.234 使用UDP ping探测主机: nmap -PU 192.168.1.0/24 使用频率最高的扫描选项:SYN扫描,又称为半开放扫描,它不打开一个完全的TCP连接,执行得很快: nmap -sS 192.168.1.0/24 当SYN扫描不能用时,TCP Connect()扫描就是默认的TCP扫描: nmap -sT 192.168.1.0/24 UDP扫描用-sU选项,UDP扫描发送空的(没有数据)UDP报头到每个目标端口: nmap -sU 192.168.1.0/24 确定目标机支持哪些IP协议 (TCP,ICMP,IGMP等): nmap -sO 192.168.1.19 探测目标主机的操作系统: nmap -O 192.168.1.19 nmap -A 192.168.1.19 另外,nmap官方文档中的例子: nmap -v scanme. 这个选项扫描主机scanme中 所有的保留TCP端口。选项-v启用细节模式。 nmap -sS -O scanme./24 进行秘密SYN扫描,对象为主机Saznme所在的“C类”网段 的255台主机。同时尝试确定每台工作主机的操作系统类型。因为进行SYN扫描 和操作系统检测,这个扫描需要有根权限。 nmap -sV -p 22,53,110,143,4564 198.116.0-255.1-127 进行主机列举和TCP扫描,对象为B类188.116网段中255个8位子网。这 个测试用于确定系统是否运行了sshd、DNS、imapd或4564端口。如果这些端口 打开,将使用版本检测来确定哪种应用在运行。 nmap -v -iR 100000 -P0 -p 80 随机选择100000台主机扫描是否运行Web服务器(80端口)。由起始阶段 发送探测报文来确定主机是否工作非常浪费时间,而且只需探测主机的一个端口,因 此使用-P0禁止对主机列表。 nmap -P0 -p80 -oX logs/pb-port80scan.xml -oG logs/pb-port80scan.gnmap 216.163.128.20/20 扫描4096个IP地址,查找Web服务器(不ping),将结果以Grep和XML格式保存。 host -l | cut -d -f 4 | nmap -v -iL - 进行DNS区域传输,以发现中的主机,然后将IP地址提供给 Nmap。上述命令用于GNU/Linux -- 其它系统进行区域传输时有不同的命令。 其他选项: -p (只扫描指定的端口) 单个端口和用连字符表示的端口范 围(如 1-1023)都可以。当既扫描TCP端口又扫描UDP端口时,可以通过在端口号前加上T: 或者U:指定协议。 协议限定符一直有效直到指定另一个。 例如,参数 -p U:53,111,137,T:21-25,80,139,8080 将扫描UDP 端口53,111,和137,同时扫描列出的TCP端口。 -F (快速 (有限的端口) 扫描)
Java可以通过调用命令行实现使用nmap扫描一个网段的端口是否存在于MySQL数据库中。以下是一个简单的实现示例: ``` import java.io.BufferedReader; import java.io.InputStreamReader; public class NmapScanner { public static void main(String[] args) { String ipRange = "192.168.0.0/24"; try { Process process = Runtime.getRuntime().exec("nmap -p 1-65535 -oG - " + ipRange); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { if (line.startsWith("Host: ")) { String ipAddress = line.substring("Host: ".length(), line.indexOf(" ")); String[] ports = line.substring(line.indexOf(":")+1).split(","); for (String port : ports) { if (port.contains("open")) { if (isPortInDatabase(ipAddress, port)) { System.out.println("Port " + port + " is open and exists in database."); } else { System.out.println("Port " + port + " is open but does not exist in database."); } } } } } } catch (Exception e) { e.printStackTrace(); } } private static boolean isPortInDatabase(String ipAddress, String port) { boolean result = false; // TODO: Implement database query to check if the port exists in MySQL database. return result; } } ``` 在上面的示例中,使用 Runtime 类的 exec() 方法调用命令行,执行 nmap 命令来扫描指定 IP 地址范围内的所有端口。然后,使用 BufferedReader 读取命令输出的结果,并解析端口状态。如果端口状态为“open”,则调用 isPortInDatabase() 方法来检查该端口是否存在于 MySQL 数据库中。 需要注意的是,在使用 nmap 扫描工具时,应该遵守相关法律法规和道德规范,不要进行未经授权的扫描行为。同时,在实际应用中,需要根据实际情况对代码进行修改和优化。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值