php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #73035 Out of bound when verify signature of tar phar in phar_parse_tarfile
Submitted: 2016-09-06 21:02 UTC Modified: 2019-02-10 01:53 UTC
From: nguyenvuhoang199321 at gmail dot com Assigned: stas (profile)
Status: Closed Package: PHAR related
PHP Version: 5.6.25 OS: ALL
Private report: No CVE-ID:
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: nguyenvuhoang199321 at gmail dot com
New email:
PHP Version: OS:

 

 [2016-09-06 21:02 UTC] nguyenvuhoang199321 at gmail dot com
Description:
------------
There was a security code in phar_parse_tarfile
```
if (FAILURE == phar_verify_signature(fp, php_stream_tell(fp) - size - 512, myphar->sig_flags, buf + 8, size - 8, fname, &myphar->signature, &myphar->sig_len, error)) {
	if (error) {
		char *save = *error;
		spprintf(error, 4096, "phar error: tar-based phar \"%s\" signature cannot be verified: %s", fname, save);
		efree(save);
		}
	goto bail;
}
```
There are no checking *entry.uncompressed_filesize* attacker can create a signature.bin with size less than 8 and then this value is passed to *phar_verify_signature* as sig_len as you can see `entry.uncompressed_filesize - 8` as result sig_len is overflow.
And the third param is sig buffer as you can see `sig + 8`, because *entry.uncompressed_filesize* is less than 8 by default emalloc will return 16 bytes this result may lead to heap out of bound.

tarfile : https://drive.google.com/open?id=0B0D1DYQpkA9UVkV1Q0tTeGpVYk0

Test script:
---------------
<?php
	$phar = new PharData('phars/signature.tar');
	var_dump($phar);
?>

Actual result:
--------------
This debug steps I will show the malicious parse phar tarfile.
Set breakpoint at line 266 in tar.c
[----------------------------------registers-----------------------------------]
RAX: 0x4
RBX: 0x0
RCX: 0x0
RDX: 0xb ('\x0b')
RSI: 0xc ('\x0c')
RDI: 0x7fffffffa6ec ("00000000004")
RBP: 0x7fffffffa8b0 --> 0x7fffffffae00 --> 0x7fffffffaea0 --> 0x7fffffffaf10 --> 0x7fffffffafa0 --> 0x7fffffffb090 --> 0x7fffffffb0e0 --> 0x7fffffffb110 --> 0x7fffffffb150 --> 0x7fffffffb260 --> 0x7fffffffd560 --> 0x7fffffffe8e0 --> 0x7fffffffea30 --> 0xa1a0a0 (<__libc_csu_init>:  	push   r15)
RSP: 0x7fffffffa400 --> 0x7fffffffaff0 --> 0x0
RIP: 0x6e67b5 (<phar_parse_tarfile+1101>:      	cmp    DWORD PTR [rbp-0x468],0x0)
R8 : 0xf2b910 ("/home/vagrant/Sources_Ext/audit/src/php7.0-7.0.8/ext/phar/tar.c")
R9 : 0xf4
R10: 0x180
R11: 0x7ffff67e2730 --> 0xfffda400fffda12f
R12: 0x42c280 (<_start>:       	xor    ebp,ebp)
R13: 0x7fffffffeb10 --> 0x2
R14: 0x7ffff3e14030 --> 0x7ffff3e7d040 --> 0x9a66aa (<ZEND_DO_FCALL_SPEC_HANDLER>:     	push   rbp)
R15: 0x7ffff3e7d040 --> 0x9a66aa (<ZEND_DO_FCALL_SPEC_HANDLER>:	push   rbp)
EFLAGS: 0x297 (CARRY PARITY ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x6e67a3 <phar_parse_tarfile+1083>: 	mov    DWORD PTR [rbp-0x3f0],eax
   0x6e67a9 <phar_parse_tarfile+1089>: 	mov    eax,DWORD PTR [rbp-0x3f0]
   0x6e67af <phar_parse_tarfile+1095>: 	mov    DWORD PTR [rbp-0x47c],eax
=> 0x6e67b5 <phar_parse_tarfile+1101>: 	cmp    DWORD PTR [rbp-0x468],0x0
   0x6e67bc <phar_parse_tarfile+1108>: 	jne    0x6e67fd <phar_parse_tarfile+1173>
   0x6e67be <phar_parse_tarfile+1110>: 	mov    rax,QWORD PTR [rbp-0x438]
   0x6e67c5 <phar_parse_tarfile+1117>: 	movzx  eax,BYTE PTR [rax+0x9c]
   0x6e67cc <phar_parse_tarfile+1124>: 	cmp    al,0x67
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffa400 --> 0x7fffffffaff0 --> 0x0
0008| 0x7fffffffa408 --> 0x7fffffffaf00 --> 0x0
0016| 0x7fffffffa410 --> 0x0
0024| 0x7fffffffa418 --> 0x2900000000 ('')
0032| 0x7fffffffa420 --> 0x7ffff3e75018 ("/vagrant_extend/audit/phars/signature.tar")
0040| 0x7fffffffa428 --> 0x7ffff3e5fa00 --> 0x12bf720 --> 0x8d6fc6 (<php_stdiop_write>:	push   rbp)
0048| 0x7fffffffa430 --> 0x4f665eff8
0056| 0x7fffffffa438 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
270    			if (!old && (hdr->typeflag == TAR_GLOBAL_HDR || hdr->typeflag == TAR_FILE_HDR)) {
gdb-peda$ p size
$3 = 0x4
You see here size is only 4 bytes. 
Set breakpoint before phar_verify_signature at line 304, and then continue
[----------------------------------registers-----------------------------------]
RAX: 0x7ffff3e5fa00 --> 0x12bf720 --> 0x8d6fc6 (<php_stdiop_write>:    	push   rbp)
RBX: 0x7fffffffa678 ("gnature.bin")
RCX: 0x7fffffffa678 ("gnature.bin")
RDX: 0x10
RSI: 0x0
RDI: 0x7ffff3e5fa00 --> 0x12bf720 --> 0x8d6fc6 (<php_stdiop_write>:    	push   rbp)
RBP: 0x7fffffffa8b0 --> 0x7fffffffae00 --> 0x7fffffffaea0 --> 0x7fffffffaf10 --> 0x7fffffffafa0 --> 0x7fffffffb090 --> 0x7fffffffb0e0 --> 0x7fffffffb110 --> 0x7fffffffb150 --> 0x7fffffffb260 --> 0x7fffffffd560 --> 0x7fffffffe8e0 --> 0x7fffffffea30 --> 0xa1a0a0 (<__libc_csu_init>:  	push   r15)
RSP: 0x7fffffffa3e0 --> 0x7ffff3e79120 --> 0x0
RIP: 0x6e6a0e (<phar_parse_tarfile+1702>:      	call   0x6e3c22 <phar_verify_signature>)
R8 : 0xfffffffc
R9 : 0x7ffff3e75018 ("/vagrant_extend/audit/phars/signature.tar")
R10: 0x7ffff6794150 (<__strncmp_sse42+3728>:   	pslldq xmm2,0x1)
R11: 0x0
R12: 0x10
R13: 0x7ffff3e79120 --> 0x0
R14: 0x7ffff3e79118 --> 0x0
R15: 0xfffffffc
EFLAGS: 0x212 (carry parity ADJUST zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x6e6a05 <phar_parse_tarfile+1693>: 	mov    rcx,rbx
   0x6e6a08 <phar_parse_tarfile+1696>: 	mov    edx,r12d
   0x6e6a0b <phar_parse_tarfile+1699>: 	mov    rdi,rax
=> 0x6e6a0e <phar_parse_tarfile+1702>: 	call   0x6e3c22 <phar_verify_signature>
   0x6e6a13 <phar_parse_tarfile+1707>: 	add    rsp,0x20
   0x6e6a17 <phar_parse_tarfile+1711>: 	cmp    eax,0xffffffff
   0x6e6a1a <phar_parse_tarfile+1714>: 	jne    0x6e6a9a <phar_parse_tarfile+1842>
   0x6e6a1c <phar_parse_tarfile+1716>: 	cmp    QWORD PTR [rbp-0x4b0],0x0
Guessed arguments:
arg[0]: 0x7ffff3e5fa00 --> 0x12bf720 --> 0x8d6fc6 (<php_stdiop_write>: 	push   rbp)
arg[1]: 0x0
arg[2]: 0x10
arg[3]: 0x7fffffffa678 ("gnature.bin")
arg[4]: 0xfffffffc
arg[5]: 0x7ffff3e75018 ("/vagrant_extend/audit/phars/signature.tar")
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffa3e0 --> 0x7ffff3e79120 --> 0x0
0008| 0x7fffffffa3e8 --> 0x7ffff3e79118 --> 0x0
0016| 0x7fffffffa3f0 --> 0x7fffffffaff0 --> 0x0
0024| 0x7fffffffa3f8 --> 0x6e69cb (<phar_parse_tarfile+1635>:  	mov    rdx,rax)
0032| 0x7fffffffa400 --> 0x7fffffffaff0 --> 0x0
0040| 0x7fffffffa408 --> 0x7fffffffaf00 --> 0x0
0048| 0x7fffffffa410 --> 0x0
0056| 0x7fffffffa418 --> 0x2900000000 ('')
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x00000000006e6a0e     	305    				if (FAILURE == phar_verify_signature(fp, php_stream_tell(fp) - size - 512, myphar->sig_flags, buf + 8, size - 8, fname, &myphar->signature, &myphar->sig_len, error)) {

As you can see because siglen is calculated by subtract size by 8 so as result this value is negative number in signed int or large int number in unsigned int. This mistake may lead to heap out of bound




Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-12 04:27 UTC] stas@php.net
Looks like the same as #72928 but for tar.
 [2016-09-12 04:30 UTC] nguyenvuhoang199321 at gmail dot com
Ok this is the same issue :) but happened in tar parsing
 [2016-09-12 04:38 UTC] stas@php.net
-PHP Version: 7.0.10 +PHP Version: 5.6.25 -Assigned To: +Assigned To: stas
 [2016-09-12 04:38 UTC] stas@php.net
The fix is in security repo as 75ebf471ff46ec6e5ee279b3650c11d51ebaf9e3 and in https://gist.github.com/87af366f29a5a5733f06389a3dfb5e60

please verify
 [2016-09-12 06:30 UTC] nguyenvuhoang199321 at gmail dot com
well bug is fixed thank :)
 [2016-09-13 04:04 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f5a9592ad8d2b60cabbaff00662477528ecefb48
Log: Fix bug #73035 (Out of bound when verify signature of tar phar in phar_parse_tarfile)
 [2016-09-13 04:04 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2016-09-13 04:06 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c5f34c9eca28769a3cc385501ee55bf153028dc4
Log: Fix bug #73035 (Out of bound when verify signature of tar phar in phar_parse_tarfile)
 [2016-09-13 04:09 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c5f34c9eca28769a3cc385501ee55bf153028dc4
Log: Fix bug #73035 (Out of bound when verify signature of tar phar in phar_parse_tarfile)
 [2016-09-13 04:11 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c5f34c9eca28769a3cc385501ee55bf153028dc4
Log: Fix bug #73035 (Out of bound when verify signature of tar phar in phar_parse_tarfile)
 [2016-09-13 09:02 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f5a9592ad8d2b60cabbaff00662477528ecefb48
Log: Fix bug #73035 (Out of bound when verify signature of tar phar in phar_parse_tarfile)
 [2016-09-15 09:30 UTC] tyrael@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=71a6cff185e26d2806b551d4022e766421d3b275
Log: Fix bug #73035 (Out of bound when verify signature of tar phar in phar_parse_tarfile)
 [2016-10-17 10:08 UTC] bwoebi@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f5a9592ad8d2b60cabbaff00662477528ecefb48
Log: Fix bug #73035 (Out of bound when verify signature of tar phar in phar_parse_tarfile)
 [2016-10-17 10:08 UTC] bwoebi@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c5f34c9eca28769a3cc385501ee55bf153028dc4
Log: Fix bug #73035 (Out of bound when verify signature of tar phar in phar_parse_tarfile)
 [2017-10-16 02:18 UTC] stas@php.net
-CVE-ID: +CVE-ID: needed
 [2019-02-10 01:53 UTC] stas@php.net
-CVE-ID: needed +CVE-ID:
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 14:01:29 2024 UTC