本文首发于:https://mp.weixin.qq.com/s?__biz=MjM5MTYxNjQxOA==&mid=2652850238&idx=1&sn=6f22d8ab7af687993330a2a1774a5579&chksm=bd5934f38a2ebde507c7964e5a0dcd4775dec3f62162a462d95814132a8cf546a9df1daa51e5&scene=0&xtrack=1#rd

1.切入漏洞点

某应用使用了版本为6.0.2的guzzlehttp/guzzle代码库,并且在其代码段中存在反序列化函数unserialize(),并且其入口参数为我们可以控制的参数,那么接下来我们就需要在其内部寻找我们可以利用的类并且寻找可以利用的反序列时将会触发的__destruct()函数和__wakeup()函数,然后再在这两类方法中找可能存在漏洞的点,我们可以在sublime中使用ctrl+shift+f键来在指定的文件夹下来查找我们指定的函数,如下图为查找的效果

2.构造pop链

我们注意到vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php中存在__destruct()函数,并且我们猜测filename属于文件型参数,可能与文件操作相关,因此我们便可以定位到FileCookieJar.php文件中进行审计

函数体中存在save方法,因此我们继续跟进到save方法

我们可以看到save方法中存在file_put_contents()函数,我们猜测是不是可以在此进行写shell,其中入口参数$filename为类FileCookieJar的私有成员变量,是我们可以控制的,$json变量来自$cookie变量,而又因为$cookie变量调用的getExpires()函数和getDiscard()函数和toArray()函数均是在SetCookie这个类中进行定义的,所以$cookie变量肯定是SetCookie类实例化后的对象,从而来调用类中的方法。并且此时我们需要满足

1.$cookie>getExpires() 返回Ture

2.$cookie>getDiscard() 返回False

接下来我们跟进到SetCookie.php中观察类SetCookie是如何定义的,

其中在SetCookie类中的成员变量里定义了私有静态成员变量$defaults和私有成员变量$data,

并且在其构造方法中$defaults的值将被$data数组中的值进行替换,并且将替换的结果赋值给$data变量。

其中getExpires()函数和getDiscard()和toArray()函数的定义如下所示:

从上面三个函数的定义中可以看到,上面两个函数返回$data变量的两个键值,下面的函数直接返回$data变量。那么我们可以让这上面两个键值满足if条件,通过我们实例化SetCookie类并传给其一个$data数组即可在其构造方法中完成赋值操作。

到这里,假设我们已经进入第一个箭头所指示的if条件语句中,那么此时将把$cookie对象所调用的toArray()函数的返回值(也就是我们上面所说的SetCookie类中所定义的$data变量的值)赋给$json变量,接下来就会将$json变量的值写入变量$filename所对应的路径中,到此pop链已经完成。

3.相应poc构造

最后,我们在本地测试我们以上的思路以及构造的pop链是否正确,首先编辑composer.json文件并在其中包含我们所测试的对应版本的代码库

接下来在composer的同级目录中执行

1.curl -sS https://getcomposer.org/installer | php  //安装composer

2.php composer.phar install                    //依赖代码库的安装

简单说下composer,composer 是 PHP 的一个依赖管理工具。它允许我们声明项目所依赖的代码库,并且会在我们的的项目中安装所依赖的代码库。composer.json中定义的require键值代表的含义是我们将要开发的应用,依赖于guzzlehttp的6.0.2版本,对于库的自动加载信息,composer 生成了一个 vendor/autoload.php 文件,我们可以通过引入这个文件,从而实现开发中所需要的类的自动加载

接下来就可以开始构造我们的poc了,因为要用到上面说的类,所以我们直接引入对应目录下的autoload.php就可以,这里的两条use语句只是使用了命名空间,具体的加载类交给我们的autoload.php来完成,

接着我们就可以来构造我们最终想要利用的file_put_contents()函数的文件路径名和文件内容,首先进行分析

因为文件路径名$filename参数是类FileCookieJar的私有成员变量,并且在其构造函数中将直接将入口参数赋值给了$filename,并在其析构函数中调用了$filename的值(也就是在反序列化时将会调用$filename的值),因此我们通过实例化FileCookieJar的匿名对象,并将想要写入的路径名作为其入口参数,就可以完成对$filename的赋值。又因为save方法要用到$cookie变量的值,并且$cookie变量的值必须由类SetCookie的实例化后的对象来进行赋值操作,而FileCookieJar的父类是CookieJar,并且在其中存在setCookie()方法,其入口参数为类SetCookie的实例化的对象,因此我们成功地找到了为$Cookie变量赋值的方法,就是通过类FileCookieJar的实例化对象来调用父类中所定义的setCookie()方法,并将其入口参数值设置为类SetCookie的匿名实例化对象,从而实现$cookie变量的赋值。

接下来我们就要构造$cookie变量的数据了,首先我们需要了解setCookie方法,它的入口参数为实例化的类SetCookie的匿名对象,其在函数中调用了validate函数对$cookie变量进行检测,并且定义了设置二次设置$cookie时的判断操作,这里我们构造poc时只需要调用一次setCookie()函数,所以不会进入foreach循环

也就是我们的目标只有一个,那就是是必须使validate()函数返回True

而validate()函数要求我们必须满足以下三个条件才能够返回true:

1.$data[‘Name’]变量非空,并且不能为数字,并且必须为所规定的字符

2.$data[‘Value’]变量非空,并且不能为数字

3.$data[‘Domain’]变量非空,并且不能为数字

并且结合又因为$data[‘Expires’]不能为null,因此我们可以确定我们必须需要设置的$data的键名为以上四个,那么接下来我们就可以继续写我们的poc了,我们在实例化类FileCookieJar时将我们想要写入shell的路径名作为入口参数传递进去,然后将php一句话写到$data变量的Name,Value,Domain中的任何一个值中,接着通过让类对象$tr1ple调用setCookie(),并将其入口参数设置为类SetCookie的匿名实例化(其入口参数为$data),就可以完成对$cookie变量的赋值,因为$cookie值最终会被传递给$json变量并经过json_encode()函数编码以后直接写入到我们指定的路径中。

4.测试结果

我们的poc文件名为poc.php,通过执行php poc.php将会生成exp文件,其中为我们序列化以后的exp数据

接下来我们可以反序列化exp中包含的数据来测试此exp能否执行成功

通过执行结果我们可以判断出已经成功反序列数据并写入shell了,说明我们之前分析的思路和测试过程是正确的。

popchain与对应poc的构造分析的更多相关文章

  1. 任意文件下载漏洞的接口URL构造分析与讨论

    文件下载接口的URL构造分析与讨论 某学院的文件下载接口 http://www.****.edu.cn/item/filedown.asp?id=76749&Ext=rar&fname ...

  2. CONTINUE...?【构造/分析】

    CONTINUE...? Time Limit: 1 Second Memory Limit: 65536 KB Special Judge DreamGrid has classmates numb ...

  3. 《编译原理》构造 LL(1) 分析表的步骤 - 例题解析

    <编译原理>构造 LL(1) 分析表的步骤 - 例题解析 易错点及扩展: 1.求每个产生式的 SELECT 集 2.注意区分是对谁 FIRST 集 FOLLOW 集 3.开始符号的 FOL ...

  4. 编译原理根据项目集规范族构造LR(0)分析表

    转载于https://blog.csdn.net/Johan_Joe_King/article/details/79058597?utm_medium=distribute.pc_relevant.n ...

  5. Fastjson 1.2.22-24 反序列化漏洞分析

    目录 0x00 废话 0x01 简单介绍 FastJson的简单使用 0x02 原理分析 分析POC 调试分析 0x03 复现过程 0x04 参考文章 0x00 废话 balabala 开始 0x01 ...

  6. CVE-2017-8464 分析

    目录 CVE-2017-8464(stuxnet 3.0) 分析 0xFF 前言 0x00 分析工具 0x01 漏洞复现 1).生成一个DLL用于测试 2).构造一个恶意的lnk二进制文件 3).RU ...

  7. [转帖]Windows DHCPServer远程代码执行漏洞分析(CVE-2019-0626)

    Windows DHCPServer远程代码执行漏洞分析(CVE-2019-0626) ADLab2019-03-15共23605人围观 ,发现 4 个不明物体安全报告漏洞 https://www.f ...

  8. Netatalk CVE-2018–1160 越界访问漏洞分析

    编译安装 首先下载带有漏洞的源代码 https://sourceforge.net/projects/netatalk/files/netatalk/3.1.11/ 安装一些依赖库(可能不全,到时根据 ...

  9. java反序列化Commons-Collections5分析

    BadAttributeValueException package org.lain.poc; import org.apache.commons.collections.Transformer; ...

随机推荐

  1. SpringMVC+Hibernate 使用 session.update(obj) 未更新的问题

    1.使用spring控制事务 2.使用session.update(obj)执行更新 spring事务配置: <bean id="transactionBese" class ...

  2. 接上一篇,Springcloud使用feignclient远程调用服务404 ,为什么去掉context-path后,就能够调通

    一.问题回顾 如果application.properties文件中配置了 #项目路径 server.servlet.context-path=/pear-cache-service 则feigncl ...

  3. C# 抽象(4)

    抽象类和普通类有区别嘛?在继承的时候,还是只能继承一次父类嘛? 答案: 抽象类除了在抽象方法和属性上面不能实现具体的代码之外和普通类没有区别.依旧符合类的基本特征.所以在继承的时候抽象类也是属于基类, ...

  4. c语言数据结构学习心得——数据结构基本概念

    1.数据>数据元素>数据项      数据的基本单位是数据元素,数据元素的基本单位是数据项 2.运算的定义->针对逻辑结构 集合:同属于一个集合,无其他关系.(数学上的集合) 线性结 ...

  5. python怎样在一行中捕获多个异常

    所属网站分类: python基础 > 异常处理 作者:浮沉 链接:http://www.pythonheidong.com/blog/article/71/ 来源:python黑洞网,专注pyt ...

  6. 文件管理NSFileManager

    //NSFileManager - (void)viewDidLoad { [super viewDidLoad]; NSLog(@"%@",NSHomeDirectory()); ...

  7. oracle数据库操纵语言DML

    oracle数据库操纵语言:DML 添加数据: ()直接添加数据: insert into table_name(column_name1,column_name2,...) values(data1 ...

  8. FFT 深夜摸鱼小笔记

    本次笔记学习自算法导论 FFT核心:系数表示→(单位复数根)点值表示→(插值)系数表示 关于单位复数根 n次单位复数根\(ω\)为满足\(ω^n=1\)的复数 n次单位复数根恰好有n个,表示为\(ω_ ...

  9. POJ - 1961 最小循环节

    如果循环节存在那在前缀部分也肯定存在 如果循环节存在那至少是可以匹配的 而next是维护最大前缀的,意会意会 注意一定要先判整除,即使别的题目保证是存在循环的 特意画了一张灵魂草图帮助理解 #incl ...

  10. Ubuntu下apt-get安装Java,Tomcat

    sudo apt-get update sudo add-apt-repository ppa:webupd8team/java sudo apt-get install oracle-java8-i ...