java安全漫谈-反序列化-2
ysoserial根据不同的利用链生成命令可控的序列化数据 HashMap调用put触发DNS请求分析首先我们编写一个hashmap 12345678910111213package org.javasec.gadget;import java.net.MalformedURLException;import java.net.URL;import java.util.HashMap;public class urldns { public static void main(String[]args) throws MalformedURLException { URL url1 = new URL("https://1111.kngfrhti.requestrepo.com"); HashMap<Object, Object> map = new HashMap<>(); map.put(url1, "xxx"); ...
java安全漫谈-反序列化-1
引言在之前的RMI篇中,我们观察到RMI通信的核心是对象的序列化与反序列化。反序列化漏洞在安全领域声名显赫,几乎每种语言都曾因此受累。那么,一个核心问题是:为什么反序列化操作如此危险? 简单来说,当程序需要将网络或磁盘上的数据“还原”成一个内存中的对象时,如果这个“还原”过程本身可以被操纵,去执行攻击者预期的逻辑,漏洞就产生了。 漏洞根源为了理解漏洞的根源,我们首先要明白不同序列化方案的设计思路: **通用数据格式 (如 JSON/XML)**: 目标:跨语言、跨平台通信。 局限:通常只支持基本数据类型(字符串、数字、布尔等)。要传输一个“对象”,需要额外约定或使用扩展库(如Jackson/Fastjson)。 **语言原生序列化 (如 Java...
java安全漫谈-RMI-3
classAnnotations我们来彻底解释清楚 classAnnotations 是什么。 首先,请区分两个概念: Java代码中的注解(Annotation):比如 @Override, @RestController。这是你写在源代码里的。 Java序列化协议中的 classAnnotations:这是序列化数据流中的一个数据块,与上面的注解没有直接关系。 核心定义classAnnotations 是 Java 对象序列化后,在二进制数据流中,紧跟在类描述符(ClassDesc)之后的一个可选数据段。它的设计目的是为了让序列化框架能够在序列化一个类时,为这个类“额外附带”一些自定义信息。 你可以把它理解成序列化数据中的一个 “自定义备注字段”。 它在序列化数据流中的位置一个完整的对象在序列化流中的结构大致如下: 12345678910TC_OBJECT (0x73)└── TC_CLASSDESC (0x72) # 类描述符开始 ├── className # 类名 ├── serialVersionUID #...
java安全漫谈-RMI-2
攻击RMI攻击背景 Registry与Server位于同一JVM 攻击者能够访问目标RMI Registry服务 攻击者和Registry与Server不在同一JVM 攻击者可控的是自己的Client,只能于server远程通信 rebindRegistry攻击?1234567891011public class RmiServer { public static void main(String[] args) throws RemoteException, MalformedURLException { LocateRegistry.createRegistry(9090); System.out.println("RMI注册表-启动成功"); test t1= new testimpl(); Naming.rebind("rmi://100.10.24.123:9090/test",t1); ...
java安全漫谈-RMI-1
server先编写一个接口,必须继承Remote,定义一个方法,这个方法就是远程被调用的方法接口 12345678package org.javasec.RMI.rmi1;import java.rmi.Remote;import java.rmi.RemoteException;public interface test extends Remote { void printest(String str) throws RemoteException;} 再编写一个接口实现类 1234567891011121314package org.javasec.RMI.rmi1;import java.rmi.RemoteException;import java.rmi.server.UnicastRemoteObject;public class testimpl extends UnicastRemoteObject implements test { public testimpl() throws RemoteException...
java安全漫谈-反射-3
没有无参构造方法怎么实例化如果一个类没有无参构造方法,也没有类似单例模式里的静态方法,我们怎样通过反射实例化该类呢? 这就需要使用到getConstructor这个方法了,先反射获取构造方法,然后调用newInstance获取实例化对象,传入构造函数所需要的参数 12345678910111213141516package org.javasec.FirstReflect;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Arrays;import java.util.List;public class TestPro { static void test() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,...
java安全漫谈-反射-2
内部类就是存在于类的内部的类,叫内部类 123456789101112package org.javasec.FirstReflect;public class Main { public static void main(String[] args) throws Exception { //TestReflect2.test(); Outer o = new Outer(); Class<?> i2=Class.forName("org.javasec.FirstReflect.Outer$inner"); Outer.inner i1 = new Outer.inner(); } } 12345678910111213package org.javasec.FirstReflect;class Outer { static { ...
java安全漫谈-反射-1
获取类的方式 .class 根据类名,获取类的字面量引用,不会触发类加载 .getClass() 类已经被加载,已经实例化了该对象的情况下,根据类名获取类的信息,故该方法不会触发类加载过程 .forName() 根据类的全额限定名,寻找到该类,然后会触发类的加载过程(包括加载→链接→初始化)。注意调用forName并不会触发构造方法 代码调试 TestReflect.java 123456789101112131415161718192021package org.javasec.FirstReflect;import static java.lang.Class.forName;public class TestReflect { static void test() throws ClassNotFoundException { System.out.println("===.class-开始==="); Class<User> c1 =User.class; ...
java安全漫谈-类加载-0
生命周期加载(Loading) JVM查找并加载类的二进制数据 创建Class对象 不执行任何代码 链接(Linking) 验证:确保类文件格式正确 准备:为静态变量分配内存并设置默认值 解析:将符号引用转换为直接引用 初始化(Initialization)触发时机(首次以下情况发生时): 创建类的实例 (new) 调用类的静态方法 访问类的静态字段(非常量) 使用反射Class.forName() 初始化子类时父类未初始化 初始化顺序: 静态字段赋值 静态初始化块 类加载时机简单来说就是要使用到类的各种方法,字段时,反射获取类时就会加载类 具体来说比如:实例化一个类时,访问类的静态方法、静态字段,构造方法,员方法,成员变量以及反射forname获取类时会触发类加载机制 接下来通过代码感受一下类加载。先写一个java bean加上一些调试输出 User.java 123456789101112131415161718192021222324252627282930313233343536373839package...
一些Java小tricks的妙用
前言:分享煮波学习到的java安全小trick,也不是什么新东西纯记录,小白努力学java中…… unicode解析特性-编码这是一段打印当前时间的代码 1<%=new java.util.Date() %> 如果把它unicode编码之后还能正常执行吗 12<%--uniocde编码后--%><%=\u006e\u0065\u0077\u0020\u006a\u0061\u0076\u0061\u002e\u0075\u0074\u0069\u006c\u002e\u0044\u0061\u0074\u0065\u0028\u0029 %> 虽然编译器爆红,但是仍然能成功解析执行 这是为什么呢?相信熟悉的师傅都知道: Java 编译器在解析源码时,会优先处理 Unicode 转义符,会在真正执行代码之前的词法分析阶段将unicode编码的部分还原为其对应的字符。 而我们又知道,JSP会被转换为 Servlet 源码,再编译为字节码。此过程会继承 Java...

