Java是一个跨平台语言:
真正的Java语言的后缀就是.Java ,其他的后缀也属于Java文件
例如:xxx.jar的属于一个压缩包如果使用解压缩解压就会发现里面超多的xxxx.class字节码文件
例如:xxx.jsp 属于Java与HTML代码混写的文件
1.刚编写一个hello.Java文件(人能看懂的计算机是看不懂得)那么将Java文件进行编译成hello.class(机器能看懂的)
2.这个时候Linux系统或者window系统他们还是不能识别hello.class,那么将hello.class进行一个jdk(JVM),将文件转换成各平台能执行的文件进行执行。
JVM:
JVM是Java Virtual Machine(Java 虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
Test.java
public class Test {
public static void main(String[] args) {
Student stu1 = new Student();
//new xxx :新建了一个对象
stu1.talk();
//使用student 调用了一个talk
}
}
Person.java
public class Person {
public int age;
public String name;
public void talk(){
//void :返回的是空
System.out.println("Person 说话了");
}
}
public:作用域(允许其他类继承)
整体的是程序的内存空间,在运行程序时候直接会去CPU申请内存空间会直接从入口处进行执行。
入口在Java中就是main函数,数据$a是任何时候都可以调用不管是否加载其他函数占用的内存这个原
有的1000 的内存必须给予。在函数中调函数如果执行代码没有执行到调用的函数将不会执行也不会占
空间(如果执行到调用的函数这里是 “b()” 就会在外部开辟堆栈,运行执行完就会消失)
Student.java
public class Student extends Person{
// public int score;
// public void talk(){
// System.out.println("Student 说话了");
// }
如果我将上面注释的话这里没有定义talk,运行test.java 就会到student 继承的父类去调用talk(结果就显示person:说话了)
}
extents:实现类之间的继承关系。
public class Student extends Person{
}
上述代码中Student 继承了Person类,也就是说Person中的属性和函数我是可以使用的
需要重写反序列化方法满足解码和解密需求。
我在student中定义了一个talk。
Student.java
public class Student extends Person{
public int score;
public void talk(){
System.out.println("Student 说话了");
}
这里有定义talk,那么执行test.java 就会直接执行student的talk的内容
}
危险函数(runtime)如果不调用则不会产生问题往上去找找到一个b ()函数有调用了危险函数在往上找找到一个readobject();(反序列化函数会自动调用,每点一下就会反序列化一次)
readobject();在满足什么情况下调用了b()函数,而b()函数又满足什么条件调用了危险函数,此时就产生应用链。
shiro 例子:的输入一个账户和密码进行的一个过程
序列化-------》对称加密----------》base64 编码 怎样反序列化----->将数据base64 解码----->然后进行解密----->此时就显示序列化的数据------>再扔给系统自带的readobject进行反序列话,这就是为什么要重写。
序列化:
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Person p=new Person();
p.age=18;
p.name="lin";
serialize(p,"lin.bin");
public static void serialize(Object obj, String filePath) throws IOException {
try (FileOutputStream fileOut = new FileOutputStream(filePath);
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut)) {
objectOut.writeObject(obj);
}
}
public static Object deserialize(String filePath) throws IOException, ClassNotFoundException {
try (FileInputStream fileIn = new FileInputStream(filePath);
ObjectInputStream objectIn = new ObjectInputStream(fileIn)) {
return objectIn.readObject();
}
}
}
执行上述代码之后他讲自动生成一个lin.bin 文件
反序列化:
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Person p=new Person();
p.age=18;
p.name="lin";
serialize(p,"lin.bin");
System.out.println("反序列化结果:" + deserialize("lin.bin"));
}
public static void serialize(Object obj, String filePath) throws IOException {
try (FileOutputStream fileOut = new FileOutputStream(filePath);
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut)) {
objectOut.writeObject(obj);
}
}
public static Object deserialize(String filePath) throws IOException, ClassNotFoundException {
try (FileInputStream fileIn = new FileInputStream(filePath);
ObjectInputStream objectIn = new ObjectInputStream(fileIn)) {
return objectIn.readObject();
}
}
}
这是将序列化重写后进行反序列化的结果:
什么是反序列化漏洞?
PHP的反序列化和java的反序列化是两种不同的类型,序列化和反序列化本身没有漏洞点,只是为了实现数据的完整高效的传输。
PHP反序列漏洞是由于类里面的魔术方法调用了某个函数,该危险函数又调用了别的函数,最终执行到了危险函数的位置
JAVA反序列化漏洞是由于开发者重写了readObject方法,该readObject方法方法调用了别的方法,最终执行到了例如Transfrom方法的危险方法