Aller au contenu

Console d'urgence

Quand une alerte vous dit “quelque chose d’étrange tourne sur l’hôte X”, vous voulez souvent regarder tout de suite. Installer SSH/RDP partout = grande surface d’attaque, charge de gestion, et pas de trail forensique. La console d’urgence ouvre via le tunnel WS de l’agent un shell court et ciblé — sans ouvrir de ports, sans credentials permanents sur l’hôte, avec une journalisation complète côté serveur.

Flux d’authentification (identique sur tous les OS)

Section intitulée « Flux d’authentification (identique sur tous les OS) »
  1. L’opérateur clique Ouvrir la console d’urgence sur un agent.
  2. Le dashboard demande raison (≥20 caractères) + code TOTP.
  3. L’API hub valide le rôle (admin/owner), TOTP, et le rate-limit (3 sessions/h/utilisateur).
  4. Le hub signe un token de session console Ed25519 (TTL 15 min, nonce, lié à l’agent) et pousse un frame console_start à l’agent via la WebSocket existante.
  5. L’agent vérifie signature + nonce + TTL, spawn un shell local, ouvre un stream de touches vers le hub.
  6. Le navigateur ouvre wss://api.monsys.ai/ws/console/<session_id> — flux binaire bidirectionnel.

Chaque octet I/O est écrit dans console_audit_log côté hub (direction=‘I’ pour l’entrée, ‘O’ pour la sortie) avec sequence_num et agent_id. À la fin de la session, un SHA256 du log complet est calculé et fixé sur console_sessions.audit_hash comme preuve forensique.

Côté Linux — bash --restricted sous monsys-console

Section intitulée « Côté Linux — bash --restricted sous monsys-console »

À l’installation de l’agent :

  • useradd -r -s /bin/false -d /var/lib/monsys/console monsys-console
  • .bashrc avec prompt rouge [MONSYS-CONSOLE] + HISTTIMEFORMAT

À chaque session :

Fenêtre de terminal
setpriv --reuid=monsys-console --regid=monsys-console \
--init-groups --inh-caps=-all \
-- /bin/bash --restricted \
--rcfile /var/lib/monsys/console/.bashrc

Bash restricted bloque cd, les redirections avec >, et la modification de PATH. Les caps sont stripées. Le fragment sudoers pour monsys-console est vide → pas d’escalation possible.

Sous Windows, une pseudo-console (ConPTY, API native depuis Win10 1809) donne une vraie expérience terminal (couleurs, resize, ctrl-c), et Just Enough Administration (JEA) applique la whitelist côté serveur.

À l’installation (install.ps1) :

  • Crée le module MonsysJEA sous $Env:ProgramFiles\WindowsPowerShell\Modules\
  • Écrit le Role Capability File MonsysConsole.psrc avec la whitelist
  • Écrit le Session Configuration File monsys-console-jea.pssc avec RunAsVirtualAccount=$true, LanguageMode=NoLanguage, SessionType=RestrictedRemoteServer
  • Register-PSSessionConfiguration -Name monsys-console-jea

À chaque session :

powershell.exe -NoLogo -NoProfile -NoExit \
-ConfigurationName monsys-console-jea

Stdin/stdout du ConPTY est mappé sur le stream WS.

Ensemble IR forensique, ~60 cmdlets :

CatégorieCmdlets
ProcessGet-Process, Stop-Process, Wait-Process, Debug-Process
ServiceGet/Stop/Start/Restart/Suspend/Resume-Service, Set-Service
Event logGet-EventLog, Get-WinEvent (pas de Clear-EventLog)
RéseauGet-NetTCPConnection, Get-NetUDPEndpoint, Get-NetAdapter, Get-NetIPAddress, Get-NetIPConfiguration, Get-NetRoute, Get-DnsClient*, Resolve-DnsName, Test-Connection, Test-NetConnection
ContainmentDisable/Enable-NetAdapter, New/Remove/Get-NetFirewallRule, Set-NetFirewallProfile
UtilisateursGet-LocalUser, Get-LocalGroup, Get-LocalGroupMember (pas Add/Set/Remove)
FilesystemGet-ChildItem, Get-Item, Get-Content, Get-ItemProperty, Get-FileHash, Test-Path, Resolve-Path, Get-Acl, Get-AuthenticodeSignature
TâchesGet-ScheduledTask, Disable-ScheduledTask
WMI/CIMGet-CimInstance, Get-CimClass (pas d’Invoke-CimMethod)
PerfGet-Counter, Get-ComputerInfo, Get-HotFix
PipelineForEach-Object, Where-Object, Select-Object, Sort-Object, Group-Object, Measure-Object, Compare-Object, Format-*, Out-*, Select-String
PowerRestart-Computer, Stop-Computer

Ce que l’opérateur NE PEUT PAS (bloqué par JEA)

Section intitulée « Ce que l’opérateur NE PEUT PAS (bloqué par JEA) »
  • Invoke-Expression, Invoke-Command — pas d’exécution arbitraire
  • New-LocalUser, Add-LocalGroupMember, Set-LocalUser — pas de nouveaux comptes privilégiés
  • Remove-Item, Format-Volume — pas de destruction
  • Clear-EventLog — pas de tampering de preuves
  • Set-Acl sur des chemins critiques — pas de modifications de permissions
  • .exe hors whitelist
  • New-PSSession — pas de pivoting vers d’autres hôtes
  • Scripts ou expansion de variables (LanguageMode=NoLanguage) — uniquement des invocations de cmdlets isolées

Tentative d’une cmdlet bloquée → erreur rouge côté serveur :

The term 'Remove-Item' is not recognized as the name of a cmdlet, function, ...

Les transcripts JEA sont aussi écrits localement sous $Env:ProgramData\monsys\console-transcripts\ comme trail forensique secondaire. La trail primaire reste console_audit_log côté hub.

La session se termine sur :

  • Déconnexion du navigateur
  • TTL 15 min atteint
  • exit / Exit-PSSession
  • Tenant suspendu → le hub ferme toutes les sessions ouvertes

À la fermeture, un SHA256 du console_audit_log complet (ordre sequence_num) est calculé et épinglé sur la row de session. Ce hash peut être comparé plus tard pour prouver l’intégrité du log.

LinuxWindows
Shellbash --restrictedpowershell (LanguageMode=NoLanguage)
Contexte utilisateurmonsys-console (low-priv)JEA RunAs virtual account (éphémère)
WhitelistBash restrictedJEA RoleCapability (~60 cmdlets)
Destruction filesystemBloquée (redirects)Remove-Item hors whitelist
Privilege escalationPas d’entrée sudoersVirtual account, pas admin
Audit (hub)console_audit_log avec SHA256 lockdownidem
Audit (host fallback)n/a$ProgramData\monsys\console-transcripts\