Java笔记-Java端口扫描功能(含TCP包分析以及原理)

118 篇文章 4 订阅
47 篇文章 38 订阅

端口扫描主要是扫描其TCP端口。因为他有三次握手,握上了,如果有加密才进行传输层的加密。

写个程序,去连接那个端口,能握手,就说明端口是开着的。

 

关于UDP的端口扫描,有但意义不是很大,因为udp不会面向连接的。主要看服务端会不会回包,以及使用了什么协议如DTLS,如果服务端写成,客户端发送过来的数据异常,就回个异常的,这样就能扫描到,如果没写成这样,那就没办法了。

 

Java代码如下:

public class PortScanJava {

    public boolean isPortOpen(String address, Integer port){

        boolean ret = false;
        try{

            Socket socket = new Socket();
            socket.bind(new InetSocketAddress(8888));
            socket.connect(new InetSocketAddress(address, port), 1000);
            socket.close();
            ret = true;
        }
        catch (Exception e){

            e.printStackTrace();
        }

        return ret;
    }
}

这里把端口固定为8888是为了抓包的方便。

调用如下:

boolean portOpen = portScanComponent.isPortOpen("www.baidu.com", 80);
System.out.println(portOpen);

程序运行截图如下:

抓到的包是这样的:

端口状态是这样的:

这样就有点问题了,可见他的四次分手,客户端只发出FIN包,就没有下文了,服务端没有发送ACK,让其进入FIN_WAIT2状态,并且握手的时候

这里再此出深究是哪个的问题了。先来看下TCP三次握手,当TCB把TCP都建立起来后,客户端发送标志位为SYN的包给服务端,服务端接收到后会回SYN和ACK的包,这里不知道是什么原因没有抓到,可能是我过滤得有问题,但是可以肯定,客户端一定是收到了,不然客户端不会会ACK的包给服务端,分手就是发FIN。

这里来看下完整的流程:

用的是QNetworkAccessManager,后端是用SpringBoot搭建的。可见其完整的流程。

public static JFrame main=new JFrame("JAVA端口扫描器"); //显示扫描结果 public static JTextArea Result=new JTextArea("",4,40); //滚动条面板 public static JScrollPane resultPane = new JScrollPane(Result,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); //输入主机名文本框 public static JTextField hostname=new JTextField("localhost",8); //输入ip地址前3位的输入框 public static JTextField fromip1=new JTextField("0",3); //输入ip地址4~6位的输入框 public static JTextField fromip2=new JTextField("0",3); //输入ip地址7~9位的输入框 public static JTextField fromip3=new JTextField("0",3); //输入起始ip地址最后4位的输入框 public static JTextField fromip4=new JTextField("0",3); //输入目标ip地址最后4位的输入框 public static JTextField toip=new JTextField("0",3); //输入最小端口的输入框 public static JTextField minPort=new JTextField("0",4); //输入最大端口的输入框 public static JTextField maxPort=new JTextField("1000",4); //输入最大线程数量的输入框 public static JTextField maxThread=new JTextField("100",3); //错误提示框 public static JDialog DLGError=new JDialog(main,"错误!"); public static JLabel DLGINFO=new JLabel(""); public static JLabel type=new JLabel("请选择:"); //扫描型 public static JRadioButton radioIp = new JRadioButton("IP地址:"); public static JRadioButton radioHost = new JRadioButton("主机名:",true); //单选框组 public static ButtonGroup group = new ButtonGroup(); public static JLabel P1=new JLabel("端口范围:"); public static JLabel P2=new JLabel("~"); public static JLabel P3=new JLabel("~"); public static JLabel Pdot1 = new JLabel("."); public static JLabel Pdot2 = new JLabel("."); public static JLabel Pdot3 = new JLabel("."); public static JLabel TNUM=new JLabel("线程数:"); public static JLabel RST=new JLabel("扫描结果: "); public static JLabel con=new JLabel(" "); //定义按钮 public static JButton OK = new JButton("确定"); public static JButton Submit = new JButton("开始扫描"); public static JButton Cancel = new JButton("退出"); public static JButton saveButton = new JButton("保存扫描结果"); //菜单栏 public static JMenuBar myBar = new JMenuBar(); public static JMenu myMenu = new JMenu("文件(F)"); public static JMenuItem saveItem = new JMenuItem("保存扫描结果(S)"); public static JMenuItem exitItem = new JMenuItem("退出(Q)"); public static JMenu myMenu2 = new JMenu("帮助"); public static JMenuItem helpItem = new JMenuItem("阅读"); public static void main(String[] args){ main.setSize(500,400); main.setLocation(300,300); main.setResizable(false); main.setLayout(new GridBagLayout()); main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); DLGError.setSize(300,100); DLGError.setLocation(400,400); //添加“菜单栏” myMenu.add(saveItem); myMenu.add(exitItem); myMenu2.add(helpItem); myBar.add(myMenu); myBar.add(myMenu2); main.setJMenuBar(myBar); //设置热键 myMenu.setMnemonic('F'); saveItem.setMnemonic ('S'); //为“另存为”组件设置快捷键为ctrl+s saveItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_S,InputEvent.CTRL_MASK)); exitItem.setMnemonic('Q'); exitItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_E,InputEvent.CTRL_MASK)); //采用表格型布局 Container mPanel = main.getContentPane(); GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(10,0,0,10); c.gridx = 0; c.gridy = 0; c.gridwidth = 10; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(type,c); group.add(radioIp); group.add(radioHost); c.gridx = 0; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(radioIp,c); c.gridx = 1; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(fromip1,c); c.gridx = 2; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(Pdot1,c); c.gridx = 3; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(fromip2,c); c.gridx = 4; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(Pdot2,c); c.gridx = 5; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(fromip3,c); c.gridx = 6; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(Pdot3,c); c.gridx = 7; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(fromip4,c); c.gridx = 8; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(P2,c); c.gridx = 9; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(toip,c); c.gridx = 0; c.gridy = 2; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(radioHost,c); c.gridx = 1; c.gridy = 2; c.gridwidth = 3; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(hostname,c); c.gridx = 0; c.gridy = 3; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(P1,c); c.gridx = 1; c.gridy = 3; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(minPort,c); c.gridx = 2; c.gridy = 3; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(P3,c); c.gridx = 3; c.gridy = 3; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(maxPort,c); c.gridx = 0; c.gridy = 4; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(TNUM,c); c.gridx = 1; c.gridy = 4; c.gridwidth = 3; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(maxThread,c);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值