host头攻击漏洞修复方案
检测到目标URL存在http host头攻击漏洞
简介
扫描到网站存在http host头攻击漏洞,需要对该漏洞进行修复,网站后台是用java写的,对于这种host头攻击的方式,有很多种方式避免。
如从源头考虑的话,一般网站都配置了nginx或者部署在Apache上面,可以在nginx或者Apache上拦截非法请求头的; 由于我是在本机上测试的,项目是部署在tomcat上,故无法验证nginx和apache的修复方式。 这里介绍一下从过滤器的层次进行拦截的方式。
过滤器拦截的方式
使用的测试工具
burpsuite,Firefox ; 在火狐上面设置代理,用burpsuite拦截请求并修改host测试验证是否成功,使用burpsuite以及在火狐设置代理的方式这里就不介绍了,网上有很多详细的教程
存在漏洞的版本
这里先介绍漏洞版本的测试样例,我在火狐代理以及burpsuite上监听的端口是8081,注意burpsuite默认监听了8080,一定要取消,不然就会和tomcat启用端口重复了。
火狐浏览器上访问存在漏洞的页面(实际上随便访问个网页测试结果都一样的)
在burpsuite上监听拦截到该地址,通过repeater修改host头,模拟访问请求。原来的host是10.4.0.246:8080,我们将其修改后改为10.4.0.2460:8080,修改后重新send请求过去,有响应,且响应内容为修改后的host。这就存在了host伪装的情况。
实际上这种非法的host的只要加了个拦截器最后跳回登录界面就可以了,但是可能存在通过修改host来跨域攻击以及越过普通权限攻击,这种只是有可能实际上系统架构完善了是完全可以避免的。但是既然检测出了漏洞,那么理所应当的也要对其进行相应的修复。
修复漏洞的版本
上面我们已经知道了如何测试漏洞的方法了,现在是如何使用过滤器的方式处理漏洞修复。 直奔主题由于使用的是javaweb开发的网站,在web.xml下配置一个新的拦截器。
hostCleanFilter com.test.HostCleanFilter hostCleanFilter /*
注意在这里添加的拦截器建议放到第一个,即< url-pattern> /* < /url-pattern> 放在第一个,因为一个项目可能本身的过滤器较多,当其他的过滤器起作用后可能就轮不到这个过滤器执行了,那么检测监听的时候会发现漏洞没被修复,这点也是我自己测试的时候踩的坑,当时发现有的页面修复了漏洞,有的页面没被修复,这是因为拦截器对于请求的结果可能导致了不同的去向。
配置拦截器的代码:
public class HostCleanFilter implements Filter { public static Logger logger = Logger.getLogger(HostCleanFilter.class); public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; String requestHost = request.getHeader("host"); if (requestHost != null && isRightHost(requestHost)){ response.setStatus(403); return; } chain.doFilter(request,response); } public boolean isRightHost(String requestHost){ if (!StringUtils.equals(requestHost,WebConstants.HostOne) &&!StringUtils.equals(requestHost,WebConstants.HostTwo)){ //域名非法 logger.info("非法的Host:" + requestHost); return true; } logger.info("合法的Host:" + requestHost); return false; } public void destroy() { } }
上面的WebConstants.HostOne、WebConstants.HostTwo是我自己配置合法host,拦截每一个请求若检验host不对则返回403。一般网站的话只要检验两个host就可以了,一个是ip地址类型的,如我本机测试允许的是10.4.0.246:8080,假如是生产环境上的可以在HostTwo修改为 域名:port,如 baidu.com:8080 这种,根据自身的真实情况添加或修改。
以上步骤修改完后,可以开始重新测试刚刚的地址了,让我们来看下会有什么变化呢。继续访问刚才的地址,在burpsuite上监听端口并重新repeater。老规矩还是修改host为10.4.0.2460:8080,重写了host查看到返回403。
至此漏洞已经修复完毕,可以多测几个不同的网页检测下是否一致。测试时候需注意几点的是:
1.在本机上测试的时候ip一般是localhost或者127.0.0.1地址作为网站的访问ip地址,会与火狐浏览器默认的不代理地址冲突,导致无法正常测试,我这里的10.4.0.246是在ipconfig上查看分配给的子网ip,本地访问网站的时候使用分配的ip进行访问而不是直接访问本机ip,这么做就能成功的代理火狐浏览器上的请求。
2.火狐或者其他浏览器设置的代理端口尽量不要与本地tomcat或者Apache重提,所以我设置的是8081端口,burpsuite上监听的也是8081端口。
3.web.xml设置过滤器建议放在第一位,因为不同的项目过滤器可能执行结果不一样,比如是直接访问这个漏洞网页还是登陆用户后再访问这个漏洞网页,所返回的结果可能都会不一样,因为登录前后拦截的session不一样了。假如你熟悉你的项目那么可以设置过滤的顺序,我这次是把host头过滤放在了执行顺序第二位,不确定的话可以直接放第一位,省去一些麻烦。
