Java安全
本文最后更新于 17 天前,其中的信息可能已经有所发展或是发生改变。

XXE

// 实例化DOM解析器工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setXIncludeAware(true);
dbf.setNamespaceAware(true);
// 获得DOM解析器对象
DocumentBuilder db = dbf.newDocumentBuilder();
String str = "<?xml version=\"1.0\" encoding=\"utf-8\"?> \n" +
        "<!DOCTYPE node [  \n" +
        "<!ENTITY goodies SYSTEM \"file:///C:/flag\"> ]> \n" +
        "<node>&goodies;</node>";
// 解析xml格式字符串
InputStream is = new FileInputStream("xxx.xml");
documentBuilder.parse(is);
documentBuilder.parse(new ByteArrayInputStream(str.getBytes()));

Java序列化与反序列化

https://www.bilibili.com/video/BV16h411z7o9?p=1

只有实现了Serializable或者Externalizable接口的类的对象才能被序列化为字节序列。

ObjectOutputStream代表对象输出流:

它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

ObjectInputStream代表对象输入流:

它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

静态成员变量是不能被序列化

transient 标识的对象成员变量不参与序列化

入口类:重写readObject、调用常见的函数、参数类型宽泛、JDK自带

调用链:gadget

执行类

Java反射+URLDNS链

https://www.bilibili.com/video/BV16h411z7o9?p=2

正射:知道类并创建;反射:不用New创建。

Person person = new Person();
class c = person.getClass();
c = Class.forName("Person");
// 反射就是操作Class

// 从原型Class里面实例化对象
c.newInstance(); // 无参实例化对象
Constructor personConstructor = c.getConstructor(String.class, int.class); //含参构造
Person p = personConstructor.newInstance("abc", 123); // 传参
// 获取类里面属性
Field[] personfields = c.getFields(); // 获取所有属性(只能获取public)
Field[] personfields = c.getDeclaredFields(); // 获取所有属性(包括private)
Field namefield = c.getField("name"); // 获得参数
namefield.set(p, "newName"); // 修改参数值(不能修改私有属性)
namefield.setAccessible(true); // 可以修改私有变量
// 调用类里面方法
Method[] personmethods = c.getMethods(); // 获取所有方法
Method actionmethod = c.getMethod("action", String.class); // 获取类,后面带上参数列表
actionmethod.invoke(p, "act"); // 调用函数
actionmethod.setAccessible(true); // 可以调用私有方法

动态代理

// 类加载器、要调用的接口、做的处理
Proxy.newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)

调用InvocationHandler的invoke方法,触发反序列化

类动态加载

类加载流程:加载→验证→准备→解析→初始化→使用→卸载。

初始化时调用静态代码块,实例化时调用构造代码块和无参构造函数。

Class.forName("Person") 触发初始化,调用静态代码块

ClassLoader cl = ClassLoader.getSystemClassLoader; Class.forName("Person", false, cl) 不触发初始化,c.newInstance();实例化触发。

双亲委派模型

ClassLoader cl = ClassLoader.getSystemClassLoader();
System.out.println(cl); //jdk.internal.loader.ClassLoaders$AppClassLoader@78308db1
cl.loadClass("Person"); //不进行初始化

加载流程:ClassLoader->SecureClassLoader->URLClassLoader->AppClassLoader
loadClass->findClass->defineClass(从字节码加载类)

JDK18ClassLoader机制(通过ApplicationClassLoader加载应用类):

Application调用loadClass,寻找父类BuiltinClassLoader的loadClass:

BuiltinClassLoader.loadClass调用loadClassOrNull,如果没有找到Class,调用parent(PlatformClassLoader)的loadClassOrNull。

PlatformClassLoader没有找到Class,调用parent(BootClassLoader)的loadClassOrNull。

define机制:

逻辑关系:Object->ClassLoader->SecureClassLoader->URLClassLoader->AppClassLoader。

漏洞利用

        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file:///D:\\")}); 
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("http://localhost:8888/")}); 
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("jar:file:///1.jar")}); 
        Class<?> c = urlClassLoader.loadClass("Test");
        c.newInstance();

URLClassLoader 任意类加载 http/jar/file

ClassLoader.defineClass 字节码加载任意类

Unsafe.defineClass 字节码加载任意类

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇