Bug #70163 [Csd]: curl_setopt_array() type confusion
| From: | andrea dot palazzo at truel dot it | Date: | Thu, 30 Jul 2015 08:42:25 +0000 |
| Subject: | Bug #70163 [Csd]: curl_setopt_array() type confusion | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-194834@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=70163&edit=1
ID: 70163
User updated by: andrea dot palazzo at truel dot it
Reported by: andrea dot palazzo at truel dot it
Summary: curl_setopt_array() type confusion
Status: Closed
Type: Bug
Package: cURL related
Operating System: Ubuntu x86_64
PHP Version: 7.0.0beta2
Assigned To: laruence
Block user comment: N
Private report: N
New Comment:
Just to be clear, I' haven't investigated the remote execution possibility in deep yet,
still I suggest you keep this report private until the next release since remotely triggering the
bug is possible.
Previous Comments:
------------------------------------------------------------------------
[2015-07-30 07:48:33] andrea dot palazzo at truel dot it
Hello,
kudos for the very prompt fix!
I see that you are not considering this one to be security related, but what about the following
scenario?
Class XMLHttpDummy {
public $curlInstance;
function __call($x, $y) {
...
curl_setopt_array($this->curlInstance, array("CURLOPT_POSTFIELDS" =>
xml_encode_request($x, $y), "CURL_BLA" => "whatever"));
...
return curl_exec($this->curlInstance);
}
}
If a class of this kind is present in an unserialize context this pretty seems remote code execution
to me, and that's not that unlikely to have something like that, is it?
Regards,
Andrea
------------------------------------------------------------------------
[2015-07-30 05:59:04] laruence@php.net
fixed in https://github.com/php/php-src/commit/6c0feb0665f3488ffdc2ab33e9e1b8d3a1af93ae
------------------------------------------------------------------------
[2015-07-29 07:15:22] andrea dot palazzo at truel dot it
Description:
------------
OVERVIEW
In PHP7 curl_setopt_array is prone to a type confusion due to an unsafe use of the Z_RES_P macro.
DETAILS
from ext/curl/interface.c:2794
if (zend_parse_parameters(ZEND_NUM_ARGS(), "za", &zid, &arr) == FAILURE) {
return;
}
if ((ch = (php_curl*)zend_fetch_resource(Z_RES_P(zid), le_curl_name, le_curl)) == NULL) {
RETURN_FALSE;
}
The problem here is that zid is being retrived as a generic zval but then an assumption is made
about it being a resource, thus if a numeric value is supplied as first argoment, Z_RES_P would be
confused and try to dereference its value as a pointer.
<?php
/*
Crash on invalid read access
*/
curl_setopt_array(1337, array());
?>
php poc.php
Program received signal SIGSEGV, Segmentation fault.
0x000000000098d81f in zend_fetch_resource (res=0x539,
resource_type_name=0xb39cf1 "cURL handle", resource_type=10)
at /home/kingolol/php-7.0.0beta2/Zend/zend_list.c:126
126 if (resource_type == res->type) {
(gdb) x/i $pc
=> 0x98d81f <zend_fetch_resource+23>: mov 0xc(%rax),%eax
(gdb) p $rax
$109 = 1337
An attacker could exploit such condition by simply crafting a zend_resource value in memory with an
arbitrary *ptr which would then be used as a php_curl.
From this point code execution could be achieved in several ways, relying on the *handlers or
*to_free fields for example.
Details about that will follow as soon as further investigations will be conducted.
SOLUTION
For what is my understanding of the code here, just retrieving zid as a resource should do the job.
Other way a typecheck should be performed on zid before passing it to Z_RES_P.
Regards,
Andrea
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=70163&edit=1