Implémentation de référence des recommandations R‑1 / R‑2 / R‑3 d'un audit de pentest SEB. Déplace la confiance du client SEB (incontournablement patchable, cf. §8 du rapport) vers le serveur Moodle, seul élément que l'étudiant ne contrôle pas.
⚠️ Ce plugin ne rend PAS SEB « inviolable ». Personne ne le peut sur un poste où l'étudiant est admin. Il élimine l'attaquant paresseux (clic sur SEBPatch v1.9 — 99 % du flux réel) et crée une trace serveur pour les autres. Lire la section « Modèle de menace » jusqu'au bout avant de promettre quoi que ce soit au SI.
| Couche | Quoi | Fichiers |
|---|---|---|
| R‑1 attestation binaire | Config émise seulement si seb-win-verificator prouve des binaires SEB connus‑bons |
attest.php, classes/attestation_manager.php, knownhashes/*.json |
| R‑2 binding token | Token lié à IP / JA3 / UA / fingerprint, usage unique, stocké hashé | launch.php, classes/token_manager.php, classes/security.php |
| R‑3 token 60 s + heartbeat | Fenêtre courte + battement live, anomalie si coupure | config_token.php, heartbeat.php, classes/heartbeat_manager.php, classes/task/sweep_heartbeats.php |
launch.php (clic étudiant)
├─ capture IP/JA3/UA + fingerprint JS
├─ vérifie attestation CLEAN fraîche (R-1) ──► sinon 409 "relance le verificator"
└─ émet token 60s lié à tout ça ──► lien sebs://config_token.php?id&tok
config_token.php (SEB)
├─ consume token : TTL + usage unique + signature + binding + attestation
├─ arme heartbeat de session
└─ sert le .seb (BEK de session injecté)
heartbeat.php (SEB, toutes les 5s) ──► gap > 10s = anomalie
sweep_heartbeats (cron 1/min) ──► flague les sessions silencieuses
- Copier le dossier dans
moodle/local/sebfix/. - Dans
config.php, ajouter un secret HMAC fort :$CFG->sebfix_secret = '<64+ hex aléatoires>'; // openssl rand -hex 32
- Visiter Administration > Notifications pour créer les tables.
- Plugins locaux > SEB Fix (hardened) : activer
require_attestation,bind_ip,bind_ua. - Déposer le vrai
.sebde chaque examen danstemplates/<cmid>.seb(ou câblerconfig_builder::load_template()sur votre stockage d'examens). - Remplacer le lien « Lancer SEB » des examens par
/local/sebfix/launch.php?cmid=<cmid>.
config_builder::build_for_cmid()— parser proprement le plist et setterbrowserExamKey/startURL, idéalement servir un.sebchiffré PKCS7 (« configure client ») plutôt que clair.- JA3 —
bind_ja3nécessite un reverse proxy (nginx/HAProxy + module JA3) qui injecte l'en‑têteX-TLS-JA3. Sans ça, laisserbind_ja3=0. - Agent verificator — un script GPO lancé avant l'examen :
exécute
seb-win-verificator, POST le JSON{sebversion, machineid, hashes}surattest.phpavec lesesskeyde la session de l'étudiant. - Tableau de bord examinateur — lire
local_sebfix_attest(verdicts) etlocal_sebfix_heartbeat(anomalies) ; capabilitylocal/sebfix:viewmonitor.
À chaque release SEB : installer la version propre, lancer le verificator,
écrire knownhashes/<version>.json. Ajouter tout hash de crack connu dans
knownhashes/blocklist.json. La base actuelle couvre 3.10.1.864 ; le
blocklist couvre SEBPatch v1.9 et v1.4.
Ce que ça arrête :
- L'étudiant qui télécharge
patch-seb.exeet lance l'examen tel quel → l'attestation voit 5 hashs divergents → config refusée. - Le replay de lien d'examen (token 60 s, usage unique, lié au poste).
- Le « SEB dans une VM pour alt‑tab sur l'hôte » → binding IP/UA + heartbeat.
Ce que ça n'arrête pas (limites structurelles, cf. rapport §8) :
- Un attaquant qui patche aussi le verificator, ou rejoue une attestation propre depuis un poste propre puis bascule. → seul un measured boot / attestation hardware (TPM) le ferme (R‑6).
- Un client patché qui passe l'attestation et renvoie un BEK/ConfigKey correct (il détient le secret en mémoire — §6.3). Le BEK reste un signal de corrélation, pas une preuve.
- Le heartbeat simulé par un client patché.
Conclusion droite : pour les examens à enjeu réel, ces trois couches sont un plancher utile, mais la seule défense robuste reste hors du navigateur — proctoring externe (R‑5) ou postes maîtrisés/re‑imagés par l'école (R‑6). À budgéter si l'intégrité compte vraiment.