Offenlegung der Container-Registry
A registry that allows anonymous pull leaks your source, and one that allows anonymous push lets an attacker replace the tag you deploy. Do both, then fix it with authentication, scoped push, and immutable tags.
Was ist Offenlegung der Container-Registry?
Eine Container-Registry enthält Ihren Quellcode, Ihre Konfiguration und das Artefakt, das Sie bereitstellen. Eine Registry, die anonymen Pull erlaubt, gibt all das an jeden weiter, der einen Repository-Namen errät, und eine, die anonymen Push erlaubt, lässt einen Angreifer einen Tag ersetzen, den Sie gerade ausliefern wollen. Diese Übung behandelt beide Hälften: Beobachten Sie, wie ein Angreifer ein privates Image liest und dann einen Tag vergiftet, und beheben Sie es anschließend mit Authentifizierung, eingeschränkten Push-Berechtigungen und unveränderlichen Tags.
Was Sie lernen in Offenlegung der Container-Registry
- Das Image enthält den Anwendungsquellcode, seine Konfiguration und seine Build-Layer, sodass ein Pull effektiv eine Kopie der Codebasis und ihrer Umgebung ist.
- Ein bestehender Tag wird auf andere Inhalte umgelenkt, sodass das getestete Artefakt auch das bereitgestellte Artefakt ist.
- Push nur auf die konkreten Repositories, die sie baut, und sonst nichts. Ein registry-weites Push-Credential verwandelt einen einzigen kompromittierten Runner in die Kontrolle über jedes Image.
- Vergleichen Sie den Digest des bereitgestellten Images mit dem von der Pipeline aufgezeichneten Digest, da sich der Tag verschieben lässt, der Digest jedoch nicht.
Offenlegung der Container-Registry — Trainingsschritte
-
Nach einem öffentlichen Repo suchen
Bob nimmt Quenmoor nicht gezielt ins Visier. Er scannt selbst gehostete Registries nach solchen, die ohne Login antworten, und listet dann deren Repositories auf, um eines zu finden, das lesbar geblieben ist. Quenmoors Registry antwortet, und ein Repository sticht heraus.
-
Ein privates Repo, offen gelassen
Bob scannt selbst gehostete Registries nach Repositories, die er eigentlich nicht erreichen dürfte. Quenmoors Registry antwortete ihm, ohne zu fragen, wer er ist, und ein Repository sticht heraus: ein interner Dispatch-Dienst.
-
Öffentlich, und beschreibbar
Das ist ein interner Dienst, aber seine Zugriffsrichtlinie steht weit offen. Bob liest die zwei Einstellungen, die für ihn zählen.
-
Anonym pullen
Keine Zugangsdaten, keine Mitgliedschaft, keine Zugriffsanfrage. Bob richtet Docker auf die Registry und zieht das Produktions-Image direkt herunter.
-
Ihre Produktionskonfiguration lesen
Das Image ist nicht nur Code. Es trägt die Konfiguration, mit der es läuft, fest eingebacken in eine Schicht. Bob startet daraus einen Container und liest diese Datei direkt aus.
-
Mit einer Backdoor neu bauen
Das Image zu lesen war Diebstahl; es zu überschreiben ist Kontrolle. Da er ihr echtes Produktions-Image gezogen hat, baut Bob direkt darauf neu auf und fügt eine einzige Schicht hinzu. Das ist das Dockerfile.
-
Die Schicht, die er hinzugefügt hat
Alles andere ist unverändert ihr Image. Ein einziges RUN macht daraus einen Brückenkopf, der mit jedem Deploy ausgeliefert wird.
-
Als deren Release taggen
Bob baut das vergiftete Image und taggt es mit genau dem Namen, von dem Quenmoor deployt, sodass die Registry es als das Produktions-Release behandelt.
-
Einen vergifteten Tag pushen
Das Image zu lesen ist Diebstahl. Es zu überschreiben ist Kontrolle. Bob baut das Image mit einer Backdoor in seinem Entrypoint neu und pusht es zurück auf genau den Tag, von dem Quenmoor deployt. Die Registry nimmt es an, ohne zu fragen, wer er ist.
-
Was der Push ihm eingebracht hat
Das nächste Deploy rollte Bobs Tag in die Produktion aus, und die Schicht, die er hinzugefügt hatte, meldete sich aus dem laufenden Dienst heraus nach Hause. Er muss Quenmoor nicht mehr von außen erreichen: Sein Code ist der Dienst.