Struts2 (s2-016) Remote Code Execution Vulnerability detailed code analysis

Source: Internet
Author: User

Before that, winwin has published an analysis article on this vulnerability, which has been well analyzed. However, there are several issues, so I will post my analysis content here for your reference. The data contamination points and triggering points of this vulnerability are different from those of other Struts. Therefore, this article analyzes this vulnerability from the Struts execution process. After Struts2.3, the official change of the original starting filter to org. apache. struts2.dispatcher. ng. filter. strutsPrepareAndExecuteFilter. class so the first breakpoint of this tracking will be under the doFilter method of this class. The Code is as follows:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest) req;        HttpServletResponse response = (HttpServletResponse) res;        try {            prepare.setEncodingAndLocale(request, response);            prepare.createActionContext(request, response);            prepare.assignDispatcherToThread();            if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {                chain.doFilter(request, response);            } else {                request = prepare.wrapRequest(request);                ActionMapping mapping = prepare.findActionMapping(request, response, true);                if (mapping == null) {                    boolean handled = execute.executeStaticResourceRequest(request, response);                    if (!handled) {                        chain.doFilter(request, response);                    }                } else {                    execute.executeAction(request, response, mapping);                }            }        } finally {            prepare.cleanupRequest(request);        }    }

 

Use the red code to obtain the currently accessed action ing. The findActionMapping method in the PrepareOperations class is as follows:
public ActionMapping findActionMapping(HttpServletRequest request, HttpServletResponse response, boolean forceLookup) {        ActionMapping mapping = (ActionMapping) request.getAttribute(STRUTS_ACTION_MAPPING_KEY);        if (mapping == null || forceLookup) {            try {                mapping = dispatcher.getContainer().getInstance(ActionMapper.class).getMapping(request, dispatcher.getConfigurationManager());                if (mapping != null) {                    request.setAttribute(STRUTS_ACTION_MAPPING_KEY, mapping);                }            } catch (Exception ex) {                dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);            }        }        return mapping;    }

 

Follow up to the red code. This Code obtains the action ing by calling the getMapping method of the defaactionactionmapper class. We continue to follow up on this method:
public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) {        ActionMapping mapping = new ActionMapping();        String uri = getUri(request);        int indexOfSemicolon = uri.indexOf(";");        uri = (indexOfSemicolon > -1) ? uri.substring(0, indexOfSemicolon) : uri;        uri = dropExtension(uri, mapping);        if (uri == null) {            return null;        }        parseNameAndNamespace(uri, mapping, configManager);             handleSpecialParameters(request, mapping);        return parseActionName(mapping);    }

 

The red code is used to process special parameters. The trigger point redirect of this vulnerability belongs to the content it processes. Let's take a look at its code:

public void handleSpecialParameters(HttpServletRequest request, ActionMapping mapping) {        // handle special parameter prefixes.        Set<String> uniqueParameters = new HashSet<String>();        Map parameterMap = request.getParameterMap();        for (Object o : parameterMap.keySet()) {            String key = (String) o;            // Strip off the image button location info, if found            if (key.endsWith(".x") || key.endsWith(".y")) {                key = key.substring(0, key.length() - 2);            }            // Ensure a parameter doesn't get processed twice            if (!uniqueParameters.contains(key)) {                ParameterAction parameterAction = (ParameterAction) prefixTrie.get(key);                if (parameterAction != null) {parameterAction.execute(key, mapping);                    uniqueParameters.add(key);                    break;                }            }        }

 

Continue with the process. The operation before the red code segment is to extract special parameters from the parameters passed in by the user, and the red code is to process this parameter. The DefaultActionMapper class defines different execute methods for four different special parameters. Here we only look at the method for processing the redirect parameter and look at its code:
public void execute(String key, ActionMapping mapping) {                        ServletRedirectResult redirect = new ServletRedirectResult();                        container.inject(redirect);                        redirect.setLocation(key.substring(REDIRECT_PREFIX                                .length()));                        mapping.setResult(redirect);                    }

 

The code is relatively simple, that is, to create a ServletRedirectResult object, insert the user-input parameter value to its Location attribute, and finally overwrite the ing result property. The key point of the problem is in the result attribute. After Struts processes the action, the returned content is dependent on the content in the result attribute. This attribute is usually set through the configuration file, but here, you can control the content of this attribute through redirect. In addition, the conditionalParse method used to parse the returned content uses the translateVariables method to process parameters. This method uses its parameters as Ognl expressions and triggers this vulnerability. The code for the conditionalParse method is as follows:
protected String conditionalParse(String param, ActionInvocation invocation) {        if (parse && param != null && invocation != null) {            return TextParseUtil.translateVariables(param, invocation.getStack(),                    new TextParseUtil.ParsedValueEvaluator() {                        public Object evaluate(String parsedValue) {                            if (encode) {                                if (parsedValue != null) {                                    try {                                        // use UTF-8 as this is the recommended encoding by W3C to                                        // avoid incompatibilities.                                        return URLEncoder.encode(parsedValue, "UTF-8");                                    }                                    catch(UnsupportedEncodingException e) {                                        if (LOG.isWarnEnabled()) {                                            LOG.warn("error while trying to encode ["+parsedValue+"]", e);                                        }                                    }                                }                            }                            return parsedValue;                        }            });        } else {            return param;        }    }

 

This should be detailed enough.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.