Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2022-29464 — Exploit for CVE-2022-29464, an unauthenticated arbitrary file upload in WSO2 servers enabling remote code execution via malicious JSP uploads. | Kitploit
Tools/GitHubGitHub/devengpk/cve-2022-29464
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingRed TeamingPayload Development
GitHubdevengpk/cve-2022-29464

CVE-2022-29464

Exploit for CVE-2022-29464, an unauthenticated arbitrary file upload in WSO2 servers enabling remote code execution via malicious JSP uploads.

View Repository
13 years agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

WSO2 RCE (CVE-2022-29464) exploit and writeup.

Details

CVE-2022-29464 is a serious flaw in WSO2. The flaw is an unauthorised, unconstrained arbitrary file upload that enables unauthorised users to upload malicious JSP files to WSO2 servers and get Remote Code Execution (RCE).

the vulerable upload route is /fileupload which is handled by FileUploadServlet servlet. and it is unprotected route by IAM as we can see in the indentity.xml configuration file:

<Resource context="(.*)/fileupload(.*)" secured="false" http-method="all"/>

The function 'handleSecurity()' is in charge of safeguarding the various routes provided by WSO2 and offers a mechanism for performing security checks on the received HTTP requests. 'handleSecurity()' will call 'CarbonUILoginUtil.handleLoginPageRequest(),' and based on its return value, it will be decided whether to grant or deny access to the requested URI:

    public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
	[snipped]
        if ((val = CarbonUILoginUtil.handleLoginPageRequest(requestedURI, request, response,
                authenticated, context, indexPageURL)) != CarbonUILoginUtil.CONTINUE) {
            if (val == CarbonUILoginUtil.RETURN_TRUE) {
                return true;
            } else {
                return false;
            }
        }
	[snipped]
    }

CarbonUILoginUtil.handleLoginPageRequest() returns CarbonUILoginUtil.RETURN_TRUE when the route is /fileupload:

    protected static int handleLoginPageRequest(String requestedURI, HttpServletRequest request,
            HttpServletResponse response, boolean authenticated, String context, String indexPageURL)
            throws IOException {
        boolean isTryIt = requestedURI.indexOf("admin/jsp/WSRequestXSSproxy_ajaxprocessor.jsp") > -1;
        boolean isFileDownload = requestedURI.endsWith("/filedownload");
        if ((requestedURI.indexOf("login.jsp") > -1
                || requestedURI.indexOf("login_ajaxprocessor.jsp") > -1
                || requestedURI.indexOf("admin/layout/template.jsp") > -1
                || isFileDownload
                || requestedURI.endsWith("/fileupload")
                || requestedURI.indexOf("/fileupload/") > -1
                || requestedURI.indexOf("login_action.jsp") > -1
                || isTryIt
                || requestedURI.indexOf("tryit/JAXRSRequestXSSproxy_ajaxprocessor.jsp") > -1)
                && !requestedURI.contains(";")) {

            if ((requestedURI.indexOf("login.jsp") > -1
                    || requestedURI.indexOf("login_ajaxprocessor.jsp") > -1 || requestedURI
                    .indexOf("login_action.jsp") > -1) && authenticated) {
                [snipped]
            } else if ((isTryIt || isFileDownload) && !authenticated) {
                [snipped]
            } else if (requestedURI.indexOf("login_action.jsp") > -1 && !authenticated) {
                [snipped]
            } else {
				if (log.isDebugEnabled()) {
					log.debug("Skipping security checks for " + requestedURI);
				}
                return RETURN_TRUE;
            }
        }

        return CONTINUE;
    }

with CarbonUILoginUtil.handleLoginPageRequest() returning CarbonUILoginUtil.RETURN_TRUE, handleSecurity() will return true, the access will be then granted to /fileupload without authentication.

the FileUploadServlet servlet and upon init() and through a series of method calls loads eventually from the carbon.xml configuration file multiple upload file formats/actions along with the object which hanldes every format.

    public void init(ServletConfig servletConfig) throws ServletException {
        this.servletConfig = servletConfig;
        try {
            fileUploadExecutorManager = new FileUploadExecutorManager(bundleContext, configContext, webContext);
            //Registering FileUploadExecutor Manager as an OSGi service
            bundleContext.registerService(FileUploadExecutorManager.class.getName(), fileUploadExecutorManager, null);
        } catch (CarbonException e) {
            log.error("Exception occurred while trying to initialize FileUploadServlet", e);
            throw new ServletException(e);
        }
    }

the FileUploadExecutorManager class constructor is as follows:

    public FileUploadExecutorManager(BundleContext bundleContext,
                                     ConfigurationContext configCtx,
                                     String webContext) throws CarbonException {
        this.bundleContext = bundleContext;
        this.configContext = configCtx;
        this.webContext = webContext;
        this.loadExecutorMap();
    }

the constructor calls the private method loadExecutorMap() which is where the configuration loading is done:

    private void loadExecutorMap() throws CarbonException {
        [snipped]
                try {
            documentElement = XMLUtils.toOM(serverConfiguration.getDocumentElement());
        } catch (Exception e) {
            String msg = "Unable to read Server Configuration.";
            log.error(msg);
            throw new CarbonException(msg, e);
        }
        [snipped]
        OMElement fileUploadConfigElement =
                documentElement.getFirstChildWithName(
                        new QName(ServerConstants.CARBON_SERVER_XML_NAMESPACE, "FileUploadConfig"));
        for (Iterator iterator = fileUploadConfigElement.getChildElements(); iterator.hasNext();) {
            OMElement mapppingElement = (OMElement) iterator.next();
            if (mapppingElement.getLocalName().equalsIgnoreCase("Mapping")) {
                OMElement actionsElement =
                        mapppingElement.getFirstChildWithName(
                                new QName(ServerConstants.CARBON_SERVER_XML_NAMESPACE, "Actions"));
                String confPath = System.getProperty(CarbonBaseConstants.CARBON_CONFIG_DIR_PATH);
        [snipped]

the file upload formats configurations is within the FileUploadConfig namespace in the XML configuration file, this is the default configuration:

    <FileUploadConfig>
        <!--
           The total file upload size limit in MB
        -->
        <TotalFileSizeLimit>100</TotalFileSizeLimit>

        <Mapping>
            <Actions>
                <Action>keystore</Action>
                <Action>certificate</Action>
                <Action>*</Action>
            </Actions>
            <Class>org.wso2.carbon.ui.transports.fileupload.AnyFileUploadExecutor</Class>
        </Mapping>
Download Tool