下载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漏洞
修复方式: