Scenario: Mustache Corp Srl detiene il brevetto Formula M-80 — la formula scientifica per far crescere baffi stile anni '80 in 30 giorni. Vale milioni. L'attaccante (Kali, 192.168.64.200) vuole esfiltrarla. Tu sei il Security Engineer che la difende (Ubuntu, 192.168.64.3).
Stack Tecnologico Target#
Costruito sulle offerte di lavoro reali del mercato EU remoto (Cloud Security Engineer / DevSecOps, 2026).
| Layer | Tecnologia | Perché è qui |
|---|---|---|
| Configuration management | Ansible | Richiesto esplicitamente. Hardening automatico. |
| CI/CD | GitHub Actions | Pipeline deploy automatico app Mustache Corp |
| SIEM | Wazuh (Elastic underneath) | Offerte chiedono Elastic/SIEM — Wazuh è Elastic + regole security |
| IDS/IPS | Suricata | Nominato esplicitamente nelle offerte |
| Firewall | iptables / ufw (Linux) | Base di ogni firewall Linux enterprise |
| IAM on-prem | Samba 4 AD (Ubuntu) | Domain controller Linux-native — Windows Server nella fase cloud |
| IAM cloud | AWS IAM / Azure Entra ID | Aggiunto nella fase cloud dopo Security+ |
| Container layer | Docker + Compose | App target e servizi ricostruibili in secondi |
| Segmentazione | Docker networks + iptables | mustache-dmz / mustache-lan isolate via regole |
| Orchestrazione | Kubernetes (k3s) | Sprint 7+ |
| Proxy | Squid | Forward proxy, content filtering, logging |
| WAF | ModSecurity (OWASP CRS) | Difesa layer 7 davanti a DVWA |
| Deception | OpenCanary | Honeynet — detection lateral movement |
| Attaccante | Kali Linux (UTM locale) | 192.168.64.200 — attacca Ubuntu |
| Framework | MITRE ATT&CK | Ogni attacco simulato mappato su una tecnica ATT&CK |
| Provisioning cloud | Terraform | Fase cloud Hetzner dopo Security+ — non serve in locale |
Crown Jewels#
formula-M80.pdf → /data/confidential/ su Ubuntu (il vero target)
DB MySQL (Docker) → tabella `brevetti`, campo `formula_m80`
/mustache-admin → pannello admin nginx, protetto da credenziali RBACDeception Layer#
OpenCanary (Docker) → sembra MySQL su porta 3306-fake — trigger alert se connesso
.env sul web container → DB_HOST=opencanary, DB_PASSWORD=Mustache2024! (falso)
password-backup.txt → honeyfile nella webroot, inotifywait monitorato
formula-M80-DRAFT.pdf → copia falsa con Canary Token — alert se aperta ovunqueArchitettura — UTM Locale#
Kali Linux (192.168.64.200) — ATTACCANTE
│
│ host-only network 192.168.64.0/24
▼
┌─────────────────────────────────────────────────┐
│ ubuntu-server (192.168.64.3) │
│ │
│ iptables (firewall stateful — Fase 3) │
│ Samba 4 AD DC — dominio mustache.corp │
│ Suricata (IDS/IPS — Fase 3-4) │
│ Wazuh server+agent (SIEM — Fase 1) │
│ fail2ban │
│ Squid proxy (Fase 3) │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ Docker Network: mustache-dmz │ │
│ │ nginx + ModSecurity WAF (80/443) │ │
│ │ DVWA (via nginx) │ │
│ │ .env falso + honeyfile │ │
│ └──────────────────┬───────────────────────┘ │
│ │ solo nginx → mysql:3306 │
│ ┌──────────────────▼───────────────────────┐ │
│ │ Docker Network: mustache-lan (isolata) │ │
│ │ MySQL — Formula M-80 crown jewel │ │
│ │ OpenCanary — fake MySQL (honeynet) │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
Mac (192.168.64.1) — host / adminRegola chiave iptables: Kali non raggiunge mai direttamente MySQL. Passa da nginx→WAF→MySQL via Docker network. OpenCanary è irraggiungibile dall'esterno tranne tramite il .env falso.
Costo totale: €0/mese (fase cloud Hetzner ~€30/mese dopo Security+)
Kill Chain Attaccante (MITRE ATT&CK)#
T1595 — Reconnaissance → nmap -sS 192.168.64.3
T1190 — Exploit Public App → SQLi su login form DVWA
T1059 — Command Execution → web shell su nginx container
T1552 — Credentials Files → trova .env con DB_HOST=opencanary
T1021 — Lateral Movement → tenta connessione a OpenCanary:3306 ← ALERT honeynet
T1083 — File Discovery → trova password-backup.txt ← ALERT honeyfile
T1048 — Exfiltration → scarica formula-M80-DRAFT.pdf ← ALERT Canary Token
T1110 — Brute Force → SSH su Ubuntu ← fail2ban + WazuhWazuh correla ogni step. Il sabato esegui la kill chain completa e documenti gli alert.
Repository GitHub#
github.com/[barno]/mustache-project/
├── README.md ← architettura + scenario + kill chain
├── ansible/
│ ├── site.yml ← playbook master (chiama tutti i ruoli)
│ ├── inventory/hosts.yml
│ └── roles/
│ ├── common/ ← SSH hardening, fail2ban, base packages
│ ├── wazuh-agent/
│ ├── suricata/
│ └── nginx-waf/
├── docker/
│ ├── docker-compose.yml ← mustache-app + MySQL + OpenCanary
│ ├── app/Dockerfile
│ └── db/init.sql ← crea tabella brevetti + Formula M-80
├── .github/workflows/
│ └── deploy.yml ← push → SSH su Ubuntu → docker-compose up
└── writeups/
└── kill-chain-sprint-03.md ← attacco documentato con screenshot alertSprint 1 — Cap 1: SIEM & Visibility + Configuration Management#
Goal: Wazuh operativo su Ubuntu, log centralizzati, hardening automatico via Ansible. Gibson: Cap 1 — Security Controls, CIA triad, Detective controls, log aggregation. MITRE: T1110 (Brute Force) — primo attacco rilevabile. DoD: Wazuh mostra eventi in real-time; SSH brute force da Kali genera alert; fail2ban banna l'IP.
Configuration Management — Ansible#
- Scrivere
ansible/roles/common/: SSH hardening (no password, no root), fail2ban, update automatici - Scrivere
ansible/inventory/hosts.ymlcon host Ubuntu (192.168.64.3) -
ansible-playbook site.yml— applica hardening a Ubuntu- Come sai che hai finito:
ssh root@192.168.64.3fallisce;ssh barno@192.168.64.3 -i keyfunziona
- Come sai che hai finito:
Crown Jewel Setup#
- Su Ubuntu:
docker-compose up -d→ MySQL + tabellabrevetticonformula_m80 - Su Ubuntu: creare
/data/confidential/formula-M80.pdf(contenuto fittizio) - Docker: nginx up con pagina login "Mustache Corp Portal"
- Piazzare
.envfalso epassword-backup.txtnella webroot del container
SIEM — Wazuh#
- Installare Wazuh server+agent su Ubuntu (script ufficiale)
- Abilitare FIM su
/data/confidential/ - Configurare inotifywait su
password-backup.txt→ log a Wazuh- Come sai che hai finito: modifichi formula-M80.pdf → alert Wazuh in < 60 sec
Verifica finale Sprint 1#
□ ansible-playbook: SSH password disabilitato su Ubuntu
□ Wazuh: vedo eventi da Ubuntu in real-time
□ FIM: modifica formula-M80.pdf → alert entro 60 sec
□ fail2ban: 5 tentativi SSH da Kali → IP bannato + alert Wazuh
□ GitHub: repo creato, ansible/ committatoSprint 2 — Cap 2: IAM + Active Directory#
Goal: AD DS operativo, utenti Mustache Corp su dominio, RBAC implementato.
Gibson: Cap 2 — AAA, RBAC, least privilege, account lockout, MFA, account lifecycle.
MITRE: T1078 (Valid Accounts), T1110 (Brute Force) — rilevabili con AD event logs su Wazuh.
DoD: login come honeyadmin genera alert critico; webadmin non può accedere a MySQL.
🔗 Lab già completati (da integrare nel contesto Mustache)#
Questi lab coprono le competenze del cap 2. Adattali al dominio
mustache.corp.
- [[[TODO] lab-active-directory-sso-kerberos|lab-active-directory-sso-kerberos]] → Samba AD DC, RBAC con gruppi, SSO + ticket Kerberos
- [[[TODO] lab-linux-acl-dac|lab-linux-acl-dac]] → setfacl/getfacl per proteggere
/data/confidential/
Active Directory Mustache Corp#
- Installare Samba 4 su Ubuntu come Domain Controller
- Creare dominio
mustache.corp - Creare OU
MustacheCorpcon utenti:webadmin,dbadmin,siem-operator,honeyadmin - Group Policy: account lockout dopo 5 tentativi, password complexity, audit logon events
- Come sai che hai finito:
net accounts /domainmostra le policy; log Samba visibile
- Come sai che hai finito:
RBAC Linux + ACL#
-
AllowUserssu Ubuntu per ruolo (webadminsolo su container nginx,dbadminsolo su MySQL) - setfacl su
/data/confidential/formula-M80.pdf→ solodbadminha lettura- Come sai che hai finito:
getfacl /data/confidential/formula-M80.pdfmostra ACE corrette
- Come sai che hai finito:
Wazuh — Samba Event Logs#
- Configurare Wazuh per ingestire log Samba (
/var/log/samba/log.samba) - Regola custom: alert CRITICO se
honeyadmineffettua login- Come sai che hai finito: login come
honeyadmin→ alert Wazuh in < 30 sec
- Come sai che hai finito: login come
PAM + Lockout#
- Configurare
faillocksu Ubuntu: 5 tentativi → lockout 15 min - Test da Kali: 5 SSH fail → account bloccato + alert Wazuh
- Come sai che hai finito:
faillock --user barnomostra i tentativi falliti
- Come sai che hai finito:
Verifica finale Sprint 2#
□ AD: utenti Mustache Corp esistono nel dominio mustache.corp
□ Group Policy: lockout dopo 5 tentativi (verificato da Kali)
□ honeyadmin login → alert CRITICO Wazuh in < 30 sec
□ webadmin accesso a MySQL → Permission denied
□ setfacl su formula-M80.pdf: solo dbadmin legge
□ Samba logs visibili in WazuhSprint 3 — Cap 3: Architecture + Network Segmentation#
Goal: Doppio firewall (iptables stateful), Docker networks come segmentazione, Suricata vede tutto, kill chain completa rilevabile. Gibson: Cap 3 — screened subnet, Zero Trust, firewall types, jump server, IDS/IPS, network appliances. MITRE: T1595 (Recon/PortScan), T1021 (Lateral Movement) — rilevati da Suricata. DoD: nmap da Kali → Suricata alert in < 10 sec; MySQL irraggiungibile da Kali direttamente.
🔗 Lab già completati (da integrare nel contesto Mustache)#
Questi lab coprono le competenze del cap 3. Verifica che le regole valgano per il setup Mustache.
- [[[TODO] lab-router-acl-iptables|lab-router-acl-iptables]] → ACL iptables/ufw per filtraggio per IP/porta/protocollo
- [[[TODO] lab-iptables-stateful|lab-iptables-stateful]] → conntrack stateful — ESTABLISHED,RELATED per return traffic
- [[[TODO] lab-jump-server-ssh|lab-jump-server-ssh]] → Mac→Ubuntu→container: bastion host pattern
- [[[TODO] lab-squid-proxy|lab-squid-proxy]] → Squid forward proxy con content filtering e logging
- [[[TODO] lab-snmp-v2-v3|lab-snmp-v2-v3]] → monitoraggio sicuro v3 (auth SHA + cifratura AES)
- [[[TODO] lab-cisco-cap03|lab-cisco-cap03]] → topologia DMZ/VLAN/ACL su Packet Tracer (conceptual reference)
Firewall iptables — Mustache Corp#
- iptables stateful su Ubuntu: permetti solo 80/443 TCP + 22 SSH da Mac in ingresso
- Implicit deny tutto il resto verso Ubuntu host
- Come sai che hai finito:
nmap -p 1-1000 192.168.64.3da Kali → solo 2-3 porte aperte
- Come sai che hai finito:
Docker Network Segmentation#
- Creare Docker network
mustache-dmzemustache-lan - nginx e DVWA su
mustache-dmz; MySQL e OpenCanary sumustache-lan - iptables: blocca traffico diretto Kali → mustache-lan (solo nginx può attraversare)
- Come sai che hai finito: da Kali
mysql -h 172.x.x.x→ timeout; via DVWA → funziona
- Come sai che hai finito: da Kali
nginx + ModSecurity WAF#
- Docker: nginx reverse proxy davanti a DVWA, ModSecurity con OWASP CRS
- GitHub Actions: push su
main→ SSH su Ubuntu →docker-compose pull && up -d- Come sai che hai finito: SQLi basilare su DVWA → WAF risponde 403; push GitHub → deploy automatico
Suricata — IDS passivo#
- Installare Suricata su Ubuntu in modalità
af-packetsull'interfaccia host-only - Abilitare ruleset ET Open, regola custom per SQLi nei payload HTTP
- Come sai che hai finito:
nmap -sS 192.168.64.3da Kali → alert Suricata in < 10 sec
- Come sai che hai finito:
Honeynet — OpenCanary#
- Docker: OpenCanary configurato come MySQL fake su porta 3306 in mustache-lan
- Wazuh: alert CRITICO se connessione a OpenCanary
- Come sai che hai finito: tentativo connessione al fake DB → alert CRITICO in < 30 sec
Verifica finale Sprint 3 — Kill Chain Completa#
Esegui questa sequenza da Kali, documenta ogni alert in Wazuh:
1. nmap -sS 192.168.64.3 → T1595 — Suricata alert port scan
2. SQLi su DVWA (low security) → T1190 — WAF log + Suricata HTTP alert
3. Web shell su nginx container → T1059 — Wazuh process alert
4. mysql -h IP_opencanary → T1021 — ALERT CRITICO honeynet
5. cat password-backup.txt → T1552 — ALERT honeyfile inotifywait
6. mysql -h 172.x.x.x (mustache-lan) → T1021 — timeout (iptables blocca)
7. Scarica formula-M80-DRAFT.pdf → T1048 — ALERT Canary Token via email
□ Tutti e 7 gli step hanno generato alert su Wazuh
□ Kill chain scritta in writeups/kill-chain-sprint-03.md con screenshot
□ Commit GitHub: "sprint-03: full kill chain documented"Sprint 4 — Cap 4: IDS/IPS avanzato + Suricata inline#
Goal: Suricata passa da IDS passivo a IPS inline; OpenCanary presidia 3 porte fake; SYN flood bloccato automaticamente. Gibson: Cap 4 — IDS/IPS, detection methods, honeypot/honeynet/honeyfile, honeytoken. MITRE: T1498 (DoS), T1046 (Network Scanning), T1021 (Lateral Movement → OpenCanary). DoD: SYN flood da Kali → Suricata blocca in < 5 sec; SSH su OpenCanary fake → alert CRITICO Wazuh in < 30 sec.
Suricata — da IDS a IPS (nfqueue)#
- Modificare config Suricata: modalità
nfq(inline) invece diaf-packet(passivo) - iptables: traffico in ingresso → NFQUEUE prima di essere accettato
- Test SYN flood:
hping3 -S --flood 192.168.64.3da Kali → traffico bloccato automaticamente- Come sai che hai finito: durante
hping3,curl http://192.168.64.3da Mac → timeout (bloccato da Suricata IPS)
- Come sai che hai finito: durante
Regole Custom Suricata#
- Regola port scan aggressivo (T1046): > 20 porte/sec →
drop+ alert - Regola SSH brute force (T1110): > 5 tentativi SSH in 60 sec →
drop - Regola SQLi HTTP (T1190): pattern
UNION SELECTo' OR '1'='1nei payload → alert- Come sai che hai finito:
nmap -sS --min-rate 1000 192.168.64.3→ Suricata log mostra[Drop]+ alert in Wazuh
- Come sai che hai finito:
OpenCanary — Deception Layer esteso#
- Avviare OpenCanary con porte fake: SSH (2222), HTTP (8080), FTP (2121)
- Wazuh: regola custom alert CRITICO per ogni connessione alle porte OpenCanary
- Test da Kali:
ssh -p 2222 192.168.64.3ecurl http://192.168.64.3:8080→ alert CRITICO entro 30 sec- Come sai che hai finito: Wazuh dashboard mostra alert con
rule.level >= 12per ogni tentativo
- Come sai che hai finito: Wazuh dashboard mostra alert con
Honeytoken — Canary Token su formula-M80#
- Generare Canary Token PDF su canarytokens.org
- Sostituire
formula-M80-DRAFT.pdfcon il Canary Token PDF - Test: aprire il PDF da Kali → email di alert arriva entro 60 sec
Verifica finale Sprint 4#
□ SYN flood da Kali → Suricata IPS blocca automaticamente (curl timeout durante flood)
□ nmap aggressivo → regola custom Suricata scatta, drop visibile nei log
□ ssh -p 2222 192.168.64.3 → alert CRITICO Wazuh in < 30 sec
□ curl http://192.168.64.3:8080 → alert CRITICO Wazuh in < 30 sec
□ Apri formula-M80-DRAFT.pdf → email Canary Token arriva entro 60 sec
□ writeups/kill-chain-sprint-04.md con screenshot aggiornatiSprint 5 — Cap 5: Securing Hosts + IaaS Responsibility + Encryption#
Goal: Applicare la shared responsibility model in pratica su una VPS IaaS reale (Hetzner), poi hardening host + PKI interna su Mustache Corp. Gibson: Cap 5 — virtualization, shared responsibility model (IaaS/PaaS/SaaS), hardening, disk encryption, PKI, TLS. Contesto: In IaaS il provider gestisce solo l'hardware. OS, firewall, patch, middleware = responsabilita' del cliente. La VPS Hetzner con Chatwoot/n8n e' il banco di prova reale.
IaaS Shared Responsibility — Hetzner VPS (lab su server reale)#
La VPS Hetzner con Chatwoot e n8n e' IaaS puro. Al momento non ha ufw. I database sono blindati dai container Docker (bind su 127.0.0.1), ma manca il layer di difesa in profondita'.
Audit porte aperte
ss -tlnp- Come sai che hai finito: hai la lista completa di cosa e' esposto su 0.0.0.0
Installare e configurare ufw
ufw default deny incoming ufw default allow outgoing ufw allow 80/tcp ufw allow 443/tcp ufw allow 22/tcp # o la porta SSH che usi ufw enable- Come sai che hai finito:
ufw status verbosemostra le regole;ss -tlnpda esterno mostra solo 80/443/SSH
- Come sai che hai finito:
Hetzner Cloud Firewall (difesa in profondita')
- Aggiungere le stesse regole sul firewall di rete nella console Hetzner
- Questo blocca il traffico prima che arrivi al server (layer separato da ufw)
- Come sai che hai finito: scan da esterno con
nmap -p 1-1000 <IP>mostra solo le porte autorizzate
Verifica che Docker non bypassa ufw
- Docker di default modifica iptables e puo' esporre porte bypassando ufw
- Controllare
/etc/docker/daemon.json→ aggiungere"iptables": falsese necessario o usareDOCKER-USERchain - Come sai che hai finito: porta interna Docker non raggiungibile dall'esterno anche dopo
docker-compose up
Encryption + PKI — Mustache Corp (UTM locale)#
- CA privata con
step-casu Ubuntu - Certificati TLS interni per nginx (non self-signed, emessi dalla CA)
-
formula-M80.pdfcifrato con GPG, chiave in password manager - TLS 1.3 only su nginx,
testssl.sh→ zero vuln - MITRE: T1557 (Adversary-in-the-Middle) — verificare che TLS lo prevenga
Sprint 6 — Cap 6: Threat Actors + Vulnerability Management#
Stub — da espandere quando si studia Cap 6
- OpenVAS/Greenbone scan contro DVWA — identificare CVE con CVSS scoring
- Remediation di 3 vulnerabilità trovate, nuovo scan → differenza documentata
- Simulare ransomware su Ubuntu: script cifra
/tmp/test/→ Wazuh FIM alert - MITRE: T1486 (Data Encrypted for Impact)
Sprint 7 — Cap 7: Application Security + Web Attacks + Kubernetes#
Stub — da espandere quando si studia Cap 7
- DVWA: SQLi, XSS, Command Injection (low → high, documentare la progressione)
- DNS filtering con Pi-hole (container)
- Email security: Postfix + OpenDKIM + SPF
- [[[TODO] lab-dll-injection-ld-preload|lab-dll-injection-ld-preload]] — DLL injection via LD_PRELOAD + Wazuh FIM
- Scrivere malware.so che intercetta puts()
- Iniettare via LD_PRELOAD su processo in esecuzione
- Sostituire .so su disco → Wazuh FIM rileva la modifica in < 60 sec
dpkg --verifyper confrontare hash contro database pacchetti
- GitHub Actions — CI/CD security ← comparso spesso nelle offerte di lavoro
- Pipeline deploy già presente in
.github/workflows/deploy.yml - Aggiungere step di sicurezza:
npm audit, SAST (Semgrep o CodeQL), secret scanning - Branch protection su
main: PR obbligatoria, status check CI verde prima del merge - Secrets management: credenziali Ubuntu mai in chiaro nel workflow, solo via GitHub Secrets
- Obiettivo: capire come si protegge una pipeline CI/CD, non solo come si usa
- Pipeline deploy già presente in
- Kubernetes (k3s): migrare mustache-app da Docker Compose a k3s
- Network Policy k3s = segmentazione mustache-dmz/lan ma per i pod
- RBAC k3s = IAM per workload
kubectl audit log→ Wazuh
- MITRE: T1190 (Web exploit), T1071 (C2 over HTTP/DNS)
Sprint 8 — Cap 8: Vulnerability Management + Cloud (Hetzner upgrade)#
Stub — da espandere dopo Security+. Qui si migra da UTM locale a Hetzner.
- Terraform: provisioning infra Hetzner (6 VPS + private networks)
- Ansible: applica tutti i ruoli dei sprint precedenti sulla nuova infra cloud
- Windows Server 2022: aggiungere VM Hetzner con AD DS reale
- NetFlow export → ntopng — baseline traffico normale vs attacco
- AWS o Azure: replicare il layer DMZ (VPC/VNET + Security Groups)
- WireGuard: accesso admin sicuro al lab cloud
- MITRE: mappare tutte le tecniche usate nei sprint precedenti su ATT&CK Navigator
Note Operative#
- Kali su UTM (192.168.64.200) — attacca Ubuntu (192.168.64.3)
- Ogni sprint: commit + writeup kill chain con screenshot alert su GitHub
docker-compose downquando non studi → risparmio risorse Mac- Screenshot obbligatori: Wazuh dashboard prima/dopo ogni attacco simulato
- Lab singoli cap-02/cap-03 già completati: richiamarli nel writeup con il link al file lab specifico



