WEB攻防-通用漏洞&PHP反序列化&POP链构造&魔术方法&原生类

知识点

1、什么是序列化与反序列化&php函数

序列化:对象转换为数组或者字符串的格式----将对象转换为字符串或者数组的格式,为了更加方便完整的传递数据,同时也不会再出现占用数据的问题,让数据更加稳定有效并且可以更方便的进行跨平台存储和网络传输。

反序列化:将数组或字符串等格式转换成对象

serialize():将一个对象转换成字符串

unserialize:将字符串还原成一个对象

2、为什么会出现安全漏洞

在php中会存在一些魔术方法,在满足某个条件时会优先触发这些方法,当这些魔术方法使用不当时,就有可能造成反序列化漏洞。

3、反序列化漏洞如何发现

主要以白盒为主,分析代码逻辑。

4、反序列化方法的利用

魔术方法的调用逻辑-如触发条件

-语言原生类的调用逻辑-如SoapClient--可以简单理解为php语言本身携带的类

-语言自身的安全缺陷-如CVE-2016-7124,是__wakeup魔术方法的漏洞,该方法在调用unserilize()方法前则先调用__wakeup方法,但是序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行

5、序列化&反序列化代码演示

序列化:

 

反序列化字符串的介绍:objeck 长度 demotest 3各变量 string 类型长度 name,后面内容都为类型、长度、内容。

 

反序列化: 

 

PHP反序列漏洞

未对用户的反序列化字符串进行有效地过滤,导致攻击者可以控制反序列化的过程,从而让代码执行触发漏洞,并在反序列化过程中触发某些魔术方法导致漏洞。

魔术方法利用点分析

__construct(): //构造函数,当对象new的时候会自动调用

__destruct()//析构函数当对象被销毁时会被自动调用,通常对象new结束后会自动销毁

__wakeup(): //unserialize()时会被自动调用

__invoke(): //当尝试以调用函数的方法调用一个对象时,会被自动调用

__call(): //在对象上下文中调用不可访问的方法时触发

__callStatci(): //在静态上下文中调用不可访问的方法时触发

__get(): //用于从不可访问的属性读取数据

__set(): //用于将数据写入不可访问的属性

__isset(): //在不可访问的属性上调用isset()或empty()触发

__unset(): //在不可访问的属性上使用unset()时触发

__toString(): //把类当作字符串使用时触发

__sleep(): //serialize()函数会检查类中是否存在一个魔术方法__sleep() 如果存在,该方法会被优先调用

举例

代码

<?php

//序列化&反序列化

class demotest{

 public $name='xiaodi';

 public $sex='man';

 public $age='29';

}

$example=new demotest();

$s=serialize($example);//序列化

$u=unserialize($s);//反序列化

echo $s.'<br>';

var_dump($u);

echo '<br>';

序列化://O:8:"demotest":3:{s:4:"name";s:6:"xiaodi";s:3:"sex";s:3:"man";s:3:"age";s:2:"29";}

反序列化://object(demotest)#2 (3) { ["name"]=> string(6) "xiaodi" ["sex"]=> string(3) "man" ["age"]=> string(2) "29" }

安全问题

class A{
    public $var='echo test';
    public function test(){
        echo $this->var;
    }
 public function __destruct(){
        echo 'x'.'<br>';
    }
 public function __construct(){
 echo '__construct'.'<br>';
 }
 public function __toString(){
 return '__toString'.'<br>';
 }
}

// 正常触发函数和魔术访问

//$a=new A();//触发__construct

//$a->test();//触发test

//触发__destruct:当创建对象会被自动销毁后触发__destruct

//echo $a;//触发__toString  当把对象a直接输出是会输出__toString魔术方法。

 

// 反序列化触发

x=('O:1:"A":1:{s:3:"var";s:9:"echo test";}'); 

//$t=unserialize($_GET['x']); 

//在反序列化中填入A类的序列化字符串,那么可以理解成$t此时就是A类的对象,如果后续没有操作则自动销毁对象,直接触发_destruct魔术方法    输出结果:x

$t->test();   // 利用反序列化之后的变量可以直接调用类里存在的函数,调用结束后对象被销毁触发__destruct方法   输出结果:echo testx

echo $t;  // 同时直接输出$t也可以直接触发__toString魔术方法

漏洞出现

class B{

     public function __destruct(){

        system('ipconfig');

    }

     public function __construct(){

     echo 'xiaodisec'.'<br>';

 }

}

$b=new b();    
echo serialize($b);  
unserialize($_GET[x]);

//函数引用,无对象创建触发魔术方法

//$b=new b();    正常创建对象,通过对象可以执行两个魔术方法

//echo serialize($b);   获取序列化字符串

 

//?x=O:1:"B":0:{}   

unserialize($_GET[x]);   // 将获取的序列化字符串进行反序列化让x参数进行接受,那么就可以直接执行__destruct方法也就自动执行了ipconfig

 

漏洞核心

获取反序列化的数据后,可以通过修改反序列化字符串里面的数值,在程序进行序列化过程中,就会执行代码并造成影响。

class C{
    public $cmd='ipconfig';
    public function __destruct(){
         system($this->cmd);
    }
    public function __construct(){
    echo 'xiaodisec'.'<br>';
 }
}
$c=new C();
echo serialize($c);   获取序列化值:O:1:"C":1:{s:3:"cmd";s:8:"ipconfig";}
unserialize($_GET[c]);

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值