php反序列化总结&刷题&pop链&原生类

思维导图

php反序列化总结&刷题&pop链&原生类_第1张图片

原理

未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,一个反序列化漏洞造成要有魔术方法,恰好魔术方法里面有危险函数,比如危险函数文件读取,命令执行,反序列化在数据传递,可能触发危险函数

知识点

1、什么是反序列化操作?-格式转换
2、为什么会出现安全漏洞?-魔术方法
3、反序列化漏洞如何发现? -对象逻辑
4、反序列化漏洞如何利用?-POP链构造
补充:反序列化利用大概分类三类
魔术方法的调用逻辑-如触发条件
语言原生类的调用逻辑-如SoapClient
语言自身的安全缺陷-如CVE-2016-7124

序列化:对象转换为数组或字符串等格式
反序列化:将数组或字符串等格式转换成对象
serialize()//将一个对象转换成一个字符串
unserialize()//将字符串还原成一个对象

方便记忆以后记忆 反序列化就是加un的

反序列化一般是在白盒里面,就是代码给到你的情况下分析,在黑盒里面发现几乎不可能的

class info{
   
  	public $name='qian';
  	public $age=18;
}
O:4:"info":2:(s:4:"name";s:4:"qian";s:3:"age";i:2:18;}
object 长度 info 2个变量 string类型 长度 name 



class info{
   
  	public $name;
  	public 19;
}

基础

php反序列化总结&刷题&pop链&原生类_第2张图片

php反序列化总结&刷题&pop链&原生类_第3张图片

触发:unserialize函数的变量可控,文件中存在可利用的类,类中有魔术方法:
__construct(): //构造函数,当对象new的时候会自动调用
__destruct()//析构函数当对象被销毁时会被自动调用
__wakeup(): //unserialize()时会被自动调用
__invoke(): //当尝试以调用函数的方法调用一个对象时,会被自动调用
__call(): //在对象上下文中调用不可访问的方法时触发
__callStatci(): //在静态上下文中调用不可访问的方法时触发
__get(): //用于从不可访问的属性读取数据
__set(): //用于将数据写入不可访问的属性
__isset(): //在不可访问的属性上调用isset()或empty()触发
__unset(): //在不可访问的属性上使用unset()时触发
__toString(): //把类当作字符串使用时触发
__sleep(): //serialize()函数会检查类中是否存在一个魔术方法__sleep() 如果存在,该方法会被优先调用

对象变量属性:

public(公共的):在本类内部、外部类、子类都可以访问

protect(受保护的):只有本类或子类或父类中可以访问

private(私人的):只有本类内部可以使用

序列化数据显示:

private属性序列化的时候格式是 *%00类名%00成员名* 在原本上加2

protect属性序列化的时候格式是 *%00*%00成员名* 在原本上加3

为了区分公有私有保护 ,让人很容易看出来是什么类型的


header("Content-type: text/html; charset=utf-8");
//public private protected说明
class test{
   
    public $name="xiaodi";
    private $age="29"; //两个%00,在原本上加2 就是9个  
    protected $sex="man"; //两个%00一个*, 在原本上加3 就是6个
}
$a=new test();
$a=serialize($a);
print_r($a);

?> 

php反序列化总结&刷题&pop链&原生类_第4张图片

1.安全问题

class A{
   
  public $var='echo test';
  public function test(){
   
      echo $this->var;
  }
  public function __destruct(){
    //对象被销毁会被调用,  疑问?没有看见销毁代码啊.其实程序执行结束都会自动销毁
      echo '__destruct'.'
'
; } public function __construct(){ //当对象new的时候会调用 echo '__construct'.'
'
; } public function __toString(){ return '__toString'.'
'
; } } $a=new A(); ?> //无需函数,创建对象触发魔术方法

访问结果

php反序列化总结&刷题&pop链&原生类_第5张图片

2.安全问题

class A{
   
  public $var='echo test';
  public function test(){
   
      echo $this->var;
  }
  public function __destruct(){
    //对象被销毁会被调用
      echo '__destruct'.'
'
; } public function __construct(){ //当对象new的时候会调用 echo '__construct'.'
'
; } public function __toString(){ return '__toString'.'
'
; } } $a=new A(); echo serialize($a).'
'
; //输入反序列化结果 ?>

php反序列化总结&刷题&pop链&原生类_第6张图片

3.安全问题

class A{
   
  public $var='echo test';
  public function test(){
   
      echo $this->var;
  }
  public function __destruct(){
    //对象被销毁会被调用
      echo '__destruct'.'
'
; } public function __construct(){ //当对象new的时候会调用 echo '__construct'.'
'
; } public function __toString(){ return '__toString'.'
'
; } } $t=unserialize($_GET['x']); ?> //触发__destruct
http://127.0.0.1/demo.php?x=O:1:“A”:1:{
   s:3:“var”;s:9:“echo test”;} 
相当于传递public $var=‘echo test’;

虽然没有new对象,但是传递了数据,只要传递数据,程序就会执行,执行就有销毁,触发__destruct()函数

php反序列化总结&刷题&pop链&原生类_第7张图片

4.安全问题

class A{
   
  public $var='echo test';
  public function test(){
   
      echo $this->var;
      echo '
'
; } public function __destruct(){ echo '__destruct'.'
'
; } public function __construct(){ echo '__construct'.'
'
; } public function __toString(){ return '__toString'.'
'
; } } $a=new A(); $a->test(); //触发test 前提是new了一个对象,才可以指向test方法 ?>

php反序列化总结&刷题&pop链&原生类_第8张图片

5.安全问题toString

class A{
   
  public $var='echo test';
  public function test(){
   
      echo $this->var;
      echo '
'
; } public function __destruct(){ echo '__destruct'.'
'
; } public function __construct(){ echo '__construct'.'
'
; } public function __toString(){ return '__toString'.'
'
; } } $a=new A(); echo $a;//触发__toString __toString触发条件:把类当作字符串使用时触发 echo输出的都是字符串 ?>

php反序列化总结&刷题&pop链&原生类_第9张图片

6.安全问题

class B{
   
  public function __destruct(){
   
  	system('ipconfig');
  }
  public function __construct(){
   
  	echo 'qian'.'
'
; } } $b=new b(); //执行__destruct和__construct echo serialize($b); //输出O:1:"B":0:{} ?>

php反序列化总结&刷题&pop链&原生类_第10张图片

7.安全问题

class B{
   
  public function __destruct(){
   
  	system('ipconfig');
  }
  public function __construct(){
   
  	echo 'qian'.'
'
; } } //$b=new b(); //执行__destruct和__construct //echo serialize($b); //输出O:1:"B":0:{} unserialize($_GET[x]); //传递O:1:"B":0:{} 执行ipconfig ?>

php反序列化总结&刷题&pop链&原生类_第11张图片

8.安全问题 关键点

class C{
   
  public $cmd='ipconfig';
  public function __destruct(){
   
  	system($this->cmd);
  }
  public function __construct(){
   
  	echo 'qian'.'
'
; } } //函数引用,无对象创建触发魔术方法自定义变量 unserialize($_GET[c]); //?c=O:1:"C":1:{s:3:"cmd";s:3:"ver";} 修改$cmd的参数,让其执行其它命令,这也是反序列化的核心点 ?>

php反序列化总结&刷题&pop链&原生类_第12张图片


12种魔术方法案例


header("Content-type: text/html; charset=utf-8");
//__construct __destruct 魔术方法 创建调用__construct 2种销毁调用__destruct
class Test{
   
    public $name;
    public $age;
    public $string;
    // __construct:实例化对象时被调用.其作用是拿来初始化一些值。
    public function __construct($name, $age, $string){
   
        echo "__construct 初始化"."
"

你可能感兴趣的:(网络安全,php,开发语言)