下载5.0.2的版本来分析
5.0.2的war包地址 http://archive.apache.org/dist/roller/roller-5/v5.0.2/bin/roller-weblogger-5.0.2-for-javaee.zip
从web.xml入手分析,可以看到如下servlet映射
<servlet> <servlet-name>XmlRpcServlet</servlet-name> <servlet-class>org.apache.xmlrpc.webserver.XmlRpcServlet</servlet-class> <init-param> <description> Sets, whether the servlet supports vendor extensions for XML-RPC. </description> <param-name>enabledForExtensions</param-name> <param-value>true</param-value> </init-param> </servlet>
指向org.apache.xmlrpc.webserver.XmlRpcServlet的类。
从doPost看起
public void doPost(HttpServletRequest pRequest, HttpServletResponse pResponse) throws IOException, ServletException {
private XmlRpcServletServer server;
server.execute(pRequest, pResponse);
}
指向org.apache.xmlrpc.webserver.XmlRpcServletServer
public void execute(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException { XmlRpcHttpRequestConfigImpl config = getConfig(pRequest); ServletStreamConnection ssc = newStreamConnection(pRequest, pResponse); try { super.execute(config, ssc); } catch (XmlRpcException e) { throw new ServletException(e); } }
看到super.execute(config, ssc); 这行指向父类的execute方法
public class XmlRpcServletServer extends XmlRpcHttpServer
父类为XmlRpcHttpServer,在父类中没找到execute方法,继续向上调用XmlRpcStreamServer类
public abstract class XmlRpcHttpServer extends XmlRpcStreamServer
在XmlRpcStreamServer类存在execute方法
public void execute(XmlRpcStreamRequestConfig pConfig, ServerStreamConnection pConnection) throws XmlRpcException { log.debug("execute: ->"); try { Object result; Throwable error; InputStream istream = null; try { istream = getInputStream(pConfig, pConnection); XmlRpcRequest request = getRequest(pConfig, istream); result = execute(request); istream.close(); istream = null; error = null; log.debug("execute: Request performed successfully"); } catch (Throwable t) { logError(t); result = null; error = t; } finally { if (istream != null) { try { istream.close(); } catch (Throwable ignore) {} } }
.......//省略后面无关代码
}
看到其中的 XmlRpcRequest request = getRequest(pConfig, istream); ,调用当前类的getRequest方法。
protected XmlRpcRequest getRequest(final XmlRpcStreamRequestConfig pConfig, InputStream pStream) throws XmlRpcException { final XmlRpcRequestParser parser = new XmlRpcRequestParser(pConfig, getTypeFactory()); final XMLReader xr = SAXParsers.newXMLReader(); xr.setContentHandler(parser); .....//省略后面无关代码 }
在getRequest()方法中有这么一句:XMLReader xr = SAXParsers.newXMLReader();
public class SAXParsers { private static final SAXParserFactory spf; static { spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); spf.setValidating(false); } /** Creates a new instance of {@link XMLReader}. */ public static XMLReader newXMLReader() throws XmlRpcException { try { return spf.newSAXParser().getXMLReader(); } catch (ParserConfigurationException e) { throw new XmlRpcException("Unable to create XML parser: " + e.getMessage(), e); } catch (SAXException e) { throw new XmlRpcException("Unable to create XML parser: " + e.getMessage(), e); } } }
其中:
spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); spf.setValidating(false);
直接引用xml文档,没做访问限制,所有造成了xxe漏洞
修复方式: