
CVE-2022-29464 के लिए एक्सप्लॉइट और तकनीकी राइटअप, जो WSO2 सर्वरों में दुर्भावनापूर्ण JSP अपलोड के माध्यम से रिमोट कोड एक्ज़ीक्यूशन की ओर ले जाने वाला एक बिना प्रमाणीकरण वाला आर्बिट्रेरी फ़ाइल अपलोड है।
WSO2 RCE (CVE-2022-29464) एक्सप्लॉइट और राइटअप।
CVE-2022-29464 WSO2 पर एक गंभीर कमजोरी है जिसे Orange Tsai ने खोजा। यह कमजोरी एक बिना प्रमाणीकरण वाला, अप्रतिबंधित मनमाना फ़ाइल अपलोड है, जो बिना प्रमाणीकरण वाले हमलावरों को दुर्भावनापूर्ण JSP फ़ाइलें अपलोड करके WSO2 सर्वर पर RCE प्राप्त करने की अनुमति देती है।
कमजोर अपलोड मार्ग /fileupload है, जिसे FileUploadServlet सर्वलेट द्वारा संभाला जाता है। और यह IAM द्वारा असुरक्षित मार्ग है, जैसा कि हम indentity.xml कॉन्फ़िगरेशन फ़ाइल में देख सकते हैं:```xml
और डिफ़ॉल्ट लॉगिन उपाय द्वारा भी असुरक्षित, `handleSecurity()` WSO2 द्वारा प्रदान किए जाने वाले विभिन्न रूट्स को सुरक्षित करने के लिए ज़िम्मेदार फ़ंक्शन है और प्राप्त HTTP अनुरोधों पर सुरक्षा जाँच करने के लिए एक तंत्र प्रदान करता है, `handleSecurity()` `CarbonUILoginUtil.handleLoginPageRequest()` को कॉल करेगा और इसके रिटर्न मान के आधार पर अनुरोधित URI तक पहुँच की अनुमति या अस्वीकृति का निर्णय लिया जाएगा:```java
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() जब रूट /fileupload होता है तो CarbonUILoginUtil.RETURN_TRUE लौटाता है:```java
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;
}
जब `CarbonUILoginUtil.handleLoginPageRequest()` `CarbonUILoginUtil.RETURN_TRUE` लौटाता है, तो `handleSecurity()` `true` लौटाएगा, जिसके बाद बिना प्रमाणीकरण के `/fileupload` तक पहुँच प्रदान कर दी जाएगी।
`FileUploadServlet` सर्वलेट [`init()`](https://github.com/wso2/carbon-kernel/blob/d47232dfb2b26c0ef18a74e2ef4aa503caa59697/core/org.wso2.carbon.ui/src/main/java/org/wso2/carbon/ui/transports/FileUploadServlet.java#L71) पर और विधि कॉलों की एक श्रृंखला के माध्यम से अंततः `carbon.xml` कॉन्फ़िगरेशन फ़ाइल से कई अपलोड फ़ाइल स्वरूपों/क्रियाओं को उस ऑब्जेक्ट के साथ लोड करता है जो प्रत्येक स्वरूप को संभालता है।```java
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);
}
}
FileUploadExecutorManager क्लास का कंस्ट्रक्टर इस प्रकार है:```java
public FileUploadExecutorManager(BundleContext bundleContext,
ConfigurationContext configCtx,
String webContext) throws CarbonException {
this.bundleContext = bundleContext;
this.configContext = configCtx;
this.webContext = webContext;
this.loadExecutorMap();
}
कंस्ट्रक्टर निजी विधि [`loadExecutorMap()`](https://github.com/wso2/carbon-kernel/blob/d47232dfb2b26c0ef18a74e2ef4aa503caa59697/core/org.wso2.carbon.ui/src/main/java/org/wso2/carbon/ui/transports/fileupload/FileUploadExecutorManager.java#L131) को कॉल करता है, जहाँ कॉन्फ़िगरेशन लोडिंग की जाती है:```java
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]
फ़ाइल अपलोड प्रारूप कॉन्फ़िगरेशन XML कॉन्फ़िगरेशन फ़ाइल में FileUploadConfig नेमस्पेस के अंतर्गत है, यह डिफ़ॉल्ट कॉन्फ़िगरेशन है:```xml
100
<Mapping>
<Actions>
<Action>keystore</Action>
<Action>certificate</Action>
<Action>*</Action>
</Actions>
<Class>org.wso2.carbon.ui.transports.fileupload.AnyFileUploadExecutor</Class>
</Mapping>