Java Web中的入侵检测及简单实现

转载 2015年07月09日 10:35:19

一、简介

  在Java Web应用程中,特别是网站开发中,我们有时候需要为应用程序增加一个入侵检测程序来防止恶意刷新的功能,防止非法用户不断的往Web应用中重复发送数据。当然,入侵检测可以用很多方法实现,包括软件、硬件防火墙,入侵检测的策略也很多。在这里我们主要介绍的是Java Web应用程序中通过软件的方式实现简单的入侵检测及防御。

  该方法的实现原理很简单,就是用户访问Web系统时记录每个用户的信息,然后进行对照,并根据设定的策略(比如:1秒钟刷新页面10次)判断用户是否属于恶意刷新。

  我们的入侵检测程序应该放到所有Java Web程序的执行前,也即若发现用户是恶意刷新就不再继续执行Java Web中的其它部分内容,否则就会失去了意义。这就需要以插件的方式把入侵检测的程序置入Java Web应用中,使得每次用户访问Java Web,都先要到这个入侵检测程序中报一次到,符合规则才能放行。

  Java Web应用大致分为两种,一种纯JSP(+Java Bean)方式,一种是基于框架(如Struts、EasyJWeb等)的。第一种方式的Java Web可以通过Java Servlet中的Filter接口实现,也即实现一个Filter接口,在其doFilter方法中插入入侵检测程序,然后再web.xml中作简单的配置即可。在基于框架的Web应用中,由于所有应用都有一个入口,因此可以把入侵检测的程序直接插入框架入口引擎中,使框架本身支持入侵检测功能。当然,也可以通过实现Filter接口来实现。

  在EasyJWeb框架中,已经置入了简单入侵检测的程序,因此,这里我们以EasyJWeb框架为例,介绍具体的实现方法及源码,完整的代码可以在EasyJWeb源码中找到。

  在基于EasyJWeb的Java Web应用中(如http://www.easyjf.com/bbs/),默认情况下你只要连续刷新页面次数过多,即会弹出如下的错误:

EasyJWeb框架友情提示!:-): 
  您对页面的刷新太快,请等待60秒后再刷新页面! 
  详细请查询http://www.easyjf.com

二、用户访问信息记录UserConnect.java类  

  这个类是一个简单的Java Bean,主要代表用户的信息,包括用户名、IP、第一次访问时间、最后登录时间、登录次数、用户状态等。全部代码如下:

package com.easyjf.web; 
import java.util.Date; 
/** 

* <p>Title:用户验证信息</p> 
* <p>Description:记录用户登录信息,判断用户登录情况</p> 
* <p>Copyright: Copyright (c) 2006</p> 
* <p>Company: www.easyjf.com</p> 
* @author 蔡世友 
* @version 1.0 
*/ 
public class UserConnect { 
private String userName; 
private String ip; 
private Date firstFailureTime; 
private Date lastLoginTime; 
private int failureTimes;//用户登录失败次数 
private int status=0;//用户状态0表示正常,-1表示锁定 
public int getFailureTimes() { 
return failureTimes; 

public void setFailureTimes(int failureTimes) { 
this.failureTimes = failureTimes; 

public Date getFirstFailureTime() { 
return firstFailureTime; 

public void setFirstFailureTime(Date firstFailureTime) { 
this.firstFailureTime = firstFailureTime; 

public String getIp() { 
return ip; 

public void setIp(String ip) { 
this.ip = ip; 

public Date getLastLoginTime() { 
return lastLoginTime; 

public void setLastLoginTime(Date lastLoginTime) { 
this.lastLoginTime = lastLoginTime; 

public String getUserName() { 
return userName; 

public void setUserName(String userName) { 
this.userName = userName; 

public int getStatus() { 
return status; 

public void setStatus(int status) { 
this.status = status; 

}

三、监控线程UserConnectManage.java类

  这是入侵检测的核心部分,主要实现具体的入侵检测、记录、判断用户信息、在线用户的刷新等功能,并提供其它应用程序使用本组件的调用接口。

package com.easyjf.web; 
import java.util.Date; 
import java.util.HashMap; 
import java.util.HashSet; 
import java.util.Iterator; 
import java.util.Map; 
import java.util.Set; 
import org.apache.log4j.Logger; 
/** 

* <p>Title:用户入侵检测信息</p> 
* <p>Description:用于判断用户刷新情况检查,默认为10秒钟之内连续连接10次为超时</p> 
* <p>Copyright: Copyright (c) 2006</p> 
* <p>Company: www.easyjf.com</p> 
* @author 蔡世友 
* @version 1.0 
*/ 
public class UserConnectManage { 
private static final Logger logger = (Logger) Logger.getLogger(UserConnectManage.class.getName()); 
private static int maxFailureTimes=10;//最大登录失败次数 
private static long maxFailureInterval=10000;//毫秒,达到最大登录次数且在这个时间范围内 
private static long waitInterval=60000;//失败后接受连接的等待时间,默认1分钟 
private static int maxOnlineUser=200;//同时在线的最大数 
private final static Map users=new HashMap();//使用ip+userName为key存放用户登录信息UserLoginAuth 
private static Thread checkThread=null; 
private static class CheckTimeOut implements Runnable{ 
private Thread parentThread; 
public CheckTimeOut(Thread parentThread) 

this.parentThread=parentThread; 
synchronized(this){ 
if(checkThread==null){ 
checkThread= new Thread(this); 
//System.out.println("创建一个新线程!"); 
checkThread.start(); 



public void run() { 
while(true) 

if(parentThread.isAlive()){ 
try{ 
Thread.sleep(2000); 
int i=0; 
if(users.size()>maxOnlineUser)//当达到最大用户数时清除 

synchronized(users){//执行删除操作 
Iterator it=users.keySet().iterator(); 
Set set=new HashSet(); 
Date now=new Date(); 
while(it.hasNext()) 

Object key=it.next(); 
UserConnect user=(UserConnect)users.get(key); 
if(now.getTime()-user.getFirstFailureTime().getTime()>maxFailureInterval)//删除超时的用户 

set.add(key); 
logger.info("删除了一个超时的连接"+i); 
i++; 


if(i<5)//如果删除少于5个,则强行删除1/2在线记录,牺牲性能的情况下保证内存 

int num=maxOnlineUser/2; 
it=users.keySet().iterator(); 
while(it.hasNext() && i<num) 

set.add(it.next()); 
logger.info("删除了一个多余的连接"+i); 
i++; 


users.keySet().removeAll(set); 




catch(Exception e) 

e.printStackTrace(); 



else 

break; 


logger.info("监视程序运行结束!"); 


//通过checkLoginValidate判断是否合法的登录连接,如果合法则继续,非法则执行 
public static boolean checkLoginValidate(String ip,String userName)//只检查认证失败次数 

boolean ret=true; 
Date now=new Date(); 
String key=ip+":"+userName; 
UserConnect auth=(UserConnect)users.get(key); 
if(auth==null)//把用户当前的访问信息加入到users容器中 

auth=new UserConnect(); 
auth.setIp(ip); 
auth.setUserName(userName); 
auth.setFailureTimes(0); 
auth.setFirstFailureTime(now); 
users.put(key,auth); 
if(checkThread==null)new CheckTimeOut(Thread.currentThread()); 

else 

if(auth.getFailureTimes()>maxFailureTimes) 

//如果在限定的时间间隔内,则返回拒绝用户连接的信息 
if((now.getTime()-auth.getFirstFailureTime().getTime())<maxFailureInterval) 

ret=false; 
auth.setStatus(-1); 

else if(auth.getStatus()==-1 && (now.getTime()-auth.getFirstFailureTime().getTime()<(maxFailureInterval+waitInterval)))//重置计数器 

ret=false; 

else 

auth.setFailureTimes(0); 
auth.setFirstFailureTime(now); 
auth.setStatus(0); 



//登录次数加1 
auth.setFailureTimes(auth.getFailureTimes()+1); 

//System.out.println(key+":"+auth.getFailureTimes()+":"+ret+":"+(now.getTime()-auth.getFirstFailureTime().getTime())); 
return ret; 

public static void reset(String ip,String userName)//重置用户信息 

Date now=new Date(); 
String key=ip+":"+userName; 
UserConnect auth=(UserConnect)users.get(key); 
if(auth==null)//把用户当前的访问信息加入到users容器中 

auth=new UserConnect(); 
auth.setIp(ip); 
auth.setUserName(userName); 
auth.setFailureTimes(0); 
auth.setFirstFailureTime(now); 
users.put(key,auth); 

else 

auth.setFailureTimes(0); 
auth.setFirstFailureTime(now); 


public static void remove(String ip,String userName)//删除用户在容器中的记录 

String key=ip+":"+userName; 
users.remove(key); 

public static void clear()//清空容器中内容 

if(!users.isEmpty())users.clear(); 

public static long getMaxFailureInterval() { 
return maxFailureInterval; 

public static void setMaxFailureInterval(long maxFailureInterval) { 
UserConnectManage.maxFailureInterval = maxFailureInterval; 

public static int getMaxFailureTimes() { 
return maxFailureTimes; 

public static void setMaxFailureTimes(int maxFailureTimes) { 
UserConnectManage.maxFailureTimes = maxFailureTimes; 

public static int getMaxOnlineUser() { 
return maxOnlineUser; 

public static void setMaxOnlineUser(int maxOnlineUser) { 
UserConnectManage.maxOnlineUser = maxOnlineUser; 

public static long getWaitInterval() { 
return waitInterval; 

public static void setWaitInterval(long waitInterval) { 
UserConnectManage.waitInterval = waitInterval; 
}


四、调用接口

  在需要进入侵检测判断的地方,直接使用UserConnectManage类中的checkLoginValidate方法即可。如EasyJWeb的核心Servlet 

com.easyjf.web.ActionServlet中调用UserConnectManage的代码: 
if(!UserConnectManage.checkLoginValidate(request.getRemoteAddr(),"guest")) 

info(request,response,new Exception("您对页面的刷新太快,请等待"+UserConnectManage.getWaitInterval()/1000+"秒后再刷新页面!")); 
return; 
}

五、总结

  当然,这里提供的方法只是一个简单的实现示例,由于上面的用户信息是直接保存在内存中,若并发用户很大的时候的代码的占用,可以考虑引入数据库来记录用户的访问信息,当然相应的执行效率肯定用降低。上面介绍的实现中,入侵检测判断的策略也只有用户访问次数及时间间隔两个元素,您还可以根据你的实现情况增加其它的检测元素。


本文转载自:http://m.zdnet.com.cn/article/903906.htm?

WEB入侵检测及简单实现

       在Java Web应用程中,特别是网站开发中,我们有时候需要为应用程序增加一个入侵检测程序来防止恶意刷新的功能,防止非法用户不断的往Web应用中重复发送数据。当然,入侵检测可以用很多方法...
  • ccsdba
  • ccsdba
  • 2006年10月24日 15:25
  • 1645

Java入侵检测(三)

这就是最终效果。用了WindowBuilder构建gui。开始捕获就去抓包,抓完包就存到数据库,并且回调到主线程中显示(有种Android既视感,只不过Android比JavaGui复杂无数倍)用到的...
  • irony0egoist
  • irony0egoist
  • 2017年05月27日 10:17
  • 225

JavaWeb安全性教程入门篇 -- 偷天换日使用者的会话信息(劫持session)

好久没有更新博客了,这段时间打算有空就更新下关于java web项目安全方面的教程文章,包括简单的说明下hacker是如何渗透入侵我们的项目,基于鄙人的技术是比较菜,所以如有说的不正确的,或者大神觉得...
  • shadowsick
  • shadowsick
  • 2015年04月25日 13:46
  • 5214

入侵Tomcat服务器一次实战描述

到网上随便逛逛,我就会发现用JSP制作的电子商务网站多如牛毛,从JSP日渐繁荣的局面来看,适合于各种平台而且免费的Tomcat逐渐成为WEB服务器的一种选择。eBay.com与Dell计算机等知名网站...
  • sinat_31998357
  • sinat_31998357
  • 2015年10月21日 11:58
  • 1646

入侵Tomcat服务器一次实战描述

到网上随便逛逛,我就会发现用JSP制作的电子商务网站多如牛毛,从JSP日渐繁荣的局面来看,适合于各种平台而且免费的Tomcat逐渐成为WEB服务器的一种选择。eBay.com与Dell计算机等知名网站...
  • sinat_31998357
  • sinat_31998357
  • 2015年10月21日 11:58
  • 1646

Java入侵检测系统(一)

这学期上了入侵检测实验,因为一开始就打算做这个包分析系统,结果拖延症再发,现在开始一边学php一边做入侵检测(为了保证进度,我会不定期更新文章督促自己)。Jpcap抓包类,看到一篇论文,讲的比较好运行...
  • irony0egoist
  • irony0egoist
  • 2017年04月27日 11:28
  • 304

五大免费企业网络入侵检测工具(IDS)

转自:http://security.ctocio.com.cn/315/12540315.shtml         Sourcefire提供有供应商支持和即时更新的功能齐全的商业版本Sn...
  • fireblue1990
  • fireblue1990
  • 2016年03月06日 19:33
  • 1596

opencv程序十九:基于帧间差分法的区域目标入侵检测

运行程序在原图像上画个入侵检测的方框,有运动目标j
  • zhangjikuan
  • zhangjikuan
  • 2014年10月19日 15:34
  • 3892

入侵检测系统概述

首先来说说这个入侵检测系统(IDS)的概念,IDS通过实时地收集和分析计算机网络或系统中的信息来检查是否出现违背安全策略的行为和是否存在入侵的迹象,进而达到提示入侵和预防攻击的目的。入侵检测系统是一种...
  • ShaoqunLiu
  • ShaoqunLiu
  • 2016年09月04日 14:55
  • 632

一种新的攻击方法——Java Web表达式注入

在2014年6月18日@终极修炼师曾发布这样一条微博: 链接的内容是一个名为Jenkins的服务,可以在没有password的情况下受到攻击。而攻击方法比较有趣,Jenkins提供了一个...
  • kk_gods
  • kk_gods
  • 2016年07月06日 17:01
  • 1895
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java Web中的入侵检测及简单实现
举报原因:
原因补充:

(最多只允许输入30个字)