CVE-2022-31625 PHP內存未初始化導致RCE漏洞成因分析和復現
漏洞信息
接上文:
CVE-2022-31626 PHP遠程命令執行漏洞成因分析與復現
XCyber,公眾號:且聽安全CVE-2022-31626 PHP遠程命令執行漏洞成因分析與復現
PHP 同時還通報了另一個高危漏洞信息,編號為 CVE-2022-31625:

在 `PHP_FUNCTION` 中分配在堆上的 `char*` 數組沒有被清除,如果發生轉換錯誤,將會調用 `_php_pgsql_free_params` 函數,由于數組沒有初始化,導致可以釋放之前請求的值,導致遠程代碼執行。漏洞影響版本:
- 5.3.0 <= PHP 5.x <= 5.6.40
- 7.0.1 <= PHP 7.x < 7.4.30
- 8.0.0 <= PHP 8.0.x < 8.0.20
- 8.1.0 <= PHP 8.1.x < 8.1.7
漏洞成因
在 `PHP_FUNCTION` 中,利用 `safe_emalloc` 申請指針數組 `params` ,但是沒有進行初始化,導致 `params` 數組中包含有內存中殘留的數據或指針。如果發生異常,代碼會執行 `_php_pgsql_free_params` 函數對整個指針數組進行釋放:

在 `_php_pgsql_free_params` 函數中,根據數組中元素的總數量 `num_params` 逐個釋放非 0 的指針,但是這個指針可能尚未被未初始化,因此導致非預期的內存釋放:

這是典型的內存未初始化漏洞,如果攻擊者能夠控制未初始化的內存內容,可以實現任意內存釋放,進而實現釋放后再引用 UAF ,最終實現遠程代碼執行。在最新的 PHP 版本中,已經對該漏洞進行修復,將原來的總數 `num_params` 改為了當前計數值 `i` ,以此來保證所有釋放的指針都是初始化過的:

漏洞復現
修改 `php.ini`,啟用 `pgsql` 擴展:
extension=pgsql
postgres 數據庫安裝:
sudo apt install postgresql postgresql-contribsudo /etc/init.d/postgresql start
postgres 配置密碼并允許網絡訪問。重啟服務:
sudo /etc/init.d/postgresql restartsudo /etc/init.d/postgresql status

利用 POC ( `test.php` )觸發漏洞,可以看到 `efree` 釋放了一個錯誤地址導致進程崩潰:
php.exe -f test.php

修復方式
該內存未初始化漏洞,容易轉化成 UAF 漏洞,利用難度比 CVE-2022-31626 要簡單。通過遠程堆風水極有可能實現任意內存釋放,進而通過 UAF 實現遠程代碼執行。受影響客戶需要盡快做好補丁升級和防護。
目前官方已發布修復版本,用戶可升級至以下安全版本:
- PHP 8.1.7
- PHP 8.0.20
- PHP 7.4.30