Noodconsole
Waarom een noodconsole
Wanneer een alert je vertelt “iets vreemds draait op host X”, wil je vaak direct kijken. SSH/RDP installeren overal is een grote attack surface, beheerlast, en geen forensische audit-log. De noodconsole geeft via de bestaande agent-WS-tunnel een kort levende, gerichte shell — zonder poorten open te zetten, zonder permanente credentials op de host, met een complete audit-trail server-side.
Auth-flow (identiek op alle OSes)
- Operator klikt Open noodconsole op een agent in het dashboard.
- Dashboard vraagt reden (≥20 tekens) + TOTP-code.
- Hub-API valideert role (admin/owner), TOTP, en rate-limit (3 sessies / uur / user).
- Hub signt een Ed25519 console-session-token (15 min TTL, nonce, agent-bound) en pusht een
console_startframe naar de agent over de bestaande WebSocket. - Agent verifieert signature + nonce + TTL, spawned een lokale shell, opent een keystroke-stream terug naar de hub.
- Browser opent
wss://api.monsys.ai/ws/console/<session_id>— bidirectionele binary stream.
Elke I/O byte wordt naar console_audit_log op de hub geschreven (direction=‘I’ voor invoer, ‘O’ voor uitvoer) met sequence_num en agent_id. Bij sessie-einde wordt een SHA256 van het complete log op console_sessions.audit_hash gezet als forensisch proof.
Linux side — bash --restricted als monsys-console
Bij agent install:
useradd -r -s /bin/false -d /var/lib/monsys/console monsys-console.bashrcschrijft een rode[MONSYS-CONSOLE]prompt +HISTTIMEFORMAT+ audit log
Bij elke sessie:
setpriv --reuid=monsys-console --regid=monsys-console \ --init-groups --inh-caps=-all \ -- /bin/bash --restricted \ --rcfile /var/lib/monsys/console/.bashrcRestricted-bash blokkeert cd, omleidingen met >, en PATH= zelf wijzigen. Caps zijn gestript. Sudoers fragment voor monsys-console user is leeg → geen privilege-escalatie mogelijk.
Windows side — ConPTY + PowerShell met JEA
Op Windows geeft je een pseudo-console (ConPTY, native API sinds Win10 1809) een echte terminal-ervaring (kleuren, resize, ctrl-c), en Just Enough Administration (JEA) enforce’t de cmdlet-whitelist server-side.
Bij agent install (install.ps1):
- Maakt module
MonsysJEAaan onder$Env:ProgramFiles\WindowsPowerShell\Modules\ - Schrijft Role Capability File
MonsysConsole.psrcmet de whitelist (zie hieronder) - Schrijft Session Configuration File
monsys-console-jea.psscmetRunAsVirtualAccount=$true,LanguageMode=NoLanguage,SessionType=RestrictedRemoteServer Register-PSSessionConfiguration -Name monsys-console-jea
Bij elke sessie:
powershell.exe -NoLogo -NoProfile -NoExit \ -ConfigurationName monsys-console-jeaStdin/stdout van het ConPTY-paar wordt gemapt op de WS-stream.
Wat de operator WEL mag (whitelist)
Forensische IR-set, ~60 cmdlets:
| Categorie | Cmdlets |
|---|---|
| Process | Get-Process, Stop-Process, Wait-Process, Debug-Process |
| Service | Get/Stop/Start/Restart/Suspend/Resume-Service, Set-Service |
| Event log | Get-EventLog, Get-WinEvent (geen Clear-EventLog) |
| Netwerk | Get-NetTCPConnection, Get-NetUDPEndpoint, Get-NetAdapter, Get-NetIPAddress, Get-NetIPConfiguration, Get-NetRoute, Get-DnsClient*, Resolve-DnsName, Test-Connection, Test-NetConnection |
| Containment | Disable/Enable-NetAdapter, New/Remove/Get-NetFirewallRule, Set-NetFirewallProfile |
| Users | Get-LocalUser, Get-LocalGroup, Get-LocalGroupMember (geen Add/Set/Remove) |
| Filesystem | Get-ChildItem, Get-Item, Get-Content, Get-ItemProperty, Get-FileHash, Test-Path, Resolve-Path, Get-Acl, Get-AuthenticodeSignature |
| Tasks | Get-ScheduledTask, Disable-ScheduledTask |
| WMI/CIM | Get-CimInstance, Get-CimClass (geen Invoke-CimMethod) |
| Perf | Get-Counter, Get-ComputerInfo, Get-HotFix |
| Pipeline | ForEach-Object, Where-Object, Select-Object, Sort-Object, Group-Object, Measure-Object, Compare-Object, Format-*, Out-*, Select-String |
| Emergency power | Restart-Computer, Stop-Computer |
Wat de operator NIET kan (JEA blokkeert server-side)
Invoke-Expression,Invoke-Command— geen arbitrary code executionNew-LocalUser,Add-LocalGroupMember,Set-LocalUser— geen nieuwe privileged accountsRemove-Item,Format-Volume— geen destructieClear-EventLog— geen forensic-evidence tamperingSet-Aclop kritieke paden — geen permissions-wijzigingen.exeexecutables buiten de whitelistNew-PSSession— geen pivoting naar andere hosts- Scripts of variabele-expansion (
LanguageMode=NoLanguage) — alleen losse cmdlet-invocations
Probeer je een geblokkeerde cmdlet, krijg je server-side een rode error:
The term 'Remove-Item' is not recognized as the name of a cmdlet, function, ...JEA-transcripten worden óók lokaal weggeschreven naar $Env:ProgramData\monsys\console-transcripts\ als secundaire forensic trail (de primaire trail blijft hub-side console_audit_log).
Sessie-einde
Sessie eindigt op:
- Browser disconnect (operator sluit tab)
- 15 min TTL bereikt → automatisch dicht
- Operator typt
exit/Exit-PSSession - Tenant suspended → hub sluit alle open sessies onmiddellijk
Bij elke sluiting wordt een SHA256 van de hele console_audit_log (in sequence_num volgorde) berekend en gepind op de session-row. Dat hash kan je later vergelijken om aan te tonen dat de log niet werd gewijzigd.
Permissions samenvatting
| Linux | Windows | |
|---|---|---|
| Shell | bash --restricted | powershell (LanguageMode=NoLanguage) |
| User context | monsys-console (low-priv) | JEA RunAs virtual account (ephemeral) |
| Cmdlet/builtin whitelist | Pad-restricted bash | JEA RoleCapability (~60 cmdlets) |
| Filesystem destructie | Geen — restricted bash blokkeert redirects | Geen — Remove-Item niet in whitelist |
| Privilege escalation | Geen sudoers entry voor monsys-console | Virtual account, geen admin lid |
| Audit trail (hub) | console_audit_log met SHA256 lockdown | idem |
| Audit trail (host fallback) | n/a | $ProgramData\monsys\console-transcripts\ |