`
zpball
  • 浏览: 916614 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

端口扫描原理,(java)UDP端口扫描

阅读更多
一个端口就是一个潜在的通信通道,也就是一个入侵通道。对目标计算机进行端口扫描,能得到许多有用的信息。进行扫描的方法很多,可以是手工进行扫描,也可以用端口扫描软件进行。

在手工进行扫描时,需要熟悉各种命令。对命令执行后的输出进行分析。用扫描软件进行扫描时,许多扫描器软件都有分析数据的功能。

通过端口扫描,可以得到许多有用的信息,从而发现系统的安全漏洞。

什么是扫描器

扫描器是一种自动检测远程或本地主机安全性弱点的程序,通过使用扫描器你可一不留痕迹的发现远程服务器的各种TCP端口的分配及提供的服务和它们的软件版本!这就能让我们间接的或直观的了解到远程主机所存在的安全问题。

工作原理

扫描器通过选用远程TCP/IP不同的端口的服务,并记录目标给予的回答,通过这种方法,可以搜集到很多关于目标主机的各种有用的信息(比如:是否能用匿名登陆!是否有可写的FTP目录,是否能用TELNET,HTTPD是用ROOT还是nobady在跑!)

扫描器能干什么

扫描器并不是一个直接的攻击网络漏洞的程序,它仅仅能帮助我们发现目标机的某些内在的弱点。一个好的扫描器能对它得到的数据进行分析,帮助我们查找目标主机的漏洞。但它不会提供进入一个系统的详细步骤。

扫描器应该有三项功能:发现一个主机或网络的能力;一旦发现一台主机,有发现什么服务正运行在这台主机上的能力;通过测试这些服务,发现漏洞的能力。

编写扫描器程序必须要很多TCP/IP程序编写和C, Perl和或SHELL语言的知识。需要一些Socket编程的背景,一种在开发客户/服务应用程序的方法。开发一个扫描器是一个雄心勃勃的项目,通常能使程序员感到很满意。

常用的端口扫描技术


TCP connect() 扫描

这是最基本的TCP扫描。操作系统提供的connect()系统调用,用来与每一个感兴趣的目标计算机的端口进行连接。如果端口处于侦听状态,那么connect()就能成功。否则,这个端口是不能用的,即没有提供服务。这个技术的一个最大的优点是,你不需要任何权限。系统中的任何用户都有权利使用这个调用。另一个好处就是速度。如果对每个目标端口以线性的方式,使用单独的connect()调用,那么将会花费相当长的时间,你可以通过同时打开多个套接字,从而加速扫描。使用非阻塞I/O允许你设置一个低的时间用尽周期,同时观察多个套接字。但这种方法的缺点是很容易被发觉,并且被过滤掉。目标计算机的logs文件会显示一连串的连接和连接是出错的服务消息,并且能很快的使它关闭。

TCP SYN扫描

这种技术通常认为是“半开放”扫描,这是因为扫描程序不必要打开一个完全的TCP连接。扫描程序发送的是一个SYN数据包,好象准备打开一个实际的连接并等待反应一样(参考TCP的三次握手建立一个TCP连接的过程)。一个SYN|ACK的返回信息表示端口处于侦听状态。一个RST返回,表示端口没有处于侦听态。如果收到一个SYN|ACK,则扫描程序必须再发送一个RST信号,来关闭这个连接过程。这种扫描技术的优点在于一般不会在目标计算机上留下记录。但这种方法的一个缺点是,必须要有root权限才能建立自己的SYN数据包。

TCP FIN 扫描

有的时候有可能SYN扫描都不够秘密。一些防火墙和包过滤器会对一些指定的端口进行监视,有的程序能检测到这些扫描。相反,FIN数据包可能会没有任何麻烦的通过。这种扫描方法的思想是关闭的端口会用适当的RST来回复FIN数据包。另一方面,打开的端口会忽略对FIN数据包的回复。这种方法和系统的实现有一定的关系。有的系统不管端口是否打开,都回复RST,这样,这种扫描方法就不适用了。并且这种方法在区分Unix和NT时,是十分有用的。

IP段扫描

这种不能算是新方法,只是其它技术的变化。它并不是直接发送TCP探测数据包,是将数据包分成两个较小的IP段。这样就将一个TCP头分成好几个数据包,从而过滤器就很难探测到。但必须小心。一些程序在处理这些小数据包时会有些麻烦。

TCP 反向 ident扫描

ident 协议允许(rfc1413)看到通过TCP连接的任何进程的拥有者的用户名,即使这个连接不是由这个进程开始的。因此你能,举个例子,连接到http端口,然后用identd来发现服务器是否正在以root权限运行。这种方法只能在和目标端口建立了一个完整的TCP连接后才能看到。

FTP 返回攻击

FTP协议的一个有趣的特点是它支持代理(proxy)FTP连接。即入侵者可以从自己的计算机a.com和目标主机target.com的FTP server-PI(协议解释器)连接,建立一个控制通信连接。然后,请求这个server-PI激活一个有效的server-DTP(数据传输进程)来给Internet上任何地方发送文件。对于一个User-DTP,这是个推测,尽管RFC明确地定义请求一个服务器发送文件到另一个服务器是可以的。但现在这个方法好象不行了。这个协议的缺点是“能用来发送不能跟踪的邮件和新闻,给许多服务器造成打击,用尽磁盘,企图越过防火墙”。

我们利用这个的目的是从一个代理的FTP服务器来扫描TCP端口。这样,你能在一个防火墙后面连接到一个FTP服务器,然后扫描端口(这些原来有可能被阻塞)。如果FTP服务器允许从一个目录读写数据,你就能发送任意的数据到发现的打开的端口。

对于端口扫描,这个技术是使用PORT命令来表示被动的User DTP正在目标计算机上的某个端口侦听。然后入侵者试图用LIST命令列出当前目录,结果通过Server-DTP发送出去。如果目标主机正在某个端口侦听,传输就会成功(产生一个150或226的回应)。否则,会出现"425 Can build data connection: Connection refused."。然后,使用另一个PORT命令,尝试目标计算机上的下一个端口。这种方法的优点很明显,难以跟踪,能穿过防火墙。主要缺点是速度很慢,有的FTP服务器最终能得到一些线索,关闭代理功能。

这种方法能成功的情景:
220 xxxxxxx.com FTP server (Version wu-2.4(3) Wed Dec 14 ...) ready.
220 xxx.xxx.xxx.edu FTP server ready.
220 xx.Telcom.xxxx.EDU FTP server (Version wu-2.4(3) Tue Jun 11 ...) ready.
220 lem FTP server (SunOS 4.1) ready.
220 xxx.xxx.es FTP server (Version wu-2.4(11) Sat Apr 27 ...) ready.
220 elios FTP server (SunOS 4.1) ready

这种方法不能成功的情景:
220 wcarchive.cdrom.com FTP server (Version DG-2.0.39 Sun May 4 ...) ready.
220 xxx.xx.xxxxx.EDU Version wu-2.4.2-academ[BETA-12](1) Fri Feb 7
220 ftp Microsoft FTP Service (Version 3.0).
220 xxx FTP server (Version wu-2.4.2-academ[BETA-11](1) Tue Sep 3 ...) ready.
220 xxx.unc.edu FTP server (Version wu-2.4.2-academ[BETA-13](6) ...) ready.

UDP ICMP端口不能到达扫描

这种方法与上面几种方法的不同之处在于使用的是UDP协议。由于这个协议很简单,所以扫描变得相对比较困难。这是由于打开的端口对扫描探测并不发送一个确认,关闭的端口也并不需要发送一个错误数据包。幸运的是,许多主机在你向一个未打开的UDP端口发送一个数据包时,会返回一个ICMP_PORT_UNREACH错误。这样你就能发现哪个端口是关闭的。UDP和ICMP错误都不保证能到达,因此这种扫描器必须还实现在一个包看上去是丢失的时候能重新传输。这种扫描方法是很慢的,因为RFC对ICMP错误消息的产生速率做了规定。同样,这种扫描方法需要具有root权限。

UDP recvfrom()和write() 扫描

当非root用户不能直接读到端口不能到达错误时,Linux能间接地在它们到达时通知用户。比如,对一个关闭的端口的第二个write()调用将失败。在非阻塞的UDP套接字上调用recvfrom()时,如果ICMP出错还没有到达时回返回EAGAIN-重试。如果ICMP到达时,返回ECONNREFUSED-连接被拒绝。这就是用来查看端口是否打开的技术。

ICMP echo扫描

这并不是真正意义上的扫描。但有时通过ping,在判断在一个网络上主机是否开机时非常有用。


下面我利用UDP ICMP端口不能到达扫描的原理给出一个完整的例子

import java.net.*;
import java.io.*;
public class socketChecker implements Runnable{
file://declarations
private String server;
private DatagramSocket dsock;
private DatagramPacket packet;
private int port;
private Socket socket;
private String response="";
private BufferedReader is;
private PrintWriter os;
public static final int TCP=0;
public static final int UDP=1;
private int type;
private boolean tcp; // if tcp true, then a tcp scan is done. if false,
udp.
private String message;
private boolean error=false;
// constructor - this is used by the factory method. You should not call
it.
public socketChecker(String server, int port, int type, String message) {
socket=null;
dsock=null;
packet=null;
this.server=server;
this.port=port;
this.type=type;
this.message=message;
response="trying; no connection"; // default response reports message
// if there is a problem connecting it will be caught as
// an exception in the run method...
}
// methods
/* This static factory method is what you use to scan a port
public static String checkSocket(String ahost, int aport,
int timeout, int type, String message);
ahost - the machine to scan
aport - the port to scan
timeout - tells the thread how many milliseconds to wait for the socket
to respond...
int type - you can use the static ints socketChecker.TCP or
socketChecker.UDP to choose tcp or udp scans...
message - a String used either to message a port (TCP), or as
the data for the UDP packet.
(use depends upon "type" of scan selected in type)
*/
public static String checkSocket(String ahost, int aport,
int timeout, int type, String message) {
socketChecker look= new socketChecker(ahost, aport, type, message);
Thread t = new Thread(look);
t.start();
try {
t.join(timeout);
} catch (InterruptedException e) {
System.out.println("InterruptedException e: " + e.toString());
}
return look.getResponse();
}
// getResponse simply returns the String response
private String getResponse() {
return response;
}
// the run method
public void run() {
if (type==TCP) {
tcp=true;
} else {
tcp=false;
}
if (tcp) {
response="trying TCP=\"" + message + "\"; no connection";
// open a tcp socket
try {
socket = new Socket(server, port);
} catch (Exception e) { // catches mainly security and unknown host
exceptions
response+="; " + e.toString();
error=true;
}
if (!error) { // if the socket is open Reader and Writer
try {
is= new BufferedReader(
new InputStreamReader(socket.getInputStream())
);
os= new PrintWriter(
socket.getOutputStream(),true /* autoFlush */
);
} catch (IOException e) {
response+="; IO problem; " + e.toString();
error=true;
}
if (!error) { // if Reader and Writer are open
response="sending TCP=\"" + message + "\"; no reply";
try {
os.println(message);
} catch (Exception e) {
response+=("; "+e.toString()+"="+message);
}
try {
response="sending TCP=\"" + message + "\"; reply="+is.readLine();
} catch (IOException e) {
response+="; " + e.toString();
}
}
}
} else {
// open a udp socket, send a packet, get response..<br />response="trying UDP packet=\"" + message + "\"; can't create";
try {
dsock=new DatagramSocket();
} catch (SocketException se) {
response="SocketException: " + se.toString();
error=true;
} catch (Exception e) { // mostly to gather the variety of possible
security exceptions
response+="; " + e.toString();
error=true;
}
if (!error) {
response="sending UDP packet=\"" + message + "\"; can't send";
try {
dsock.send(new DatagramPacket(message.getBytes(),
message.getBytes().length,
InetAddress.getByName(server),
port)
);
} catch (UnknownHostException e) {
response+="UnknownHostException:" + e.toString();
error=true;
} catch (IOException e) {
response+="IOException: " + e.toString();
error=true;
} catch (Exception e) { // mostly to gather the variety of possible
security exceptions
response+="; " + e.toString();
error=true;
}
if (!error) {
response="UDP packet sent=\"" + message
+ "\"; no reply";
byte[] buf= new byte[1024];
packet= new DatagramPacket(buf, buf.length);
try {
dsock.receive(packet);
error=true;
} catch (ArrayIndexOutOfBoundsException e) {
response="server trying to overflow buffer: " + e.toString();
error=true;
} catch (IOException e) {
response="IOException: " + e.toString();
error=true;
}
response= "UDP packet sent=\"" + message + "\"; reply=" + new
String(packet.getData(), 0, packet.getLength());
}
}
}
}
}

    以上这个例子包括测试tcp和udp端口,下面我会给出一个更简单的例子和测试结果,旨在给大家一个直观的认识,这个例子是充分利用DatagramSocket在本机 bind端口后的会返回SocketException异常的原理做的例子

package com.bw.module.subsystem.bwwms;
import java.net.*;
 public class test
 {
  public static void main(String args[])  
  {
   for (int port=1024;port<=65535;port++) {
    try {
     DatagramSocket server=new DatagramSocket(port);
     server.close();
     }
    catch(SocketException e) {
     System.out.println("there is a server in port "+port+".");
     }
    }
   }

}
测试结果:

there is a server in port 1025.
there is a server in port 1038.
there is a server in port 1058.
there is a server in port 1105.
there is a server in port 1106.
there is a server in port 1147.
there is a server in port 1478.
there is a server in port 1569.
there is a server in port 4000.
there is a server in port 4500.
there is a server in port 6000.
there is a server in port 6001.
there is a server in port 6002.
there is a server in port 6003.
there is a server in port 6004.
there is a server in port 6005.
there is a server in port 6006.
there is a server in port 6007.
there is a server in port 6008.
there is a server in port 6009.
there is a server in port 6010.
there is a server in port 6011.
there is a server in port 6012.


更加详细的用法你可以去认真阅读java.net包然后熟练使用,在此我只是给个抛砖引玉的作用,如果哪位有更好的方法,可以直接联系我,我的email:xiaoqin99@gamil.com

补上测试远程服务器的测试例子,不过我在这里需要说明的是因为udp协议是属于不可靠协议,所以这里的测试用例我都是在局域网测试成功的,而在现实网络中,有很多网关以及其他一些不可测的原因,所以这个成功率是不能保障的。所以这个示例更适合于要扫描局域网某机udp端口的时候。

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UdpPort {

 public UdpPort() {
  super();
  // TODO Auto-generated constructor stub
 }
 public void TestUdpPort()
   {

  String ipAddress = "192.168.0.29";
  
  int port = 4545;

     DatagramSocket connection = null;


  byte[] myByte = ipAddress.getBytes();
  String myStr = new String(myByte);

 

  try
  {
   //connection = new DatagramSocket(port, InetAddress.getByName(ipAddress));//(ipAddress, port);
   connection = new DatagramSocket();//(ipAddress, port);
   //connection.setReceiveTimeout(20*1000);
   connection.setSoTimeout(120*1000);
   connection.connect( InetAddress.getByName(ipAddress), port);
   System.out.println("连结创建完成...");
   connection.send((new DatagramPacket(myByte, myByte.length)));
   System.out.println(" 数据发送完成...");
   while(true)
   {
    byte[] newByte = new byte[4096];
    DatagramPacket dp = new DatagramPacket(newByte, 4096);
    connection.receive(dp);
    if (dp != null && dp.getData() != null)
    {
     System.out.println(dp.getLength());
     System.out.println("#####");
     byte[] rslt = dp.getData();
     for (int i = 0;i < dp.getLength(); i++)
     {
      System.out.println(rslt[i]);
      //System.out.println();
     }
     System.out.println("#####");
    }
    //String myDump = buffer.getHexDump();
    
    break;
   }
   connection.close();
  }
  catch(Exception ex)
  {

   ex.printStackTrace();
   
  }
 }
 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  UdpPort up = new UdpPort();
  up.TestUdpPort();

 }


}



文章出处:飞诺网(www.firnow.com):http://dev.firnow.com/course/3_program/java/javajs/20071018/77896_2.html
分享到:
评论

相关推荐

    Java开发端口扫描

    总结,Java开发中的端口扫描涉及到TCP连接、UDP通信、多线程和异步编程等技术。理解这些原理和实践可以帮助开发者构建高效且合规的端口扫描工具。同时,注意优化策略,如使用NIO和分布式处理,以及遵守网络使用的...

    端口扫描器的设计与实现

    端口扫描的基本原理。 3.基于Java的端口扫描器的核心代码。 4.端口扫描的设计优化。 5.端口扫描的实现效果。报告有一定的质量保证,可以用来参考借鉴。 博主以专业第一的成绩保送至某计算机强校,所做的课程设计有...

    计算机网络课程设计 多线程端口扫描器(TCP/UDP端口扫描)(java实现)带GUI界面

    2.2端口的有效范围是1~65535,在该范围内使用多线程机制循环创建客户端套接字对象,对某一地址(段)的主机端口进行扫描,若套接字没有发生异常,说明该端口打开并提供服务,返回该开放端口的类型(如UDP端口还是TCP...

    java端口扫描器

    同时,通过实际运行程序,可以加深对端口扫描原理的理解,并提升网络安全意识。 总结,Java端口扫描器是一个实用的网络工具,它结合了Java的网络编程特性和端口扫描技术,为学习和研究提供了宝贵的资源。通过研究和...

    java 端口扫描源代码 30个 汇总

    二、Java端口扫描原理 在Java中,我们可以使用`java.net.Socket`类进行端口扫描。创建Socket对象时,可以指定目标主机和端口号,如果端口开放,Socket会成功建立;如果端口关闭,会抛出异常。此外,还可以使用`java...

    java端口扫描程序

    在实际开发中,一个完整的Java端口扫描程序会包括以上这些核心组件,并可能根据具体需求进行扩展,如支持UDP扫描、增加结果输出格式、添加扫描策略等。同时,开发者应了解相关的网络法规,以确保扫描活动的合法性。

    TCP/UDP端口扫描器的设计(含源码)

    第3章 TCP/UDP端口扫描器的设计 3.4 PortScan_TCP 3.5 PortScan_UDP 因为网上没有网络扫描技术揭秘的源代码,所以自己买了书dump下光盘按章节上传,可以根据需要下载

    Java端口扫描工具源代码

    此外,还可以在此基础上扩展功能,例如添加UDP端口扫描、异步处理、更复杂的错误处理机制,或者使用更高级的并发库如`CompletableFuture`来进一步提升性能。 在实际应用中,端口扫描工具也可以用于安全测试,比如在...

    端口扫描器的设计与实现(java)

    在这个“端口扫描器的设计与实现(java)”项目中,开发者运用了Java语言,结合Socket编程和TCP技术,创建了一个基于Java JFrame的图形用户界面应用程序。 1. **Java Socket编程**: Java Socket是网络通信的基础...

    Java端口扫描器

    9. **网络协议理解**:理解TCP和UDP协议的基本工作原理有助于编写更精确的端口扫描器。例如,TCP的三次握手可以用来判断端口是否被监听,而不仅仅是开放。 10. **安全性与合规性**:进行端口扫描时,应遵循网络安全...

    基于java的多线程端口扫描器

    端口扫描器的工作原理通常是发送TCP或UDP数据包到目标主机的特定端口,并根据响应判断端口是否开放。在这个Java实现中,多线程技术被用来提高效率,因为每个线程可以独立扫描不同的端口,从而加快整个扫描过程。多...

    端口扫描器

    端口扫描器是一种网络安全工具,它通过发送网络连接请求到目标主机的多个端口来检测哪些...通过进一步改进,可以添加更多高级特性,比如多线程扫描、自定义扫描策略、支持UDP端口扫描等,以提升扫描效率和功能完备性。

    java实现的端口扫描程序

    在实际开发中,还可以根据需求增加更多功能,比如通过Nmap库进行更复杂的端口扫描,或者添加对UDP端口的支持(使用DatagramSocket)。 需要注意的是,频繁或无授权的端口扫描可能被视为网络攻击,因此在进行端口...

    java开发的端口扫描程序

    端口扫描程序是网络安全和系统管理员常用的工具,用于检测网络上的设备开放了哪些端口,以便了解服务状态、...通过理解和应用这些原理,开发者可以创建出高效、稳定的端口扫描工具,满足各种网络诊断和安全评估的需求。

    服务器IP端口扫描工具

    在IT领域,网络管理和安全是至关重要的部分,而服务器IP端口扫描工具则是这一环节中的重要工具。IP端口扫描是网络安全评估、故障排查和系统维护的重要手段,它可以帮助我们了解网络服务的状态,发现潜在的安全漏洞,...

    毕业论文设计-IT计算机-JAVA本地监听与远程端口扫描(源代码+论文).zip

    Java中可以使用Socket或DatagramSocket类实现TCP或UDP端口扫描。 4. **源代码分析**:论文附带的源代码提供了实际实现的示例,帮助理解监听和扫描的逻辑。通过阅读和分析这些代码,学习者可以深入了解Java网络编程...

    JAVA SWING 多线程实现扫描同一个网段的IP,以及选定IP的端口

    用了一个礼拜时间做了一个端口扫描程序 从扫描同一个网段的IP开始 逐步添加功能 现在还具有了扫描选定IP的常见TCP UDP端口 包括部分常见木马所使用端口 并可以自定义扫描端口 扫描同一网段的IP主要是用SHELL方法 ...

    UDP端口扫描

    UDP端口扫描 找了一堆,觉得不好用,于是自己写了一个。 有代码,有文档。 编译环境VC6或VS2008均可。 代码风格还有很大的调整余地,不过应该不影响阅读。 补充一句,此代码可以可以改成多线程调用,也就是说速度...

Global site tag (gtag.js) - Google Analytics