wonderer's program

everything will be better
posts - 19, comments - 6, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2007年6月22日

去SA面试的时候,面试官问我平时用Java的什么数据结构,答曰:Vector。又问:哪有用过其他的的吗?例如List和Map之类的。答曰:甚少。(自己汗一个,没水平)既然不会就要学习啦。

翻开《Java学习笔记》,里面对对象容器的描述不错。

1. ArrayList和LinkedList

ArrayList使用了数组结构实现List的数据。所以ArraryList用来快速定位对象是非常有效率的。但是如果要对ArraryList中间插入或者删除,效率会非常低。

LinkedList使用链表来实现的List。所以跟ArrayList相反,LinkedList对于插入和删除是非常有优势,反之对于快速定位,是LinkedList的弱项。

1)ArrayListDemo

public class ArrayListDemo {
    public static void main(String[] args) {
        
        //用Scanner类,可以轻松获得commander的输入
        Scanner scanner = new Scanner(System.in);
        
        List<String> list = new ArrayList<String>();
        
        //在控制台输入,quit退出
        while(true) {
            System.out.print("Rokey@console# ");
            String input = scanner.next();
            if(input.equals("quit")) {
                break;
            }
            list.add(input);
        }
        
        System.out.print("显示输入:");
        
        //使用5.0的foreach功能对List进行遍历
        for(String s:list) {
            //5.0的类C的输出格式
            System.out.printf("%s ",s);
        }
    }
}

输出:

Rokey@console# 一二三
Rokey@console# 三二一
Rokey@console# quit
显示输入:一二三 三二一 

 

2)用LinkedList实现的一个字符串栈

/**
 *
 * @author Rokey
 * 用LinkedList构建一个字符栈,先进先出
 */
public class StringStack {

    private LinkedList<String> linkList;

    public StringStack() {
        linkList = new LinkedList<String>();
    }

    public void push(String s) {
        //将元素加入链表第一个位置
        linkList.addFirst(s);
    }

    public String pop() {
        //删除链表第一个元素,并返回
        return linkList.removeFirst();
    }

    public String top() {
        //返回链表第一个元素,但并不删除
        return linkList.getFirst();
    }

    public boolean isEmpty() {
        //检查链表是否为空
        return linkList.isEmpty();
    }
}
public class StringStackDemo {

    public static void main(String[] args) {

        //用Scanner类,可以轻松获得commander的输入
        Scanner scanner = new Scanner(System.in);

        StringStack stack = new StringStack();

        //在控制台输入,quit退出
        while (true) {
            System.out.print("Rokey@console# ");
            String input = scanner.next();
            if (input.equals("quit")) {
                break;
            }
            stack.push(input);
        }

        System.out.print("显示输入:");
        //使用5.0的foreach功能对List进行遍历
        
        while(!stack.isEmpty()) {
            //5.0的类C的输出格式
            System.out.printf("%s ", stack.pop());
        }
    }
}

输出:

Rokey@console# 一二三
Rokey@console# 三二一
Rokey@console# quit
显示输入:三二一 一二三 

posted @ 2007-12-27 23:05 wonderer 阅读(3058) | 评论 (0)编辑 收藏

OYM中的任务中,有一项对文件内容的检查挺有意思的,就是要检查字符是否是全角的,例如“GY”(not“GY”),并且把这些字符改为半角的。
想起了在研发中心的一个朋友的抱怨:“昨天写了一整天的程序,发到广大教务处那边居然说不能用,然后亲自跑了一躺,发现不是我的程序有问题,是那边的人输入个全角字符,搜半角的字符,当然不行了”
恩,Betty写的需求真有意思,考虑的问题很周全,是一个很厉害的项目经理。如果从输入这里解决了字符是否是半角的,那么,以后的情况就容易解决很多了。恩,网上搜了一下资料,查了一下书,得出了以下代码:
public void testChar() {
  String s1 
= "123";
  String s2 
= "abc";
  String s3 
= "123abc";
  System.out.println(s1);
  System.out.println(s2);
  System.out.println(s3);
  
for (int i = 0; i < s1.length(); i++) {
   
int j = s1.charAt(i);
   
if (j > 256) {
    
int temp = j - 65248;
    
if (temp >= 0) {
     System.out.print((
char)j+"-->:" + (char) temp);
    } 
else {
      System.out.print((
char) j);
    }
   } 
else {
    System.out.print((
char) j);
   }
  }
  System.out.println();
  
  
for (int i = 0; i < s2.length(); i++) {
   
int j = s2.charAt(i);
   
if (j > 256) {
    
int temp = j - 65248;
    
if (temp >= 0) {
     System.out.print((
char)j+"-->:" + (char) temp);
    } 
else {
     System.out.print((
char) j);
    }
   } 
else {
    System.out.print ((
char) j);
   }
  }
  System.out.println();
  
  
for (int i = 0; i < s3.length(); i++) {
   
int j = s3.charAt(i);
   
if (j > 256) {
    
int temp = j - 65248;
    
if (temp >= 0) {
      System.out.print((
char)j+"-->:" + (char) temp);
    } 
else {
     System.out.print((
char) j);
    }
   } 
else {
    System.out.print((
char) j);
   }
  }
  System.out.println();
 
 }
输出的结果如下:
123
-->ab-->bc--c
123a
-->ab-->bc--c


posted @ 2007-12-23 16:46 wonderer 阅读(1904) | 评论 (3)编辑 收藏

OYM的任务中,有个要求,上传一个Excel文件,检查他的内容是否合法,并返回信息。

今天想了一下,第一个要解决的问题就是上传一个Excel文件,上传文件的组件到挺多的,网上一搜,就有一大堆教程,但是现在并不是要上传一个文件到服务器以作存储之用,而是要上传一个文件到内存里,以Java的数据结构存储起来,并检查,把合乎要求的数据写到数据库里。所以在网上的一大堆上传文件的组件并不合用。于是又想自己写,思路就是从客户端那里获取一个InputStream,然后就对这个InputStream做一系列的检查。代码如下:

ServletInputStream sis =  request.getInputStream();
InputStreamReader isr = new InputStreamReader(sis);
             
int ch;
while((ch = isr.read()) != -1 ) {          
   out.println((char)ch);
}
             
System.out.flush();

结果的出去就是如下(输出东西写到页面):

-----------------------------7d7ea23120550 
Content-Disposition: form-data; name="file1"; 
filename="C:\Documents and Settings\Administrator\桌面\test.txt" 
Content-Type: text/plain 
my name is Rokey.Rokey。我的名字叫Rokey. 
-----------------------------7d7ea23120550 Content-Disposition: form-data; 
name="Submit" 上传 -----------------------------7d7ea23120550--
很明显,这里只有
my name is Rokey.Rokey。我的名字叫Rokey.

对我有用,这个也正是我的文件里面的内容,其它的都是关于这些form的其它信息。对我这个程序是没有用的。如果这里写下去的话,还要我去分析那些是数据,哪些是form的参数。好,到现在为止,我已经打消了自己写的念头了。我想,那些组件都可以把上传文件封装得那么好,能不能利用那些库,抽出文件的IO流,让我操作呢?

于是,就开始对O'Reilly的上传组件cos.jar的API看,看到里面有这么一段。

public class MultipartParser
extends java.lang.Object
A utility class to handle multipart/form-data requests, the kind of requests that support file uploads. This class uses a "pull" model where the reading of incoming files and parameters is controlled by the client code, which allows incoming files to be stored into any OutputStream. If you wish to use an API which resembles HttpServletRequest, use the "push" model MultipartRequest instead. It's an easy-to-use wrapper around this class.

This class can receive arbitrarily large files (up to an artificial limit you can set), and fairly efficiently too. It cannot handle nested data (multipart content within multipart content). It can now with the latest release handle internationalized content (such as non Latin-1 filenames).

It also optionally includes enhanced buffering and Content-Length limitation. Buffering is only required if your servlet container is poorly implemented (many are, including Tomcat 3.2), but it is generally recommended because it will make a slow servlet container a lot faster, and will only make a fast servlet container a little slower. Content-Length limiting is usually only required if you find that your servlet is hanging trying to read the input stram from the POST, and it is similarly recommended because it only has a minimal impact on performance.

而且里面的API已经封装程我想象得到的情况了。于是,我就觉得这样我就可以完成我的功能了。于是,就写了以下代码:

MultipartParser mp = new MultipartParser(request, 10 * 1024 * 1024);
Part part;
while ((part = mp.readNextPart()) != null) {
      if (part.isParam()) {
          // it's a parameter part
          ParamPart paramPart = (ParamPart) part;
          //out.println("param: name=" + name + "; value=" + value);
      } else if (part.isFile()) {
          FilePart filePart = (FilePart) part;
          InputStream is = filePart.getInputStream();
          InputStreamReader isr = new InputStreamReader(is);

          int ch;
          while ((ch = isr.read()) != -1) {

              out.print((char) ch);
          }

          System.out.flush();
          isr.close();
          is.close();
      }
}
               

出去结果如下:

my name is Rokey.Rokey。
我的名字叫Rokey.
到现在,已经可以把这个流封装成一个文件流,送给Excel的组件去处理了。

posted @ 2007-12-23 00:52 wonderer 阅读(1431) | 评论 (0)编辑 收藏

     摘要: 什么是IOC呢,在网上搜到了一非常有意思的讲解。IoC就是Inversion of Control,控制反转。在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制。这称为控制反转。 下面我们以几个例子来说明什么是IoC 假设我们要设计一个Girl和一个Boy类,其中Girl有kiss方法,即Girl想要Kiss一个Boy。那么,我们的问题是,Girl如何能够认识这个B...  阅读全文

posted @ 2007-10-28 16:50 wonderer 阅读(665) | 评论 (0)编辑 收藏

Buffloa里的传递参数的编码是GBK。

buffalo.switchPart('body',url,false);如果url中包含汉字,是采用GBK编码的。在不改变tomcat的配置文件的情况下,在目标页面里获得url参数的正确方法是

   1: String name = new String(request.getParameter("name").getBytes(
   2:             "ISO8859-1"), "GBK");

注意,如果这里用utf-8作为编码的转换的话,会出现乱码。

posted @ 2007-10-26 16:41 wonderer 阅读(413) | 评论 (0)编辑 收藏

最近在准备考试系统的开发,碰到了 request.getParameter乱码的问题。跟林彬讨论了一下,还是觉得用老方法管用。

如果是post的话,可以通过设置filter的方法来解决。

如果是get或者是超链接的话,以前是通过设置tomcat的配置文件server.xml来解决的,但这样不好,并不是所有的项目,我们都可以修改到服务器的tomcat的配置文件。具体代码如下:

   1: Connector port="8080" maxHttpHeaderSize="8192"
   2:                maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
   3:                enableLookups="false" redirectPort="8443" acceptCount="100"
   4:                connectionTimeout="20000" disableUploadTimeout="true" uRIEncoding="gbk"/>

还是觉得老方法管用,只是有点麻烦:

   1: String id=new String(request.getParameter("id").getBytes("ISO8859-1"),"UTF-8");
   2: String name = new String(request.getParameter("name").getBytes("ISO8859-1"),"UTF-8");

posted @ 2007-10-25 23:23 wonderer 阅读(13414) | 评论 (1)编辑 收藏

电脑搬回了宿舍,破解了校园网,多人公用一条宽带。要一个主机拨号。ip总不免要设来设去,总是要手工改,很麻烦,于是上网查了查,写了个改ip的bat文件。内容如下:

1: netsh interface ip set address name="本地连接" source=static addr=192.168.0.39

mask=255.255.255.0 gateway=192.168.0.1 gwmetric=1

   2: netsh interface ip set dns name = "本地连接" source = static addr = 202.116.128.1
   3: netsh interface ip add dns name = "本地连接" addr = 202.116.128.2

posted @ 2007-09-11 17:25 wonderer 阅读(2047) | 评论 (1)编辑 收藏

在写HTML中,并不是&nbsp才会产生一个空格。<td>hello (间隔一个空格)</td>输出的数据是: hello+一个空格.如果是对这数据进行修改然后再写回到数据库的话,这样就会产生错误。

如下写法是会错误的,

image

造成的结果是 image  仔细留意会发现运通后面多了一个空格

必须改成一下写法:

image 

注意</td>跟前面是没有空格的。这样运行结果就会是这样的image ,是没有空格的。

posted @ 2007-08-03 10:32 wonderer 阅读(652) | 评论 (0)编辑 收藏

     摘要: 写了个Spring的DAO入门例子。 DAO的接口 1: package dataSourceDemo; 2:   3: public interface IUserDAO { 4: public void insert(User user); 5: public User find(Integer id); 6:   7: } ...  阅读全文

posted @ 2007-07-18 14:04 wonderer 阅读(480) | 评论 (0)编辑 收藏

首先要导入包

1:Spring支持包:spring.jar , commons-logging.jar

2: JUnit支持包: JUnit.jar

image

建立Bean类,

   1: package refBeanDemo;
   2:  
   3: import java.util.Date;
   4:  
   5: public class HelloBean {
   6:     private String helloWorld;
   7:     private Date date;
   8:     public Date getDate() {
   9:         return date;
  10:     }
  11:     public void setDate(Date date) {
  12:         this.date = date;
  13:     }
  14:     public String getHelloWorld() {
  15:         return helloWorld;
  16:     }
  17:     public void setHelloWorld(String helloWorld) {
  18:         this.helloWorld = helloWorld;
  19:     }
  20:     
  21: }

 

建立配置文件,和在里面进行注入

   1: <?xml version="1.0" encoding="UTF-8"?>
   2: <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "../resources/spring-beans-2.0.dtd" >
   3: <beans>
   4:     <bean id="dateBean" class="java.util.Date"></bean>
   5:     
   6:     <bean id="helloBean" class="refBeanDemo.HelloBean">
   7:         <property name="helloWorld">
   8:             <value>你好,世界</value>
   9:         </property>
  10:         <property name="date" ref="dateBean"></property>
  11:     </bean>
  12: </beans>

写JUnit进行测试,方便管理,把JUnit的东东放到test包里。

   1: package refBeanDemo;
   2:  
   3: import org.springframework.context.ApplicationContext;
   4: import org.springframework.context.support.ClassPathXmlApplicationContext;
   5:  
   6: import junit.framework.TestCase;
   7:  
   8: public class TestRefBeanDemo extends TestCase {
   9:     private ApplicationContext context;
  10:  
  11:     public void setUp() {
  12:         context = new ClassPathXmlApplicationContext("refBeanDemo/NewFile.xml");
  13:     }
  14:  
  15:     public void testSpring() {
  16:         HelloBean helloBean = (HelloBean)context.getBean("helloBean");
  17:         System.out.println(helloBean.getDate());
  18:         assertEquals("你好,世界", helloBean.getHelloWorld());
  19:         
  20:     }
  21: }

 

运行JUnit测试

image

测试成功。类的分布如下:

image

image

posted @ 2007-07-18 11:12 wonderer 阅读(1340) | 评论 (0)编辑 收藏

ARP地址欺骗类病毒(以下简称ARP病毒)是一类特殊的病毒,该病毒一般属于木马(Trojan)病毒,不具备主动传播的特性,不会自我复制。但是由于其发作的时候会向全网发送伪造的ARP数据包,干扰全网的运行,因此它的危害比一些蠕虫还要严重得多。

二、ARP病毒发作时的现象

网络掉线,但网络连接正常,内网的部分PC机不能上网,或者所有电脑不能上网,无法打开网页或打开网页慢,局域网时断时续并且网速较慢等。

三、ARP病毒原理

3.1 网络模型简介

众所周知,按照OSI (Open Systems Interconnection Reference Model 开放系统互联参考模型) 的观点,可将网络系统划分为7层结构,每一个层次上运行着不同的协议和服务,并且上下层之间互相配合,完成网络数据交换的功能,如图1:

1106901

图1 OSI网络体系模型

然而,OSI的模型仅仅是一个参考模型,并不是实际网络中应用的模型。实际上应用最广泛的商用网络模型即TCP/IP体系模型,将网络划分为四层,每一个层次上也运行着不同的协议和服务,如图2。

1106903

图2 TCP/IP四层体系模型及其配套协议

上图中,蓝色字体表示该层的名称,绿色字表示运行在该层上的协议。由图2可见,我们即将要讨论的ARP协议,就是工作在网际层上的协议。

3.2 ARP协议简介


我们大家都知道,在局域网中,一台主机要和另一台主机进行通信,必须要知道目标主机 的IP地址,但是最终负责在局域网中传送数据的网卡等物理设备是不识别IP地址的,只能识别其硬件地址即MAC地址。MAC地址是48位的,通常表示为 12个16进制数,每2个16进制数之间用“-”或者冒号隔开,如:00-0B-2F-13-1A-11就是一个MAC地址。每一块网卡都有其全球唯一的 MAC地址,网卡之间发送数据,只能根据对方网卡的MAC地址进行发送,这时就需要一个将高层数据包中的IP地址转换成低层MAC地址的协议,而这个重要 的任务将由ARP协议完成。

ARP全称为Address Resolution Protocol,地址解析协议。所谓“地址解析”就是主机在发送数据包前将目标主机IP地址转换成目标主机MAC地址的过程。ARP协议的基本功能就是 通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。 这时就涉及到一个问题,一个局域网中的电脑少则几台,多则上百台,这么多的电脑之间,如何能准确的记住对方电脑网卡的MAC地址,以便数据的发送呢?这就 涉及到了另外一个概念,ARP缓存表。在局域网的任何一台主机中,都有一个ARP缓存表,该表中保存这网络中各个电脑的IP地址和MAC地址的对照关系。 当这台主机向同局域网中另外的主机发送数据的时候,会根据ARP缓存表里的对应关系进行发送。

下面,我们用一个模拟的局域网环境,来说明ARP欺骗的过程。

3.3 ARP欺骗过程


假设一个只有三台电脑组成的局域网,该局域网由交换机(Switch)连接。其中一 个电脑名叫A,代表攻击方;一台电脑叫S,代表源主机,即发送数据的电脑;令一台电脑名叫D,代表目的主机,即接收数据的电脑。这三台电脑的IP地址分别 为192.168.0.2,192.168.0.3,192.168.0.4。MAC地址分别为MAC_A,MAC_S,MAC_D。其网络拓扑环境如图 3。

1106905

图3 网络拓扑

现在,S电脑要给D电脑发送数据了,在S电脑内部,上层的TCP和UDP的数据包已经传送到 了最底层的网络接口层,数据包即将要发送出去,但这时还不知道目的主机D电脑的MAC地址MAC_D。这时候,S电脑要先查询自身的ARP缓存表,查看里 面是否有192.168.0.4这台电脑的MAC地址,如果有,那很好办,就将 封装在数据包的外面。直接发送出去即可。如果没有,这时S电脑要向全网络发送一个ARP广播包,大声询问:“我的IP是192.168.0.3,硬件地址 是MAC_S,我想知道IP地址为192.168.0.4的主机的硬件地址是多少?” 这时,全网络的电脑都收到该ARP广播包了,包括A电脑和D电脑。A电脑一看其要查询的IP地址不是自己的,就将该数据包丢弃不予理会。而D电脑一看IP 地址是自己的,则回答S电脑:“我的IP地址是192.168.0.4,我的硬件地址是MAC_D”需要注意的是,这条信息是单独回答的,即D电脑单独向 S电脑发送的,并非刚才的广播。现在S电脑已经知道目的电脑D的MAC地址了,它可以将要发送的数据包上贴上目的地址MAC_D,发送出去了。同时它还会 动态更新自身的ARP缓存表,将192.168.0.4-MAC_D这一条记录添加进去,这样,等S电脑下次再给D电脑发送数据的时候,就不用大声询问发 送ARP广播包了。这就是正常情况下的数据包发送过程。

这样的机制看上去很完美,似乎整个局域网也天下太平,相安无事。但是,上述数据发 送机制有一个致命的缺陷,即它是建立在对局域网中电脑全部信任的基础上的,也就是说它的假设前提是:无论局域网中那台电脑,其发送的ARP数据包都是正确 的。那么这样就很危险了!因为局域网中并非所有的电脑都安分守己,往往有非法者的存在。比如在上述数据发送中,当S电脑向全网询问“我想知道IP地址为 192.168.0.4的主机的硬件地址是多少?”后,D电脑也回应了自己的正确MAC地址。但是当此时,一向沉默寡言的A电脑也回话了:“我的IP地址 是192.168.0.4,我的硬件地址是MAC_A” ,注意,此时它竟然冒充自己是D电脑的IP地址,而MAC地址竟然写成自己的!由于A电脑不停地发送这样的应答数据包,本来S电脑的ARP缓存表中已经保 存了正确的记录:192.168.0.4-MAC_D,但是由于A电脑的不停应答,这时S电脑并不知道A电脑发送的数据包是伪造的,导致S电脑又重新动态 更新自身的ARP缓存表,这回记录成:192.168.0.4-MAC_A,很显然,这是一个错误的记录(这步也叫ARP缓存表中毒),这样就导致以后凡 是S电脑要发送给D电脑,也就是IP地址为192.168.0.4这台主机的数据,都将会发送给MAC地址为MAC_A的主机,这样,在光天化日之下,A 电脑竟然劫持了由S电脑发送给D电脑的数据!这就是ARP欺骗的过程。

如果A这台电脑再做的“过分”一些,它不冒充D电脑,而是冒充网关,那后果会怎么 样呢?我们大家都知道,如果一个局域网中的电脑要连接外网,也就是登陆互联网的时候,都要经过局域网中的网关转发一下,所有收发的数据都要先经过网关,再 由网关发向互联网。在局域网中,网关的IP地址一般为192.168.0.1。如果A这台电脑向全网不停的发送ARP欺骗广播,大声说:“我的IP地址是 192.168.0.1,我的硬件地址是MAC_A”这时局域网中的其它电脑并没有察觉到什么,因为局域网通信的前提条件是信任任何电脑发送的ARP广播 包。这样局域网中的其它电脑都会更新自身的ARP缓存表,记录下192.168.0.1-MAC_A这样的记录,这样,当它们发送给网关,也就是IP地址 为192.168.0.1这台电脑的数据,结果都会发送到MAC_A这台电脑中!这样,A电脑就将会监听整个局域网发送给互联网的数据包!

实际上,这种病毒早就出现过,这就是ARP地址欺骗类病毒。一些传奇木马 (Trojan/PSW.LMir)具有这样的特性,该木马一般通过传奇外挂、网页木马等方式使局域网中的某台电脑中毒,这样中毒电脑便可嗅探到整个局域 网发送的所有数据包,该木马破解了《传奇》游戏的数据包加密算法,通过截获局域网中的数据包,分析数据包中的用户隐私信息,盗取用户的游戏帐号和密码。在 解析这些封包之后,再将它们发送到真正的网关。这样的病毒有一个令网吧游戏玩家闻之色变的名字:“传奇网吧杀手” !

四、ARP病毒新的表现形式


由于现在的网络游戏数据包在发送过程中,均已采用了强悍的加密算法,因此这类ARP 病毒在解密数据包的时候遇到了很大的难度。现在又新出现了一种ARP病毒,与以前的一样的是,该类ARP病毒也是向全网发送伪造的ARP欺骗广播,自身伪 装成网关。但区别是,它着重的不是对网络游戏数据包的解密,而是对于HTTP请求访问的修改。

HTTP是应用层的协议,主要是用于WEB网页访问。还是以上面的局域网环境举 例,如果局域网中一台电脑S要请求某个网站页面,如想请求www.sina.com.cn这个网页,这台电脑会先向网关发送HTTP请求,说:“我想登陆 www.sina.com.cn网页,请你将这个网页下载下来,并发送给我。”这样,网关就会将www.sina.com.cn页面下载下来,并发送给S 电脑。这时,如果A这台电脑通过向全网发送伪造的ARP欺骗广播,自身伪装成网关,成为一台ARP中毒电脑的话,这样当S电脑请求WEB网页时,A电脑先 是“好心好意”地将这个页面下载下来,然后发送给S电脑,但是它在返回给S电脑时,会向其中插入恶意网址连接!该恶意网址连接会利用MS06-014和 MS07-017等多种系统漏洞,向S电脑种植木马病毒!同样,如果D电脑也是请求WEB页面访问,A电脑同样也会给D电脑返回带毒的网页,这样,如果一 个局域网中存在这样的ARP病毒电脑的话,顷刻间,整个网段的电脑将会全部中毒!沦为黑客手中的僵尸电脑!

案例:


某企业用户反映,其内部局域网用户无论访问那个网站,KV杀毒软件均报病毒:Exploit.ANIfile.o 。

在经过对该局域网分析之后,发现该局域网中有ARP病毒电脑导致其它电脑访问网页 时,返回的网页带毒,并且该带毒网页通过MS06-014和MS07-017漏洞给电脑植入一个木马下载器,而该木马下载器又会下载10多个恶性网游木 马,可以盗取包括魔兽世界,传奇世界,征途,梦幻西游,边锋游戏在内的多款网络游戏的帐号和密码,对网络游戏玩家的游戏装备造成了极大的损失。被ARP病 毒电脑篡改的网页如图4。

1108133

图4 被ARP病毒插入的恶意网址连接

从图4中可以看出,局域网中存在这样的ARP病毒电脑之后,其它客户机无论访问什么网页,当返回该网页时,都会被插入一条恶意网址连接,如果用户没有打过相应的系统补丁,就会感染木马病毒。

五、ARP病毒电脑的定位方法


下面,又有了一个新的课题摆在我们面前:如何能够快速检测定位出局域网中的ARP病毒电脑?

面对着局域网中成百台电脑,一个一个地检测显然不是好办法。其实我们只要利用ARP 病毒的基本原理:发送伪造的ARP欺骗广播,中毒电脑自身伪装成网关的特性,就可以快速锁定中毒电脑。可以设想用程序来实现以下功能:在网络正常的时候, 牢牢记住正确网关的IP地址和MAC地址,并且实时监控着来自全网的ARP数据包,当发现有某个ARP数据包广播,其IP地址是正确网关的IP地址,但是 其MAC地址竟然是其它电脑的MAC地址的时候,这时,无疑是发生了ARP欺骗。对此可疑MAC地址报警,在根据网络正常时候的IP-MAC地址对照表查 询该电脑,定位出其IP地址,这样就定位出中毒电脑了。下面详细说一下几种不同的检测ARP中毒电脑的方法。

5.1 命令行法


这种方法比较简便,不利用第三方工具,利用系统自带的ARP命令即可完成。上文已经 说过,当局域网中发生ARP欺骗的时候,ARP病毒电脑会向全网不停地发送ARP欺骗广播,这时局域网中的其它电脑就会动态更新自身的ARP缓存表,将网 关的MAC地址记录成ARP病毒电脑的MAC地址,这时候我们只要在其它受影响的电脑中查询一下当前网关的MAC地址,就知道中毒电脑的MAC地址了,查 询命令为 ARP -a,需要在cmd命令提示行下输入。输入后的返回信息如下:

Internet Address      Physical Address        Type

192.168.0.1 00-50-56-e6-49-56 dynamic

这时,由于这个电脑的ARP表是错误的记录,因此,该MAC地址不是真正网关的MAC地址, 而是中毒电脑的MAC地址!这时,再根据网络正常时,全网的IP—MAC地址对照表,查找中毒电脑的IP地址就可以了。由此可见,在网络正常的时候,保存 一个全网电脑的IP—MAC地址对照表是多么的重要。可以使用nbtscan 工具扫描全网段的IP地址和MAC地址,保存下来,以备后用。

5.2 工具软件法


现在网上有很多ARP病毒定位工具,其中做得较好的是Anti ARP Sniffer(现在已更名为ARP防火墙),下面我就演示一下使用Anti ARP Sniffer这个工具软件来定位ARP中毒电脑。

首先打开Anti ARP Sniffer 软件,输入网关的IP地址之后,再点击红色框内的“枚举MAC”按钮,即可获得正确网关的MAC地址,如图5。

1109953

图5 输入网关IP地址后,枚举MAC

接着点击“自动保护”按钮,即可保护当前网卡与网关的正常通信。如图6。

1109955

图6 点击自动保护按钮

当局域网中存在ARP欺骗时,该数据包会被Anti ARP Sniffer记录,该软件会以气泡的形式报警。如图7。

1109957

图7 Anti ARP Sniffer 的拦截记录

这时,我们再根据欺骗机的MAC地址,对比查找全网的IP-MAC地址对照表,即可快速定位出中毒电脑。

5.3 Sniffer 抓包嗅探法

当局域网中有ARP病毒欺骗时,往往伴随着大量的ARP欺骗广播数据包,这时,流量检测机制应该能够很好的检测出网络的异常举动,此时Ethereal 这样的抓包工具就能派上用场。如图8。

1109959

图8 用Ethereal抓包工具定位出ARP中毒电脑

从图8中的红色框内的信息可以看出,192.168.0.109 这台电脑正向全网发送大量的ARP广播包,一般的讲,局域网中有电脑发送ARP广播包的情况是存在的,但是如果不停的大量发送,就很可疑了。而这台192.168.0.109 电脑正是一个ARP中毒电脑。

以上三种方法有时需要结合使用,互相印证,这样可以快速准确的将ARP中毒电脑定位出来。

七、ARP病毒的网络免疫措施


由于ARP病毒的种种网络特性,可以采用一些技术手段进行网络中ARP病毒欺骗数据包免疫。即便网络中有ARP中毒电脑,在发送欺骗的ARP数据包,其它电脑也不会修改自身的ARP缓存表,数据包始终发送给正确的网关,用的比较多的办法是“双向绑定法” 。

双向绑定法,顾名思义,就是要在两端绑定IP-MAC地址,其中一端是在路由器中, 把所有PC的IP-MAC输入到一个静态表中,这叫路由器IP-MAC绑定。令一端是局域网中的每个客户机,在客户端设置网关的静态ARP信息,这叫PC 机IP-MAC绑定。客户机中的设置方法如下:

新建记事本,输入如下命令:

arp -d
arp -s 192.168.0.1 00-e0-4c-8c-9a-47

其中,“arp –d” 命令是清空当前的ARP缓存表,而“arp -s 192.168.0.1 00-e0-4c-8c-9a-47 ”命令则是将正确网关的IP地址和MAC地址绑定起来,将这个批处理文件放到系统的启动目录中,可以实现每次开机自运行,这一步叫做“固化arp表” 。

“双向绑定法”一般在网吧里面应用的居多。

除此之外,很多交换机和路由器厂商也推出了各自的防御ARP病毒的软硬产品,如:华 为的H3C AR 18-6X 系列全千兆以太网路由器就可以实现局域网中的ARP病毒免疫,该路由器提供MAC和IP地址绑定功能,可以根据用户的配置,在特定的IP地址和MAC地址 之间形成关联关系。对于声称从这个IP地址发送的报文,如果其MAC地址不是指定关系对中的地址,路由器将予以丢弃,是避免IP地址假冒攻击的一种方式。

八、ARP病毒KV解决方案

针对ARP病毒日益猖獗的情况,江民科技推出了整体解决方案:

1.KV杀毒软件每周7天不间断升级病毒库,单机版网络版同步升级,实时拦截来自网络上的各种ARP病毒。

2.针对局域网用户,建议统一部署KV网络版杀毒软件,KV网络版具有全网统一升级病毒库,统一全网杀毒的强大功能,可以彻底查杀来自局域网中的ARP病毒。

3.“KV未知病毒扫描”功能可以识别出绝大多数ARP病毒,KV未知病毒扫描程序采用独特的行为判定技术,可以彻底检测出本机中已知和未知的ARP病毒,协助网络管理员快速清除ARP病毒。

4.特针对企业用户,提供“ARP病毒应急响应服务” ,江民科技网络安全工程师可以上门处理企业用户内网中的ARP病毒,确保快速恢复企业网络的数据通讯安全。

5.KV新版防火墙特增加了ARP病毒防御功能,可以拦截来自局域网中的ARP欺骗数据包,保护本机联网安全。设置界面如图11。

1112749

图11 KV新版防火墙增加了ARP攻击防护功能

KV新版防火墙增加了ARP攻击防护功能,该功能使用方法也很简单,安装完KV防火墙之后, 点击“设置”按钮,然后勾选“启用攻击防护功能” ,再点击“自动检测本机网络设置” ,程序就会自动获得本机和网关的IP地址和MAC地址,然后点击确定即可。KV防火墙就会实时检测来自网络中的ARP数据包,发现有异常的数据包欺骗,就 会予以拦截,保障本机网络通信安全。

九、关于ARP病毒的网络安全建议

1.在网络正常时候保存好全网的IP—MAC地址对照表,这样在查找ARP中毒电脑时很方便。

2.都全网的电脑都打上MS06-014和MS07-017这两个补丁,包括所有的客户端和服务器,以免感染网页木马。

3.部署网络流量检测设备,时刻监视全网的ARP广播包,查看其MAC地址是否正确。

4.做好IP—MAC地址的绑定工作,对于从这个IP地址发送的报文,如果其MAC地址不是指定关系对中的地址,予以丢弃。

5.部署网络版的杀毒软件,定期升级病毒库,定期全网杀毒。

posted @ 2007-06-22 21:11 wonderer 阅读(262) | 评论 (0)编辑 收藏