Quandu ùn si tratta micca solu di vulnerabili di Kubernetes ...
Nota. transl.: l'autori di stu articulu parlanu in dettagliu cumu si sò riesciutu à scopre a vulnerabilità CVE-2020-8555 in Kubernetes. Ancu s'ellu inizialmente ùn pareva micca assai periculosu, in cumminazione cù altri fattori, a so criticità hè stata massima per certi fornituri di nuvola. Diversi urganisazioni anu premiatu generosamente i specialisti per u so travagliu.
Quale simu
Semu dui circadori francesi di sicurezza chì anu scupertu inseme una vulnerabilità in Kubernetes. I nostri nomi sò Brice Augras è Christophe Hauquiert, ma in parechje piattaforme Bug Bounty simu cunnisciuti rispettivamente cum'è Reeverzax è Hach:
Questu articulu hè u nostru modu di sparte cumu un prughjettu di ricerca ordinariu hà diventatu inesperu in l'avventura più eccitante in a vita di i cacciatori di bug (almenu per avà).
Cume probabilmente sapete, i cacciatori di bug anu un paru di caratteristiche notevuli:
campanu di pizza è biera;
travaglianu quandu tutti l'altri dormenu.
Ùn simu micca eccezzioni à queste regule: avemu di solitu scontru u weekend è passanu notti senza dorme pirate. Ma una di queste notti finita in una manera assai inusual.
À u principiu, avemu da riunite per discutiri a participazione CTF u ghjornu dopu. Durante una conversazione nantu à a sicurità di Kubernetes in un ambiente di serviziu amministratu, avemu ricurdatu di a vechja idea di SSRF (Falsificazione di dumanda à u latu di u servitore) è hà decisu di pruvà à aduprà cum'è un script d'attaccu.
À 11 ore di sera, ci pusemu à fà a nostra ricerca è andemu in lettu à a matina, assai cuntenta di i risultati. Hè per via di sta ricerca chì avemu ghjuntu à traversu u prugramma MSRC Bug Bounty è hè ghjuntu cù un sfruttamentu di l'escalation di privilegiu.
Passavanu parechje settimane / mesi, è u nostru risultatu inespettatu hà risultatu unu di i più alti premii in a storia di Azure Cloud Bug Bounty - in più di quellu chì avemu ricevutu da Kubernetes!
Basatu nantu à u nostru prughjettu di ricerca, u Cumitatu di Sicurezza di u Produttu Kubernetes hà publicatu CVE-2020-8555.
Avà mi piacerebbe sparghje infurmazione nantu à a vulnerabilità truvata quant'è pussibule. Speremu chì apprezzà a ricerca è sparte i dettagli tecnichi cù l'altri membri di a cumunità infosec!
Allora eccu a nostra storia...
U cuntestu
Per fà u più sensu di ciò chì hè accadutu, fighjemu prima cumu funziona Kubernetes in un ambiente amministratu in nuvola.
Quandu istanziate un cluster Kubernetes in un tali ambiente, a strata di gestione hè tipicamente a responsabilità di u fornitore di nuvola:
A capa di cuntrollu hè situata à u perimetru di u fornitore di nuvola, mentre chì i nodi Kubernetes sò situati à u perimetru di u cliente.
Per assignà dinamicamente volumi, un mecanismu hè utilizatu per furnisce dinamicamente da un backend di almacenamentu esternu è paragunà cù PVC (pretendenza di volume persistente, vale à dì una dumanda per un voluminu).
Cusì, dopu chì u PVC hè creatu è ligatu à u StorageClass in u cluster K8s, più azzioni per furnisce u voluminu sò ripresi da u gestore di u controller kube / cloud (u so nome esatta dipende da a liberazione). (Nota. transl.: Avemu digià scrittu più nantu à CCM cù l'esempiu di a so implementazione per unu di i fornituri di nuvola ccà.)
Ci sò parechji tippi di furnituri supportati da Kubernetes: a maiò parte di elli sò inclusi in core di l'orchestratore, mentri àutri sò amministrati da furnituri supplementari chì sò posti in pods in u cluster.
In a nostra ricerca, avemu focu annantu à u mecanismu di furnimentu di volumi internu, chì hè illustratu quì sottu:
Fornitura dinamica di volumi aduprendu u provisioner Kubernetes integratu
In breve, quandu Kubernetes hè implementatu in un ambiente amministratu, u gestore di u controller hè a rispunsabilità di u fornitore di nuvola, ma a dumanda di creazione di volumi (numeru 3 in u diagramma sopra) abbanduneghja a reta interna di u fornitore di nuvola. È questu hè induve e cose diventanu veramente interessanti!
Scenariu di pirate
In questa sezione, spiegheremu cumu avemu apprufittatu di u flussu di travagliu citatu sopra è accede à e risorse internu di u fornitore di serviziu di nuvola. Vi mostrarà ancu cumu pudete fà certe azzioni, cum'è ottene credenziali internu o privilegii di scala.
Una manipulazione simplice (in questu casu, Service Side Request Forgery) hà aiutatu à andà oltre l'ambiente di u cliente in clusters di diversi fornitori di servizii sottu K8s gestiti.
In a nostra ricerca avemu focu annantu à u GlusterFS provisioner. Malgradu u fattu chì l'ulteriore sequenza d'azzioni hè descritta in questu cuntestu, Quobyte, StorageOS è ScaleIO sò suscettibili à a stessa vulnerabilità.
Abusu di u mecanismu di furnimentu di volumi dinamichi
Durante l'analisi di classi di almacenamento GlusterFS in u codice fonte di u cliente Golang noi rimarcatuchì nantu à a prima dumanda HTTP (3) mandata durante a creazione di volumi, à a fine di l'URL persunalizata in u paràmetru resturl aghjuntu /volumes.
Avemu decisu di sbarazzà di sta strada addiziale aghjunghjendu # in paràmetru resturl. Eccu a prima cunfigurazione YAML chì avemu usatu per pruvà una vulnerabilità SSRF semi-cecu (pudete leghje più nantu à SSRF semi-blind o half-blind, per esempiu, ccà - ca. trad.):
Allora avemu usatu u binariu per gestisce remotamente u cluster Kubernetes kubectl. Di genere, i fornituri di nuvola (Azure, Google, AWS, etc.) permettenu di ottene credenziali per l'usu in questa utilità.
Grazie à questu, aghju pussutu utilizà u mo schedariu "speciale". Kube-controller-manager hà eseguitu a dumanda HTTP risultante:
kubectl create -f sc-poc.yaml
A risposta da u puntu di vista di l'attaccante
Pocu dopu, avemu ancu pussutu riceve una risposta HTTP da u servitore di destinazione - via i cumandamenti describe pvc o get events in kubectl. È veramente: stu driver Kubernetes predeterminatu hè troppu verbose in i so avvisi / messagi d'errore ...
Eccu un esempiu cù un ligame per https://www.google.frstabilitu cum'è paràmetru resturl:
kubectl describe pvc poc-ssrf
# или же можете воспользоваться kubectl get events
In questu approcciu, eramu limitati à dumande cum'è HTTP POST è ùn pudia micca ottene u cuntenutu di u corpu di risposta se u codice di ritornu era 201. Dunque, avemu decisu di fà ricerche supplementari è espansione stu scenariu di pirate cù novi approcci.
L'evoluzione di a nostra ricerca
Scenariu Avanzatu # 1: Utilizendu una redirezzione 302 da un servitore esternu per cambià u metudu HTTP per furnisce un modu più flexible per cullà dati interni.
Scenariu Avanzatu #2: Automatizà a scansione LAN è a scuperta di risorse internu.
Scenariu avanzatu # 3: utilizendu HTTP CRLF + contrabbanda ("richiesta di contrabbanda") per creà richieste HTTP adattate è ricuperà e dati estratti da i logs di kube-controller.
Specificazioni tecniche
A ricerca hà utilizatu Azure Kubernetes Service (AKS) cù Kubernetes versione 1.12 in a regione di l'Europa di u Nordu.
I scenarii descritti sopra sò stati eseguiti nantu à l'ultime versioni di Kubernetes, cù l'eccezzioni di u terzu scenariu, perchè avia bisognu di Kubernetes custruitu cù a versione Golang ≤ 1.12.
Servitore esternu di l'attaccante - https://attacker.com.
Scenariu Avanzatu #1: Redirezzione di una dumanda HTTP POST à GET è riceve dati sensibili
U metudu uriginale hè statu migliuratu da a cunfigurazione di u servitore di l'attaccu per vultà 302 HTTP Retcodeper cunvertisce una dumanda POST in una dumanda GET (passu 4 in u diagramma):
Prima dumanda (3) da u cliente GlusterFS (Controller Manager), hà un tipu POST. Facendu questi passi, pudemu turnà in un GET:
Cum'è un paràmetru resturl in StorageClass hè indicatu http://attacker.com/redirect.php.
Endpoint https://attacker.com/redirect.php risponde cù un codice di statutu HTTP 302 cù l'intestazione di u locu seguente: http://169.254.169.254. Questu pò esse qualsiasi altra risorsa interna - in questu casu, u ligame di redirezzione hè utilizatu solu com'è esempiu.
automaticamente biblioteca net/http Golang redirige a dumanda è cunvertisce u POST in un GET cù un codice di statutu 302, chì risulta in una dumanda HTTP GET à a risorsa di destinazione.
Per leghje u corpu di risposta HTTP avete bisognu di fà describe Oggettu in PVC:
kubectl describe pvc xxx
Eccu un esempiu di una risposta HTTP in formatu JSON chì avemu pussutu riceve:
A capacità di a vulnerabilità truvata in quellu tempu era limitata per i seguenti punti:
Incapacità di inserisce intestazioni HTTP in a dumanda in uscita.
Incapacità di fà una dumanda POST cù paràmetri in u corpu (questu hè convenientu per dumandà u valore chjave da una istanza etcd in esecuzione 2379 portu se hè utilizatu HTTP senza criptu).
Incapacità di ricuperà u cuntenutu di u corpu di risposta quandu u codice di statutu era 200 è a risposta ùn hà micca un JSON Content-Type.
Scenariu avanzatu #2: Scanning a reta lucale
Stu metudu SSRF mezzu cecu hè stata allora utilizata per scansà a reta interna di u fornitore di nuvola è polling diversi servizii d'ascolta (Istanza di Metadata, Kubelet, etcd, etc.) basatu nantu à e risposte. controller kube.
Prima, i porti di ascolta standard di i cumpunenti di Kubernetes sò stati determinati (8443, 10250, 10251, etc.), è dopu avemu avutu à automatizà u prucessu di scanning.
Videndu chì stu metudu di risorsi di scanning hè assai specificu è ùn hè micca cumpatibile cù scanners classici è strumenti SSRF, avemu decisu di creà i nostri propri travagliadori in un script bash chì automatizà tuttu u prucessu.
Per esempiu, per scansà rapidamente a gamma 172.16.0.0/12 di a reta interna, 15 travagliadori sò stati lanciati in parallelu. U intervallu IP sopra hè statu sceltu cum'è un esempiu solu è pò esse sottumessu à cambià à a gamma IP di u vostru fornitore di serviziu specificu.
Per scansà un indirizzu IP è un portu, avete bisognu di fà e seguenti:
sguassate l'ultimu StorageClass verificatu;
sguassate l'annunziu di volume persistente verificatu precedente;
cambià i valori IP è Port in sc.yaml;
creà una StorageClass cù un novu IP è portu;
creà un novu PVC;
estratti i risultati di scansione cù descrizzione per PVC.
Scenariu avanzatu # 3: iniezione CRLF + contrabanda HTTP in versioni "vechji" di u cluster Kubernetes
Se in più di questu, u fornitore offre à i clienti versioni antichi di u cluster K8s и li hà datu accessu à i logs di kube-controller-manager, l'effettu hè diventatu ancu più significativu.
Hè veramente assai più convenientu per un attaccu di cambià e richieste HTTP pensate per ottene una risposta HTTP completa à a so discrezione.
Per implementà l'ultimu scenariu, i seguenti cundizioni anu da esse cumpletu:
L'utilizatore deve avè accessu à i logs kube-controller-manager (cum'è, per esempiu, in Azure LogInsights).
U cluster Kubernetes deve aduprà una versione di Golang più bassa di 1.12.
Avemu implementatu un ambiente lucale chì simulava a cumunicazione trà u cliente di GlusterFS Go è un servitore di destinazione falsu (asteneremu di pubblicà u PoC per avà).
Hè statu trovu vulnerabilità, chì hà affettatu e versioni Golang più bassu di 1.12 è hà permessu à i pirate di realizà attacchi HTTP smuggling / CRLF.
Cumminendu u SSRF semi-cecu descrittu sopra вместе cun questu, pudemu mandà dumande à u nostru piace, cumpresu rimpiazzà intestazioni, mètudu HTTP, paràmetri è dati, chì kube-controller-manager poi processatu.
Eccu un esempiu di un "esca" di travagliu in un paràmetru resturl StorageClass, chì implementa un scenariu di attaccu simili:
U risultatu hè un errore risposta micca dumandata, un missaghju nantu à quale hè arregistratu in i logs di u controller. Grazie à a verbosità attivata per automaticamente, u cuntenutu di u missaghju di risposta HTTP hè ancu salvatu quì.
Questa era a nostra "esca" più efficace in u quadru di prova di cuncettu.
Utilizendu stu approcciu, pudemu fà alcuni di i seguenti attacchi à clusters di diversi fornitori di k8s gestiti: escalazione di privilegi cù credenziali nantu à istanze di metadati, Master DoS via richieste HTTP (non criptate) in istanze master etcd, etc.
Cunsiquenzi
In a dichjarazione ufficiale di Kubernetes in quantu à a vulnerabilità SSRF chì avemu scupertu, hè stata valutata CVSS 6.3/10: CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N. Se avemu cunsideratu solu a vulnerabilità assuciata cù u perimetru Kubernetes, u vettore di integrità (vettore di integrità) hè qualificatu cum'è None.
Tuttavia, a valutazione di e pussibuli cunsequenze in u cuntestu di un ambiente di serviziu amministratu (è questu era a parte più interessante di a nostra ricerca!) Ci hà incitatu à riclassificà a vulnerabilità in una valutazione. CVSS criticu 10/10 per parechji distributori.
Quì sottu hè infurmazione supplementaria per aiutà à capisce e nostre cunsiderazioni quandu valute l'impatti potenziali in ambienti nuvola:
Riproducendu u scenariu di sopra cù u metudu IDOR (Insecure Direct Object Reference) cù altre risorse truvate in a reta lucale.
Cunfidenzialità
Tipu d'attaccu Muvimentu Laterale grazia à u furtu di credenziali di nuvola (per esempiu, metadata API).
Raccolta di l'infurmazioni scannendu a reta lucale (determinazione di a versione SSH, a versione di u servitore HTTP, ...).
Raccoglie l'infurmazioni di l'istanza è l'infrastruttura per sondaghju l'API interni cum'è l'API di metadata (http://169.254.169.254, ...).
Arrubà i dati di i clienti utilizendu credenziali in nuvola.
Disponibilidad
Tutti i scenarii di sfruttamentu ligati à i vettori di attaccu integrità, pò esse usatu per l'azzioni distruttive è portanu à l'istanze maestru da u perimetru di u cliente (o qualsiasi altru) ùn sò micca dispunibili.
Siccomu eramu in un ambiente K8s gestitu è evaluendu l'impattu nantu à l'integrità, pudemu imaginà parechji scenarii chì puderanu impactà a dispunibilità. Esempi supplementari includenu corruzzione di a basa di dati etcd o fà una chjama critica à l'API Kubernetes.
Timeline
6 dicembre 2019: Vulnerabilità signalata à MSRC Bug Bounty.
3 di ghjennaghju di u 2020: Un terzu hà infurmatu à i sviluppatori Kubernetes chì stavamu travagliendu annantu à un prublema di sicurezza. È li dumandò di cunsiderà SSRF cum'è una vulnerabilità interna (in core). Dopu avemu furnitu un rapportu generale cù dettagli tecnichi nantu à a fonte di u prublema.
15 di ghjennaghju di u 2020: Avemu furnitu rapporti tecnichi è generali à i sviluppatori Kubernetes nantu à a so dumanda (via a piattaforma HackerOne).
15 di ghjennaghju di u 2020: I sviluppatori di Kubernetes ci anu infurmatu chì l'iniezione di SSRF + CRLF mezza cieca per versioni passate hè cunsiderata una vulnerabilità in core. Avemu immediatamente cessatu di analizà i perimetri di l'altri fornituri di serviziu: a squadra di K8s era avà trattatu cù a causa radicali.
15 di ghjennaghju di u 2020: a ricumpensa MSRC ricevutu attraversu HackerOne.
16 di ghjennaghju di u 2020: Kubernetes PSC (Comitatu di Sicurezza di u Produttu) hà ricunnisciutu a vulnerabilità è hà dumandatu à mantene a sicreta finu à a mità di marzu per via di u gran numaru di vittimi potenziali.
11 di ferraghju di u 2020: a ricumpensa Google VRP hà ricevutu.
4 di marzu di u 2020: a ricumpensa Kubernetes ricevutu attraversu HackerOne.
15 di marzu di u 2020: A divulgazione publica inizialmente prevista hè posposta per via di a situazione COVID-19.
1 di ghjugnu 2020: Dichjarazione cumuna di Kubernetes + Microsoft nantu à a vulnerabilità.
TL; DR
Bevemu a birra è manghjemu pizza :)
Avemu scupertu una vulnerabilità in-core in Kubernetes, anche se ùn aviamu micca intenzione di fà.
Avemu realizatu analisi supplementari nantu à clusters di diversi fornitori di nuvola è pudemu aumentà i danni causati da a vulnerabilità per riceve bonus fantastichi supplementari.
Truverete assai ditaglii tecnichi in questu articulu. Saremu felici di discutiri cun voi (Twitter: @ReeverZax & @__hach_).
Risultava chì ogni tipu di formalità è di rapportu pigliò assai più di l'aspittatu.