Recent Posts

Recent Comments

Archives

Categories

Chamilo

Hi,

I had a friend who wanted to install a E-learning solution for his company. He choose Chamilo. It has a nice interface and is easy to install.

Then he asked me help to configure the mail server and some others little things. During the navigation on the pages, I saw it was in php, using no obvious framework and have nice parameters in the URL.

Since it is open-source, I put myself up to the challenge and the next day I downloaded and install it on a VM.

After some research, I discovered that there was a lot of php pages accessible without any authentication. I love pre-auth exploit! So I started to look into those files to see if there was interesting features for an exploit.

Version

I installed the 1.11.8 version (the last stable release from github).
But checking the code for version 2.x, vulnerabilities are still present.

Leak Data

When I am searching inside the code, I love API. You always find some interesting things in it, because it’s not used the same way, doesn’t use the same logic or permissions. So I started with the main/ajax folder.

Obviously, the user_management.ajax.php file was the first one I looked into.
It didn’t take me a lot of times to realize I already have my first exploit.

The check is done after the unserialize. It means the input of this method is not filtered and only required to be base64 encoded.
I didn’t go further in the exploitation but you just need to right chain starting from this point. You can use PHPGGC to help for example.

Okay, we can see several bad practices:
1. Use a blacklist to validate extension
2. When a php file is found, set an error message, but doesn’t stop the loop. Even worst with the comment saying that once the right file is found, it should stop the loop

So, to resume, it checks the content of the zip file and if it founds any php files, it will set an error message but continue the process.

An extraction of the files is done in $courseSysDir.$newDir. This directory has nothing secret and is known by the user. The only restriction to exploit this vulnerability is to know a course_id, which is not a sequential value. (more info below).

So, back to our code, the application extract the zip in a folder we know the path.
Then it loop through all files in this folder and delete them if they are dangerous, meaning for example if you have a .php extension.

In this case I see several possibilities to exploit this process, I will not test them all, I think the fix should be smart enough to block those cases anyway:

1. Race condition… or not…

Between the time from the extraction to the deletion of our malicious php file, there is some time. We can run a thread in parallel that request our file (we know the full URL) and execute it during this small amount of time. We can even fill the zip with a lot of empty files so the loop will take more times and it would be easier to trigger the vulnerability.

Update:

After some testing, I realised that you don’t need a Race condition. All you need is to put your files in a folder then zip the folder instead of all the files.
The checks in Chamilo will be done only at the first level of the folder. It means that it will check the folder’s extension and nothing else. It will leave all your files untouched: php extension, .htaccess, etc…

2. HTACCESS POWER

Depending on the server’s configuration, we can put a .htaccess in the zip file and a malicious php file called “hack.0xecute” for example.
We would put in the .htaccess file something like this:

AddType application/x-httpd-php .0xecute

meaning, apache will execute every file with the extension above as a php file and execute the code.

At the end, it copies our file in $documentPath which is a concatenation of our 2 inputs: filename and filepath.

We can see that this is no joke about the $filename variable. is it filtered a lot!
But… what about $_GET[‘filepath’] ?
Nothing… except XSS.
So what we can do is put a file anywhere in the system. It may not have the extension we want but it’s not a problem.

Creating your own session

In a nutshell, what you can do is set the filepath to ‘/var/lib/php/sessions and set as filename ‘sess_0xecute’. What is going to happen?

This directory contains all the session of php. So maybe we cannot read them but we can create one with anything we want inside.

I give an empty filename (the one that is filtered) and I put ‘exploit.php’ in the filepath. Since there is a concatenation with no slash between them…

And there you have your php file, in an executable directory.

A public repository of chamilo’s

What is the next step for a non-ethical hacker once he found a vulnerability on a source code?
He has to find website that has the application running. The advantage is that for chamilo, they already do that for you:
https://version.chamilo.org/community.php
You have a list of a lot of chamilo’s installation.
Okay… it is true you don’t have the domain name or the IP, but you have the name of the e-learning platform, and this can be interesting.

On my side, every link I found or tried starting from this webpage were not using chamilo anymore or down. But I didn’t test all of them of course. I tested some that include domain name inside the title.

After a research on shodan, not so many has been shown:

Below the community page, it is written:

We collect the information on these sites by allowing an opt-in system on the administration page of each portal. This option sends a small summary of the portal information, in the background, to our server. This information contains (exhaustive list):
The portal name
The portal URL
The server's IP address
The number of users
The number of courses
The admin name
The admin e-mail
This information serves only for two reasons:
Establish a report of who is using Chamilo, so that the Chamilo community can show off a little of the number of organizations using it
Establish a list of people that might want to know when we discover critical security issues

Can someone explain to me how storing the IP and url of chamilo installation help in the two goals cited above?

From what we can see in the source code, this is what chamilo send:

$data = [
'url' => api_get_path(WEB_PATH),
'campus' => api_get_setting('siteName'),
'contact' => api_get_setting('emailAdministrator'), // the admin's e-mail, with the only purpose of being able to contact admins to inform about critical security issues
'version' => $system_version,
'numberofcourses' => $number_of_courses, // to sum up into non-personal statistics - see https://version.chamilo.org/stats/
'numberofusers' => $number_of_users, // to sum up into non-personal statistics
'numberofactiveusers' => $number_of_active_users, // to sum up into non-personal statistics
'numberofsessions' => $number_of_sessions,
//The donotlistcampus setting recovery should be improved to make
// it true by default - this does not affect numbers counting
'donotlistcampus' => api_get_setting('donotlistcampus'),
'organisation' => api_get_setting('Institution'),
'language' => api_get_setting('platformLanguage'), //helps us know the spread of language usage for campuses, by main language
'adminname' => api_get_setting('administratorName').' '.api_get_setting('administratorSurname'), //not sure this is necessary...
'ip' => $_SERVER['REMOTE_ADDR'], //the admin's IP address, with the only purpose of trying to geolocate portals around the globe to draw a map
// Reference to the packager system or provider through which
// Chamilo is installed/downloaded. Packagers can change this in
// the default config file (main/install/configuration.dist.php)
// or in the installed config file. The default value is 'chamilo'
'packager' => $packager,
'unique_id' => $uniqueId,
];

So you have,

the WEB_PATH ( this is the url of your chamilo)

site name

email administrator

version of Chamilo you installed

number of courses

number of users

number of active users

number of sessions

donotlistcampus

Organisation

Language

Administrator name

The IP of the administrator (not the server!)

Maybe it is me but I don’t see in this file any restriction about what is send (main/inc/ajax/admin.ajax.php). And this is the only way you can check that your version is up to date. (Waiting for a response of Chamilo team)

So, it is a lot of personal data that is being fetch. And can you imagine if they get hacked and this become public?

They speak about OWASP and filtering input, and best coding conventions. So how those vulnerabilities happened?

I am sure the team will do everything to improve the source code and fix those issues which includes:
– lack of permission checks
– lack of input’s filtration

Disclosure timeline:
23.01.2019: First contact with the team via not encrypted mail
25.01.2019: They say I can send them details of critical vulnerabilities by email. So I send them the two leaks information. I didn’t have the exploit or a confirmation that the RCE was working at that time.
…