分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

PHP反序列漏洞学习

发布时间:2023-09-06 02:15责任编辑:董明明关键词:PHP

0x00 序列化和反序列化

在PHP中,序列化和反序列化对应的函数分别为serialize()和unserialize()。

序列化:serialize()将对象转换为字符串以便存储传输的一种方式。

反序列化:unserialize()将序列化以后产生的字符串转换为对象供程序使用。

反序列化本身并不危险,但是如果在反序列化时,传入反序列化函数的参数可以被用户控制那将会是一件非常危险的事情。所以,反序列化的危害,关键还是在于可控或不可控。

0x01 PHP序列化格式

1、基础格式

Boolean

b:;b:1;// Trueb:0;// False

Integer

i:;i:1;//1i:-4;//-4

Double

d:;d:1.234560000000001;//1.23456(PHP弱类型造成的四舍五入现象)

NULL

N;

String

s::"";s:4:"name";//name(4指的是name的字符长度)

Array

a::{key,value pairs};a:2:{s:4:"key1";s:6:"value1";s:4:"key2";s:6:"value2";}// array("key1"=>"value1","key2"=>"value2")

2、序列化举例

class_serializ.php

<?php ???class Person{ ???????private $name = ‘Thinking‘; ???????public $sex = ‘man‘; ???????function say($name,$sex) ???????{ ???????????echo "My name is ".$name."I am a ".$sex; ???????} ????} ???????$Person = new Person(); ???echo serialize($Person); ????>

运行结果:

O:6:"Person":2:{s:12:"Personname";s:8:"Thinking";s:3:"sex";s:3:"man";}
O 代表object6 代表对象名字Person占6个字符Person 对象名2 代表对象里面有2个变量s 变量数据类型,s代表string类型12 代表变量名的字符长度Personname 代表这是一个私有变量,变量名是nameThinking 代表是变量name的值

3、反序列化实例

<?php ???class Person{ ???????private $name = ‘Thinking‘; ???????public $sex = ‘man‘; ???????function say($name,$sex) ???????{ ???????????echo "My name is ".$name."I am a ".$sex; ???????} ????} ???????$Person = new Person(); ???$seri = serialize($Person); ???$unseri = unserialize($seri); ???var_dump($unseri)?>

输出结果

object(Person)#2 (2) { ["name":"Person":private]=> string(8) "Thinking" ["sex"]=> string(3) "man" } 

0x02 PHP(反)序列化有关的魔法函数

**__construct()**
构造函数,当一个对象创建时被调用

**__destruct()**
析构函数,当一个对象销毁时被调用

call(),callStatic()

方法重载的两函数

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

__callStatic()是在静态上下文中调用不可访问的方法是触发

get(),set()

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

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

isset(),unset()

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

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

sleep(),wakeup()

__sleep()在对象被序列化之前运行

__wakeup()将在序列化之后立即被调用

**__toString()**

__toString()方法允许一个类决定如何处理像一个字符串时它将如何反应

这么多的魔术方法中我们所需要关注的方法也就是__destruct() 和 __wakeup() 方法.这两个方法中前者是在对象被销毁时程序会自动调用,后者是在类对象被反序列化时被调用.所以这两个方法是在 对象反序列化一直到程序执行完毕这整个过程中,必定会被调用的方法,如果在这两个函数中有一些危险的动作,并且能够被我们所利用,那么漏洞并出现了。

举个简单的例子

test.php

<?phpclass A{ ???var $test = "demo"; ???function __destruct(){ ???????echo $this->test; ???}}$a = $_GET[‘test‘];$unser = unserialize($a);?>

我们只要构造payload:

http://127.0.0.1/serialize/test.php?test=O:1:%22A%22:1:{s:4:%22test%22;s:5:%22hello%22;}

就能控制echo出的变量。

0x03 PHP反序列化与POP链

在反序列化中,我们所能控制的数据就是对象中的各个属性值,所以在PHP反序列化有一种漏洞利用方法叫做“面向属性编程”,即POP(Property Oriented Programming)。和二进制漏洞中常用的ROP技术类似。在ROP中我们往往需要一段初始化gadgets来开始我们的整个利用过程,然后继续调用其他的gadgets。在PHP反序列化漏洞利用技术POP中,对应的初始化gadgets就是__wakeup()或者是__destruct()方法,在最理想的情况下能够实现漏洞利用的点就在这两个函数中,但往往我们需要从这个函数开始,逐步的跟进在这个函数中调用到的所有函数,直至找到可以利用的点为止。

下面列举在跟进其函数调用过程中需要关注一些有价值的函数。

命令执行:

exec()passthru()popen()system()

文件操作:

file_put_contents()file_get_contents()unlink()

PHP反序列漏洞学习

原文地址:https://www.cnblogs.com/ESHLkangi/p/9668997.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved