Geheimnisse in Image-Layern

Geheimnisse in Image-Layern

A private package-index token is baked into a public container image and survives the RUN that deletes it. Read it out of the layer history like an attacker would, then rotate the credential and rebuild so the secret never enters a layer.

Was ist Geheimnisse in Image-Layern?

Ein Credential verschwindet nicht aus einem Image, nur weil das Dockerfile es löscht. Image-Layer sind nur anfügend (append-only), daher wird ein Credential, das in einem RUN übergeben wird, für immer in diesem Layer aufgezeichnet – ein späteres RUN, das die Datei entfernt, fügt lediglich einen neuen Layer obendrauf hinzu. Diese Übung behandelt ein privates Package-Index-Token, das in ein öffentliches Image eingebacken wurde: Sieh zu, wie ein Angreifer es direkt aus der Layer-Historie ausliest und verwendet, und arbeite dann die eigentliche Lösung durch. Rotiere zuerst das Credential, damit der geleakte Wert nutzlos wird, und baue das Image dann so neu, dass das Geheimnis überhaupt nie in einen Layer gelangt.

Was Sie lernen in Geheimnisse in Image-Layern

Geheimnisse in Image-Layern — Trainingsschritte

  1. Das Ziel einschätzen

    Heute nimmt Bob Cindralt ins Visier, einen Zahlungsdienstleister, dessen Abrechnungsdienst (Settlement Service) als Container-Image ausgeliefert wird. Er beginnt dort, wo jeder beginnen kann: bei der eigenen Container-Registry des Unternehmens. Ein veröffentlichtes Image ist ein bequemes Angriffsziel. Es ist genau das Artefakt, das in Produktion läuft, und es zu pullen kostet nichts.

  2. Jeder kann es pullen

    Das Repository ist für anonymes Pullen freigegeben. Das ist für viele Unternehmen eine bewusste Entscheidung und für sich genommen keine Schwachstelle, bedeutet aber, dass das Artefakt Bob zu denselben Bedingungen zur Verfügung steht wie Cindralts eigenen Build-Servern.

  3. Das Image pullen

    Bob pullt den Tag, den die Registry als latest führt. Was auf seinem Rechner landet, ist byteidentisch mit dem, was Cindralt in Produktion betreibt, einschließlich jedes Layers, den der Build dabei erzeugt hat.

  4. Die Build-Historie lesen

    Jedes Image trägt die Befehle mit sich, mit denen es gebaut wurde. Bob muss den Container nicht starten oder irgendetwas entpacken: Die Layer-Historie ist Metadaten und kommt automatisch mit dem Pull mit. Auf den ersten Blick wirkt dieser Build sorgfältig. Jemand hat sogar nach der Installation der Abhängigkeiten aufgeräumt.

  5. Nach dem vollständigen Befehl fragen

    Die Standardtabelle ist darauf ausgelegt, ins Terminal zu passen, nicht darauf, die volle Wahrheit zu zeigen. Bob lässt sich die Build-Befehle einzeln anzeigen, ohne dass irgendetwas gekürzt wird. Der Installationsbefehl hat ein Credential in eine Konfigurationsdatei geschrieben, und es befindet sich immer noch in dem Layer, den dieser Befehl erzeugt hat.

  6. Warum das Löschen nichts gebracht hat

    Ein kurzer Moment zum Mechanismus, bevor Bob nutzt, was er gefunden hat.

  7. Prüfen, was das Token öffnet

    Ein Credential ist nur so viel wert wie das, was es erreichen kann. Bob fragt Cindralts Package-Index, wem dieses Token gehört und was es tun darf. Die Antwort ist schlimmer als ein einzelner Dienst. Das Token kann für jedes Package veröffentlichen, gegen das Cindralt baut, und es läuft nie ab.

  8. Was dieses Token wert ist

    Bob muss Cindralts Server kein zweites Mal anfassen. Mit Publish-Rechten auf jedes Package, gegen das das Unternehmen baut, kann die nächste Version jeder internen Bibliothek von ihm stammen, und sie wird von jedem Build gepullt, der danach läuft.

  9. Der Index meldet eine Veröffentlichung

    Cindralts Package-Index protokolliert jeden authentifizierten Aufruf. Über Nacht wurde erfasst, dass das Token ci-publisher von einer Adresse aus verwendet wurde, die niemandem im Unternehmen gehört.

  10. Am Image bestätigen

    Alice überprüft die Behauptung selbst anhand des veröffentlichten Artefakts, mit genau dem, was auch ein Außenstehender hätte: dem öffentlichen Tag und einem gewöhnlichen Docker-Client.