In 2022, cfreal gave a talk at BlackAlps 2022 on Generic Remote Exploit Techniques For The PHP Allocator, And 0days. I was there as well, told him that it was ridiculous that PHP's heap was such a soft target, and that I might do something about it eventually, if only to make PHP exploitation less dull.
Two years later, I opened a meta-issue on PHP's bug tracker, and (slowly) started to get to work. I was immediately joined by Arnaud Le Blanc on this endeavour, who actually did most of the work and was kind enough to ping-pong on reviews. Here's what we did so far:
- Safe-unlink, after being born in PHP's codebase in 2003 by Stefan Esser, it got somehow removed during the PHP5 to PHP7 transition. But it's now back for stream_bucket and zend_mm_heap, making it harder to turn a limited write into an arbitrary write.
- A commonly used technique to transform an arbitrary-ish write into code
execution is to overwrite function pointers in the
zend_mm_heapstructure, as demonstrated by cfreal's masterful exploitation of CVE-2024-2961. Suggestion to make those parts read-only was rejected as a 0.6% performance impact was deemed too expensive for too little gain. - Isolating remotely-controlled allocations like user inputs and request environment/data into separate chunks to make remote heap feng-shui/spraying way harder, likely killing exploits like cfreal's Roundcube RCE via CVE-2024-2961
- PHP's heap freelist provided a powerful one-byte-overflow-to-arbitrary-write-what-where primitive, used in countless exploits, like Emmanuel Law's CVE-2016-3132 Peter Nguyen's CVE-2016-3141, cfreal's CVE-2024-2961. A classic hardening measure, as done by XNU/linux/partitionAlloc/suhosin/… was to add a shadow-pointer.
We also took a stab at some non-heap-related techniques:
- Improved randomness of uploaded file names and files created by tempnam(), closing a trivially-bruteforceable remote-file-inclusion vector.
- PHP filters have been used for a couple of years now to enable all sort of interesting behaviour, from arbitrary-reads to code execution with increasing degrees of sophistication. Fortunately, as attacker needs to chain a handful of them, limiting their numbers significantly neuters those techniques.
All those cool things either have landed or will likely soon, so keep your PHP stack up to date. And as usual if you need more hardening, there is always Snuffleupagus.
I find it fascinating that people are putting so much efforts optimizing exploitation techniques, yet ~nobody bothers fixing them, even if it only takes a couple of lines of code and 20 minutes.