欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

一次测试引发的探索:关于分号在java web中的一个特性

来源:本站整理 作者:wadcl 时间:2017-06-22 TAG: 我要投稿

还记得IIS的解析漏洞吗?xx.asp;.jpg。而最近对java网站进行测试的时候发现了一个问题,也是由分号引起的,也因此去查看了一下源码,也许很多人已经知道了这个问题,但是也许有的人不知道,所以我将内容记录下来了并进行了分享。
起因
我在测试的时候的一个功能的配置文件片段为:
"viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       
"prefix" value="/view/" />
       
"suffix" value=".jsp" />
代码片段:
  public static String PRE = "landingpage/";
  @RequestMapping({"online"})
  public String toOnline(String version) { if (StringUtils.isBlank(version)) {
      version = "1.0";
    }
    return PRE + "online-" + version;
  }
很明显,version的值是可以通过客户端传递过来的,也就是返回的文件路径是可以被控制的:
当version=xxx时,返回的文件应该是:/view/landingpage/online-xxx.jsp
所以这一功能是存在任意文件下载漏洞的,前提是我们如何把后面的.jsp给分割出去,在很多时候我们会使用%00等空字符进行截断,但是这里并不能成功。
而经过一些测试,我发现分号在这里能有截断的功能,也就是当我输入../../WEB-INF/web.xml;的时候,我能够获取到web.xml的配置信息:

怀疑
漏洞已经测试成功,但是为什么分号能够有截断的功能呢?
我开始以为是spring mvc的框架中的问题,但似乎并不是,我又怀疑是tomcat中间件的问题,似乎也不全是。
如何验证这些疑问呢?
找一个java的网站,在路径的结尾也就是问号的前面输入:http://www.xxx.com/sdaf.jsp;xxxx?id=xx,你会发现和http://www.xxx.com/sdaf.jsp?id=xx返回的结果一样的,并没有提示找不到对应的页面。
也就是说;xxxx在处理的过程中与前面的内容被分隔开了。
也就是说这似乎是java web的一个普遍现象,而不仅仅是某个中间件或者spring的问题。
调试
于是直接写了一个简单的jsp的代码,来调试这个过程:
request.getRequestDispatcher(request.getParameter("filename")+".doc").include(request, response); %>
作为突破口,使用tomcat作为中间件进行调试,打开接口requestDispatcher的一个实现类:ApplicationDispatcher

在ApplicationDispatcher中设置断点进行调试
访问下面地址来触发断点:
http://localhost:8080/Spring/test123.jsp?filename=/WEB-INF/web.xml;
这时发现doForward函数中的变量servletPath中的值为:WEB-INF/web.xml,已经将分号以及后面的数据给去除了

而经过变量的追踪,就发现在经过wrequest.setServletPath(servletPath)这个方法前:wrequest.getServletPath=”test123.jsp”,而之后变成了/WEB-INF/web.xml,所以问题出在servletPath的获取上:servletPath的获取应该是在实例化的时候,也就是在代码中:
public ApplicationDispatcher   (Wrapper wrapper, String requestURI, String servletPath, String pathInfo, String queryString, String name) {
        super();
        // Save all of our configuration parameters
        this.wrapper = wrapper;
        this.context = (Context) wrapper.getParent();
        this.requestURI = requestURI;
        this.servletPath = servletPath;
        this.pathInfo = pathInfo;
        this.queryString = queryString;
        this.name = name;
        if (wrapper instanceof StandardWrapper)
            this.support = ((StandardWrapper) wrapper).getInstanceSupport();
        else
            this.support = new InstanceSupport(wrapper);
}
由此看出来servletPath的值也是从外部传递进来的
实例化该类的对象为:ApplicationContext.getRequestDispatcher:

查看代码

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载