Phar Deserialization Vulnerability via Logging Settings
Medium
C
Concrete CMS
Submitted None
Actions:
Reported by
egix
Vulnerability Details
Technical details and impact analysis
**Vulnerability Description:**
The vulnerable code is located within the `concrete/controllers/single_page/dashboard/system/environment/logging.php` script.
Specifically, into the `Logging::update_logging() ` method:
```
public function update_logging()
{
$config = $this->app->make('config');
$request = $this->request;
if (!$this->token->validate('update_logging')) {
return $this->showError($this->token->getErrorMessage());
}
// Load in variables from the request
$mode = (string) $request->request->get('logging_mode') === 'advanced' ? 'advanced' : 'simple';
$handler = $mode === 'simple' ? (string) $request->request->get('handler', 'database') : null;
$logFile = $handler === 'file' ? (string) $request->request->get('logFile') : null;
$enableDashboardReport = $request->request->get('enable_dashboard_report') ? true : false;
$loggingLevel = strtoupper((string) $request->request->get('logging_level'));
$intLogErrorsPost = $request->request->get('ENABLE_LOG_ERRORS') === 1 ? 1 : 0;
$intLogEmailsPost = $request->request->get('ENABLE_LOG_EMAILS') === 1 ? 1 : 0;
$intLogApiPost = $request->request->get('ENABLE_LOG_API') === 1 ? 1 : 0;
// Handle 'file' based logging
if ($handler === 'file') {
$directory = dirname($logFile);
// Validate the file name
if (pathinfo($logFile, PATHINFO_EXTENSION) !== 'log') {
return $this->showError(t('The filename provided must be a valid filename and end with .log'));
}
// Validate the file path, create the log file if needed
if (!file_exists($logFile)) {
// If the file doesn't exist, make sure we can create one
if (!is_writable($directory) || !is_dir($directory)) {
return $this->showError(t('Log file does not exist on the server. The directory of the file provided must exist and be writable on the web server.'));
}
```
User input passed through the “logFile” request parameter is not properly sanitized before being used in a call to the `file_exists` function. This can be exploited by malicious users to inject arbitrary PHP objects into the application scope ([PHP Object Injection via phar:// stream wrapper](https://github.com/s-n-t/presentations/blob/master/us-18-Thomas-It's-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It.pdf)), allowing them to carry out a variety of attacks, such as executing arbitrary PHP code.
**Reproduction Steps:**
1. Login to the Concrete5 instance as an admin user
2. Go to "System & Settings" -> "Files" -> "Allowed File Types" and add `log` to File Extensions to Accept
3. Use the attached Proof of Concept (PoC) script to create a sample Phar file to upload (just run `php phar-generator.php` from the CLI)
4. Go to "Files" and upload the `phar.log` file
5. Take note of the path where the file has been uploaded (e.g. `application/files/4916/0848/5009/phar.log`)
6. Go to "System & Settings" -> "Environment" -> "Logging Settings" and select File as Handler
7. Put the following string into the File text box: `phar://./application/files/4916/0848/5009/phar.log`
8. Click the Save button, go to http://[host]/[concrete5]/application/files/tmp/test.php and you will see a "phpinfo" page
**Notes:**
The vulnerability has been successfully tested on Concrete5 versions 8.5.4 and 8.5.5 RC1.
## Impact
This vulnerability might be abused by malicious users to inject and execute arbitrary PHP code on the web server.
However, successful exploitation requires an admin account, and this partially mitigates the issue.
Report Details
Additional information and metadata
State
Closed
Substate
Resolved
Submitted
Weakness
Deserialization of Untrusted Data