一、Pikachu 反序列化漏洞通关与漏洞原理
1. 反序列化漏洞核心原理
反序列化漏洞的本质是程序对不可信的反序列化输入未做严格校验,且被反序列化的类中存在__wakeup()、__destruct()、__toString()等 PHP 魔术方法。攻击者可构造恶意序列化字符串,让反序列化过程激活魔术方法的链式调用,自动执行其中的危险代码,从而实现恶意操作。
2. Pikachu 反序列化漏洞实战通关
Pikachu 漏洞练习平台的 PHP 反序列化漏洞模块,核心是通过构造指定的序列化字符串提交到目标接口,触发前端 XSS 弹窗完成通关,具体步骤如下:
首先pikachu反序列化漏洞是可以用php代码写的一个框架,输入到

<?php
class S{
var $test = "<script>alert('XSS by Pikachu');</script>";
}
$obj = new S();
echo serialize($obj);
// 输出:O:1:"S":1:{s:4:"test";s:35:"<script>alert('XSS by Pikachu');</script>";}
?>
写一个php代码执行,序列话后的代码为:O:1:"S":1:{s:4:"test";s:41:"<script>alert('XSS by Pikachu');</script>";}
O:1:"S":1:{s:4:"test";s:41:"<script>alert('XSS by Pikachu');</script>";}
查看皮卡丘的源代码可以发现 
有童鞋会问:可不可以执行其他的代码,答案不可以,这段代码中只有 echo/ 字符串拼接操作,没有 eval()、system()、assert() 等能执行 PHP 代码的危险函数;
$unser->test 只是作为字符串被输出到页面,即便你把 test 的值设为 phpinfo();,页面也只会显示字符串 "phpinfo ();",而不会执行这个 PHP 函数。
编写java代码,演示继承重写的作用
实现思路
定义一个父类(比如Animal),包含通用属性和方法(比如name和makeSound())
定义多个子类(比如Dog、Cat)继承父类,重写父类的makeSound()方法,实现各自特有的行为
通过测试类调用不同子类的方法,展示重写的效果
// 父类:动物类,定义通用属性和方法
class Animal {
protected String name; // 受保护的属性,子类可直接访问
// 构造方法
public Animal(String name) {
this.name = name;
}
// 通用方法:发出声音(父类的默认实现)
public void makeSound() {
System.out.println(name + " 发出了某种声音");
}
// 父类的其他通用方法
public void eat() {
System.out.println(name + " 在吃东西");
}
}
// 子类:狗类,继承Animal
class Dog extends Animal {
// 子类构造方法,必须调用父类构造方法
public Dog(String name) {
super(name); // super关键字调用父类构造方法
}
// 重写父类的makeSound方法,实现狗的特有行为
@Override // 注解标识这是重写的方法,编译器会检查语法正确性
public void makeSound() {
System.out.println(name + " 汪汪汪地叫");
}
// 子类独有的方法(继承之外的扩展)
public void fetch() {
System.out.println(name + " 去捡球了");
}
}
// 子类:猫类,继承Animal
class Cat extends Animal {
public Cat(String name) {
super(name);
}
// 重写父类的makeSound方法,实现猫的特有行为
@Override
public void makeSound() {
System.out.println(name + " 喵喵喵地叫");
}
}
// 测试类
public class InheritanceOverrideDemo {
public static void main(String[] args) {
// 创建父类对象
Animal genericAnimal = new Animal("普通动物");
genericAnimal.makeSound(); // 调用父类默认方法
genericAnimal.eat(); // 调用父类通用方法
System.out.println("————————");
// 创建子类Dog对象
Dog dog = new Dog("旺财");
dog.makeSound(); // 调用重写后的方法
dog.eat(); // 继承父类的方法
dog.fetch(); // 子类独有的方法
System.out.println("————————");
// 创建子类Cat对象
Cat cat = new Cat("咪宝");
cat.makeSound(); // 调用重写后的方法
cat.eat(); // 继承父类的方法
// 多态演示(继承重写的核心价值之一)
System.out.println("————————");
Animal animal1 = new Dog("来福");
Animal animal2 = new Cat("小花");
animal1.makeSound(); // 实际调用Dog的makeSound
animal2.makeSound(); // 实际调用Cat的makeSound
}
}
使用IntelliJ IDEA编写java重构

但是提示:类 InheritanceOverrideDemo 是公共的,应在名为 InheritanceOverrideDemo.java 的文件中声明
这是 Java 语法的强制规范:
-
被 public 修饰的类,其类名必须与文件名完全一致(包括大小写)
-
你当前的文件名是 Main.java,但公共类名是 InheritanceOverrideDemo,二者不匹配,导致编译失败
-
修复:修改文件名,符合 Java 规范
-
在左侧项目结构中,右键点击 Main.java
-
选择「重构」,右击重命名,将文件名改为 InheritanceOverrideDemo.java

-
确认后,代码即可正常编译运行

父类引用指向子类对象,调用重写方法时,会执行**子类的实现**,这是继承 + 重写带来的多态特性,也是面向对象 “开闭原则” 的体现(新增动物类时,只需继承 Animal 并重写方法,无需修改原有代码)。





