S2-017重现过程

简单介绍

s2-017漏洞为URL跳转漏洞,点我进官方漏洞介绍,POC为:

http://localhost:8080/struts2-showcase/fileupload/doUpload.action?redirect:http://www.zhutougg.com  

概念铺垫

在重现漏洞之前,我们先学习两个知道点

什么是ActionServlet

我不知道怎么解释ActionServlet,所以谷歌搜索了一下别人的定义

ActionServlet provides the "controller" in the Model-View-Controller (MVC) design pattern for web applications that is commonly known as "Model 2". All the requests to the server goes through the controller. Controller is responsible for handling all the requests. Struts Flow start with ActionServlet then call to process() method of RequestProcessor  

缩成一句话意思就是:struts2框架就是由ActionServlet开始,然后调用RequestProcessorprocess()方法来响应请求

Servlet的生命周期

Servlet的生命周期分为三个阶段

  1. 初始化阶段性,调用init()方法
  2. 响应客户请求阶段,调用service()方法
  3. 终止阶段,调用destory()方法

漏洞分析

根据官方漏洞介绍,漏洞是在redirect跳转时产生的,这个功能是由类ServletRedirectResultsendRedirect()方法实现的

我们从头分析一下漏洞执行流程

1.由StrutsServlet响应用户请求,在被调用时执行StrutsServletservice()方法

2.第76行,当匹配到对应的action后则执行execute.executeAction(),我们跟进去,发现来到了ExecuteOperations

3.继续跟进到Dispatcher.serviceAction(),ActionMapping主要是获取配置文件中的对象,当对象不为空时,则执行Result.execute()

4.Result是一个接口,其中的execute()方法由StrutsResultSupport实现,StrutsResultSupport为所有Action执行结果的基类,其中location表示执行后要去的结果(可以是JSP页面,也可以是action)

5.这里它调用了自己的doExecute()

   protected abstract void doExecute(String finalLocation, ActionInvocation invocation) throws Exception;

继续调试可以发现ServletRedirectResult在继承StrutsResultSupport时重写了这个方法

6.这个函数代码比较长,这里就不截图了,复制了一些相关代码

   protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
       ......
       sendRedirect(response, finalLocation);
   }

然后执行下面的sendRedirect()

   protected void sendRedirect(HttpServletResponse response, String finalLocation) throws IOException {
           if (SC_FOUND == statusCode) {
               response.sendRedirect(finalLocation);
           } else {
               response.setStatus(statusCode);
               response.setHeader("Location", finalLocation);
               response.getWriter().write(finalLocation);
               response.getWriter().close();
           }

       }

  1. 最后页面响应response.sendRedirect(finalLocation)

我们发现程序中并没有检查redirect的location值,只是直接将location直接添加到响应的HTTP 302跳转请求头中,所以导致了URL跳转漏洞

测试方法

可以在所有的action后面添加?redirect:http://www.zhutougg.com查看是否跳转。如:

http://localhost:8080/struts2-showcase/fileupload/doUpload.action?redirect:http://www.zhutougg.com

http://localhost:8080/struts2-showcase/chat/showRooms.action?redirect:http://www.zhutougg.com

zhutougg

继续阅读此作者的更多文章