2006年07月28日

Internet的飞速发展大大增加了网络的用户规模,但同时网络中的安全问题也日趋严重。维护网络安全的一项重要技术就是网络的实时监控,因此,对于能够分析、诊断、以及测试网络功能与安全性的工具软件的需求也越来越迫切。而网络分析程序依赖一套捕获数据包的库函数,这就是所谓的包捕获软件。目前已有几种类型的包捕获应用软件,例如:基于原始套接字、基于LibPcap库和基于WinPcap库,而Jpcap是Windows和Linux平台中实现的一个跨平台网络数据包处理开发库。本文就是利用Jpcap来实现对用户访问ASP、JSP、PHP、CGI的Web口令与E-Mail口令的捕获。由于国内大多数网站对用户名与密码口令均采用明文传送,因此使用本文方法可以在局域网内捕获用户名与密码。

一、网络嗅探原理
网络嗅探是一种常用的收集网络数据包的方法,其基本原理对经过网卡的数据包进行捕获和解码,从链路层协议开始进行解码分析,一直到应用层的协议,最后获取数据包中需要的内容。

1 局域网的连接方式
局域网的连接设备主要有HUB和交换机。由于以HUB连接的以太网等很多网络是基于总线方式的,所以当一个机器给另一个机器发送数据时,HUB会将要传送的数据包发送至本网段内的所有主机。这种以广播方式发送数据包的形式使得任何网络接收设备都可以接收到所有正在传送的通讯数据,不过通常情况下主机只将判断为应该接收的数据包传给上层应用程序处理。所以在共享HUB情况下同一网段的所有机器的网卡都能接收到数据。

而交换机能记住每个端口的MAC地址,该哪个机器接收就发往哪个端口,而不是像HUB那样发给所有的端口,所以交换机环境下只有该接收数据的机器的网卡能接收到数据。HUB的工作模式使得共享决定了同一网段同一时间只能有两个机器进行数据通信,而交换机在两个机器传输数据的时候其它端口没有占用,所以其它端口之间也可以同时传输。这就是HUB与交换机不同的两个地方,HUB是同一时间只能有一个机器发送数据并且所有机器都可以接收,只要不是广播数据,交换机同一时间可以有一对机器进行数据传输并且数据是私有的。

2 网卡工作模式
在实际的系统中,数据的收发由网卡来完成,网卡的主要工作原理是整理计算机发往网线上的数据,并将数据包发送出去。当网卡接收到传输来的数据时,根据接收数据帧的目的MAC地址和网卡驱动程序设置的接收模式进行判断,对需要接收的就产生中断信号送CPU,然后由操作系统调用驱动程序进行接收;认为不该接收的就丢弃不管,所以不该接收的数据在网卡处就截断了。对于网卡来说一般有四种接收模式:

(1)广播方式(Broadcast):能够接收网络中的广播信息。

(2)组播方式(Multicast):网卡能够接收组播数据,也就是一个人发出的包可以同时被其他多个有资格的人接收,这些人就形成了一个组,他们在组内的通信是广播式的。

(3)直接方式(Directory):只有目的网卡才能接收该数据。

(4)混杂模式(Promiscuous):能够接收一切通过网卡的数据。

网卡的缺省工作模式包含广播模式和直接模式,即它只接收广播帧和发给自己的帧,而网络数据包捕获程序一般采用第4种模式。

3 数据包截获机制
网络数据包截获机制一般指通过截获整个网络的所有信息流量,根据信息源主机,目标主机,服务协议断口等信息简单过滤掉不关心的数据,再将用户感兴趣的数据发送给更高层的应用程序进行分析。

在局域网中,由于以太网是基于广播方式传送数据的,以太网上的所有主机都共享一条网络总线,所以所有的物理信号都会被传送到每一个主机节点,如果将网卡设置为混杂接受模式,则无论监听到的数据帧目的地址如何,网卡都能予以接收。而TCP/IP协议簇中的应用层协议大多数都是以明文形式在网络上传输,这些明文数据往往包含一些敏感数据,如密码、账号等,因此使用监听程序软件可以监听到所有局域网内的数据通信,得到这些敏感信息。当然,其局限性是只能在局域网的共享冲突域中进行。

嗅探器作为一种网络通讯程序,主要是通过对网卡的编程来实现的,对网卡的编程有很多种方法,通常的套接字程序只能响应与自己硬件地址相匹配的或是以广播方式发出的数据帧,对于其他形式的数据帧,网络接口在验证目的地址并非自身地址之后将不引起响应,也就是说应用程序无法接收到达的数据包。而网络嗅探器的目的恰恰在于从网卡接收所有经过它的数据包,这些数据包既可以是发给自己的也可以是发给别人的。显然,要达到此目的就不能让网卡按通常的正常模式工作,而必须将其设置为混杂模式。嗅探程序的设计一般有如下几个阶段:

(1)包捕获设置:包括网络适配器的识别和网卡混杂模式的设置;

(2)过滤器设置:对数据包的捕获设定一些条件,如可以按某些特定的IP地址进行过滤,也可根据网络协议只捕获某种特定的协议,如TCP或UDP包中的数据,还可以过滤出包含特定信息的数据包,例如包含用户名和密码信息的数据包;

(3)数据分析:对捕获的数据进行分析处理,获得数据包中的上层信息。

2006年07月27日

Description
Jpcap is a Java class package that allows Java applications to capture and/or send packets to the network.

Jpcap is based on libpcap/winpcap and Raw Socket API. Therefore, Jpcap is supposed to work on any OS on which libpcap/winpcap has been implemented. Currently, Jpcap has been tested on FreeBSD 3.x, Linux RedHat 6.1, Fedora Core 4, Solaris, and Microsoft Windows 2000/XP.

Jpcap supports the following types of packets: Ethernet, IPv4, IPv6, ARP/RARP, TCP, UDP, and ICMPv4. Other types of packets are captured as raw packets (i.e., instances of the Packet class) which contains the whole data of the packets. This allows Java applications to analyze unsupported packet types.

What’s New
4/22/06 Jpcap ver.0.5.1 is released. This contains several bug fixes. See ChangeLog in detail.
1/6/06 Jpcap ver.0.5 is released under LGPL.
4/9/03 Bug fix on Jpcap.openFile() and JpcapWriter.
4/1/03 New homepage. Jpcap ver.0.4 was released.
9/14/00 Jpcap ver.0.3 is released ARP/RARP supported.Many important bug fix.
7/29/00 Jpcap ver.0.2 is released. Now MS Windows are supported.

Installation
< Windows 9x, NT, 2000, xp >
1.Download and install Javatm2 Platform, Standard Edition (J2SEtm) JRE or JDK.
2.Download and install the latest WinPcap.
3.Download and run Self Installer.
4.Follow the instruction of the installer.
If you do not want to use the installer, you can also install manually.
1.Download and extract the Jpcap source code from the Download page.
2.Copy "lib\Jpcap.dll" into "[JRE directory]\bin" or "[JRE directory]\lib\ext\x86"
3.Copy "lib\jpcap.jar" into "[JRE directory]\lib\ext"
4.If you installed JDK, you also need to copy "lib\jpcap.jar" into "[JDK directory]\jre\lib\ext".
   Note: [JRE directory] is usually "C:\Program Files\Java\j2re*".
   [JDK directory] is usually "C:\Program Files\Java\jdk*".

< UNIX >
1.Download and install Javatm2 Platform, Standard Edition (J2SEtm) JRE or JDK
2.Download and install libpcap if not installed.
   Note: Jpcap ver.0.5 requres libpcap 0.9.4 or later.
3.Download and extract the latest Jpcap
4.Go to "src/c" directory, and edit Makefile 
5.Run "make".
   If you get an error "structure has no member named `sa_len’",
   comment out the line "#define HAVE_SA_LEN" in Jpcap_sub.h.
6.Copy libjpcap.so to [Java directory]/jre/lib/<arch>. <arch> is either "i386" or "sparc"
7.Copy "lib/jpcap.jar" into [Java directory]/jre/lib/ext.

Download

 

Self Installer

Source code

Jpcap ver.0.5.1

Installer for Windows

jpcap-0.5.1.zip

Jpcap ver.0.5

 

jpcap-0.5.zip

Jpcap ver.0.4

 

jpcap-0.4.zip

Jpcap ver.0.3

 

jpcap-0.3.zip

原文:

Capturing low-level network data can be hard in Java, but it’s certainly not impossible

If you want to capture network packets in your Java program, you’ll need a little help because no parts of the core Java APIAPIAPIAPI give access to low-level network data. However, Jpcap is a Java API that provides you with this access on Windows or Unix systems. Jpcap isn’t a pure Java solution; it depends on the use of native libraries. On either Windows or Unix, you must have the required third-party library, WinPcap or libpcap, respectively.

How Jpcap works

Jpcap uses an event model to allow you to process packets. To get started, you must first create a class that implements the interface jpcap.JpcapHandler.

public class JpcapTip implements JpcapHandler {
public void handlePacket(Packet packet){
System.out.println(packet);
}
}

In order to capture packets, you need to tell Jpcap which network device you want to listen with. The API provides the jpcap.Jpcap.getDeviceList() method for this purpose. The method returns an array of strings, and you use it like this:

String[] devices = Jpcap.getDeviceList();

Once you have a list of device names, you must choose one for listening:

String deviceName = devices[0];

After choosing a device, you open it for listening by using the method Jpcap.openDevice(). The openDevice() method requires four arguments: the device name to be opened, the maximum number of bytes to read from the device at one time, a Boolean value specifying whether to put the device into promiscuous mode, and a timeout value that will be used if you later call the processPacket() method.

Jpcap jpcap = Jpcap.openDevice(deviceName, 1028, false, 10000);

The openDevice() method returns a reference to a Jpcap object that will be used for capturing. Now that you have the Jpcap instance, you can start listening by calling either processPacket() or loopPacket(). Both of the methods take two arguments: The maximum number of packets to capture can be -1 to indicate no limit and an instance of a class that implements JpcapHandler.

If you call processPacket(), then Jpcap will capture packets until either the timeout specified in openDevice is exceeded or the maximum number of packets specified has been reached. loopPacket() will capture packets until the maximum number of packets is reached or forever, if there is no maximum. The call looks like this:

jpcap.loopPacket(-1, new JpcapTip());

Here’s the code for the entire test class:

import jpcap.JpcapHandler;
import jpcap.Jpcap;
import jpcap.Packet;

public class JpcapTip implements JpcapHandler {
public void handlePacket(Packet packet){
System.out.println(packet);
}

public static void main(String[] args) throws java.io.IOException{
String[] devices = Jpcap.getDeviceList();

for (int i = 0; i < devices.length; i++) {
System.out.println(devices[i]);
}

String deviceName = devices[0];

Jpcap jpcap = Jpcap.openDevice(deviceName, 1028, false, 1); jpcap.loopPacket(-1, new JpcapTip()); } }

To execute the class, you must make sure that the virtual machine can find the Jpcap native library. On Windows, if the jpcap.dll is in the lib directory, the Java command looks like this:

java -Djava.library.path=lib -cp lib\jpcap.jar;. JpcapTip

The output of executing the test class looks like this (it’s shortened for space purposes):

ARP REQUEST 00:06:5b:01:b2:4d(192.168.15.79)     00:00:00:00:00:00(192.168.15.34)ARP REQUEST 00:06:5b:01:b2:4d(192.168.15.79)     00:00:00:00:00:00(192.168.15.34)1052251329:525479 192.168.15.103->255.255.255.255 protocol(17) priority(0)  hop(offset(0) ident(59244) UDP 1211      1211...

Capturing packets in Java isn’t a pure Java endeavour but, since it’s possible, it’s nice to know the functionality exists.

翻译:

如果你想捕获Java程序中的网络包,那么你需要一些辅助工具,因为核心Java API不能访问底层的网络数据。但Jpcap是一种提供在Windows或UNIX系统上进行这种访问的Java API。

Jpcap不是一种纯粹的Java解决方案;它依赖本地库的使用。在Windows 或 UNIX上,你必须有必要的第三方库,分别是WinPcap或libpcap。

Jpcap的工作原理

Jpcap使用一个事件模型来让你处理包。首先你必须创建一个执行接口jpcap.JpcapHandler的类。

public class JpcapTip implements JpcapHandler {
      public void handlePacket(Packet packet){
          System.out.println(packet);
    }
}

为了捕获包,你需要告诉Jpcap你想用哪个网络设备来监听。API提供了jpcap.Jpcap.getDeviceList()方法以满足这一目的。这个方法返回一列字符串,你可以象如下使用它:

String[] devices = Jpcap.getDeviceList();

 一旦你有了一个设备名称的目录,你必须选取一个用来监听:

String deviceName = devices[0];

 选择一个设备之后,通过Jpcap.openDevice()方法打开它。openDevice()方法需要四个参数:即将打开的设备名,从设备上一次读取的最大字节数,说明是否将设备设为混杂模式的Boolean值,和以后调用processPacket()方法要使用到的超时值。

Jpcapjpcap = Jpcap.openDevice(deviceName, 1028, false, 10000);

 openDevice()方法将一个参数返回到用以捕获的Jpcap对象。既然有了Jpcap实例,你可以调用processPacket() 或loopPacket()开始监听了。这两种方式都带有两个参数:捕获的最大包数可以是-1(说明没有限制);执行JpcapHandler的一个类的实例。

 如果你调用processPacket(),那么Jpcap将一直捕获包,直到超过openDevice中规定的时限或达到了规定的最大包数。loopPacket()则将一直捕获包,直到达到最大包数,如果没有最大数限制,它将永远运行下去。就像下面这样调用:

jpcap.loopPacket(-1, new JpcapTip());

下面则是全部测试类的代码:

import jpcap.JpcapHandler;
import jpcap.Jpcap;
import jpcap.Packet;

public class JpcapTip implements JpcapHandler {
      public void handlePacket(Packet packet){
          System.out.println(packet);
      }

      public static void main(String[] args) throws java.io.IOException{
          String[] devices = Jpcap.getDeviceList();
        for (inti = 0; i < devices.length; i++) {
            System.out.println(devices[i]);
          }
          String deviceName = devices[0];
          Jpcapjpcap = Jpcap.openDevice(deviceName, 1028, false, 1);
          jpcap.loopPacket(-1, new JpcapTip());
     }
}

 为了执行这个类,你必须确保虚拟机可以找到Jpcap的本地库。在Window上,如果jpcap.dll在库地址目录中,Java命令如下:

java -Djava.library.path=lib -cp lib\jpcap.jar;. JpcapTip

 执行测试类的输出则如下(出于篇幅考虑进行了缩减):

ARP REQUEST 00:06:5b:01:b2:4d(192.168.15.79)    
 00:00:00:00:00:00(192.168.15.34)
ARP REQUEST 00:06:5b:01:b2:4d(192.168.15.79)    
 00:00:00:00:00:00(192.168.15.34)
1052251329:525479 192.168.15.103->255.255.255.255 protocol(17) priority(0) 
hop(
offset(0) ident(59244) UDP 1211      1211

 捕获Java中的包并不是一种完美的Java应用,但是,在可能的情况下,最好还是了解其现有的功能。