pikachu之php反序列化

pikachu之php反序列化

一、php对象和类

php面向对象编程:

对象:可以做一些事情。一个对象有状态、行为和标识三种属性。

:一个共享共同结构和行为的对象的集合。

每个类的定义都以class开头,后面跟着类的名字,一个类可以包含有属于自己的变量,变量(称为属性)以及函数(称为方法)。类定义了一件事物的抽象特点。通常来说,类定义了事物的属性和它可以做到的。

类可能包含一些特殊的函数(magic函数),magic函数命名是以符号‘_’开头的,比如_construct当一个队形创建时调用;_destruct当一个对象被销毁时调用;_toString当一个对象被当作一个字符串时使用

__construct: 在创建对象时候初始化对象,一般用于对变量赋初值。
__destruct: 和构造函数相反,当对象所在函数调用完毕后执行。
__toString:当对象被当做一个字符串使用时调用。
__sleep: 序列化对象之前就调用此方法(其返回需要一个数组)
__wakeup: 反序列化恢复对象之前调用该方法
__call: 当调用对象中不存在的方法会自动调用该方法。
__get: 在调用私有属性的时候会自动执行
__isset():在不可访问的属性上调用isset()empty()时触发
__unset():在不可访问的属性上使用unset()时触发

例一:

image-20210217194016278 image-20210217193652877

例二:

image-20210217200817547

image-20210217200857502

二、php反序列化

在传递变量的过程中,有可能遇到变量值要跨脚本文件传递的过程。如果一个脚本中想要的调用之前一个脚本的变量,但是之前一个脚本已经执行完毕,所有的变量和内容释放掉了,那该如何操作呢?serialize和unserialize就是解决这一问题的存在,serialize可以将变量转换为字符串,并且在转换的过程中可以保存当前变量的值,而unserialize则可以将serialize生成的字符串转换回变量。通俗来说:通过反序列化在特定条件下可以重建php对象并执行php对象中某些magic函数。我们通过例子来看php对象序列化之后的格式,代码如下:

例一:

扫描二维码关注公众号,回复: 12651847 查看本文章

image-20210217210808906

image-20210217210833725

  • 为什么会输出两次‘__destruct’呢?难道__destruct方法被调用了两次?也就是说脚本结束了两次?

来查查__destruct的具体用法:

image-20210217211218280

原来就是脚本结束了两次,第一次是原本的object运行完毕时,第二次由于反序列化再次激活了对象object2随着脚本的运行结束也完毕了,所以相当于调用了两次__destruct方法,也就会输出两次"__destruct"。

  • 看看反序列化的结果

    O:4:"test":2:{s:8:"variable";s:4:"mdzz";s:9:"variable2";s:5:"other";}

    O:代表Object

    4:代表对象名长度为4

    2:该对象中有两个变量

    s:该变量为str型

    8:该变量名长度为8

    variable:该变量内容为variable

    后面以此类推…

三、靶场演示

一般情况下,php反序列化漏洞是通过代码审计发现的。

所以我们直接上源码:

image-20210218000111232

有源码可知,后台直接将用户的输入做反序列化,并调用其中的test属性,直接输出到p标签中

根据源码,编写poc

image-20210218000618204

访问该页面:

image-20210218000758433

查看网页源代码获取payload:O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}

image-20210218000647287

在网页提交payload:

image-20210218001003042

image-20210218001015695

如图成功弹窗!

四、总结

反序列化(unserialize)漏洞依赖条件

1、unserialize参数用户可控。

2、脚本的类中存在构造函数(__construct()、析构函数__destruct()、__wakeup()等),该构造函数中有向php文件中写数据的操作的类。

3、所写的内容需要有对象中的成员变量的值。

防范方法

1、严控unserialize函数的参数。

2、对unserialize后的变量内容严格检查,以确保未被污染。

参考文章

宝藏文章

猜你喜欢

转载自blog.csdn.net/qq_43665434/article/details/113840463