文件下载
首先git上下载包。
1 | git clone https://github.com/apache/dubbo-spring-boot-project |
将整个项目导入IDEA
PS:在dubbo-spring-boot-samples/auto-configure-samples/provider-sample/pom.xml需要有如下依赖
这里有几个坑,也值得学习:
直接打开项目没有Project文件只显示个pom
solved:配置项目,File—Project Structure–Modules–增加项目目录
Spring-Boot无法识别到主类
solved:全部导入后识别到5个主类入口
只能选择DubboExternalizedConfigurationProviderBootstrap,否则会报错。
启动环境
搭建完成直接启动环境即可
攻击Dubbo服务
dubbo默认运行在12345端口,这里可通过dubbo-spring-boot-samples\externalized-configuration-samples\provider-sample\src\main\resources\application.properties进行修改,这里我修改为了12317端口。
由于dubbo开放的端口不包含WEB服务,因此对于Fofa的dork为:port:12345 && protocol != “http” && protocol != “https”
代码执行问题
com.sun.rowset.JdbcRowSetImpl在JDK 6u132, 7u122, or 8u113及之后的版本被修复了,可以换低版本jdk尝试。
因此如果想看到弹窗需要使用<8u113(dubbo不兼容7版本)
使用8u202现象,可用发起ldap请求,但是Send LDAP reference result返回后不会请求Exploit.class文件:
遂使用8u66:
POC
1 | from dubbo.codec.hessian2 import Decoder,new_object |
代码分析
在如下报错代码断点org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol#getInvoker
org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation#decode(org.apache.dubbo.remoting.Channel, java.io.InputStream) 48行
继续跟入F7进入org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation#decode(org.apache.dubbo.remoting.Channel, java.io.InputStream)函数
在89行存在readObject函数,但是注意这里是CodecSupport.getSerialization对象取得的,而不是ObjectInputStream的readObject,用了多态让父类型ObjectInput来接的,跟进89行的in.readObject,进入到了
org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput#readObject(java.lang.Class
可知CodecSupport.getSerialization返回的对象是Hessian2ObjectInput,再继而调了com.alibaba.com.caucho.hessian.io.Hessian2Input#readObject(java.lang.Class)
当前反序列化链:
1 | org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation#decode(org.apache.dubbo.remoting.Channel, java.io.InputStream) |
在com.alibaba.com.caucho.hessian.io.Hessian2Input#readObject(java.lang.Class)继续调用自身三参数的readObject,在1877打个断点,后面涉及switch
进入1880的return this.readObject(expectedClass),在该文件重复调用几次readObject后返回
进入com.alibaba.com.caucho.hessian.io.JavaDeserializer.ObjectFieldDeserializer
当前反序列化链:
1 | org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation#decode(org.apache.dubbo.remoting.Channel, java.io.InputStream) |
in是com.alibaba.com.caucho.hessian.io.JavaDeserializer的实例,进入后调用JavaDeserializer.FieldDeserializer的deserialize方法
然后循环进入switch、最后在case127出去,进入2004行com.alibaba.com.caucho.hessian.io.Hessian2Input#findSerializerFactory
返回com/alibaba/com/caucho/hessian/io/Hessian2Input.class:2005
返回后来到com.alibaba.com.caucho.hessian.io.JavaDeserializer#readObject(com.alibaba.com.caucho.hessian.io.AbstractHessianInput, java.lang.Object, java.lang.String[])
得到反序列化链
1 | org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation#decode(org.apache.dubbo.remoting.Channel, java.io.InputStream) |